Separate controllers for child entities - oop

This is probably very basic question but I can't find straight answer to it,
I was thinking about it for a while and still didn't figure out what is best practice?
In parent - child relationship, e.g. Department / Employee should I have actions like:
DepartmentController -> addEmpoyee(deptId)
DepartmentController -> editEmpoyee(empId)
DepartmentController -> employees(deptId)
Or rather create separate controller for Employee operations?
EmployeeController -> add(deptId)
EmployeeController -> edit(empId)
EmployeeController -> list(deptId)
Second approach makes sense to me but the first seems to be logical as well as employees are child entities of dept...

I would make a DepartmentCrudController gathering those methods (index, show, create, delete, new, edit).
Indeed, CRUD is ONE responsibility in itself, so does not break Single Responsibility Principle.
However, associated commands called by controller (take a look at CQRS for instance), if contain some business logic (task-driven UI), should themselves be separated in order to be less sensitive to change, increasing the flexibility of your application.
But for a simple CRUD, one service layer class is enough.
Your controller should be a simple humble object delegating to your use cases (services layer), meaning without ANY business logic at all.

Related

Repository Pattern - Structuring repositories

I am trying to use repositories in my MVC program designs and I have run up against a problem on how to best structure them.
as an example, say I have an object USers and I have a UserRepository which has functions like getUser(int id), saveUser(Dal.User model) etc...
So If in my controller I have EditUser and I want to display a view that will have a user details input form. so I can do something like this:
User user = _userRepository.getUserDetails(userId);
The benefit being that my controller just deals with processing HTTP requests, and business logic is moved to repositories, making testing etc easier
So, say I want to display a drop down list of possible roles this user could have in my system, ie client, admin, staff etc
is it ok to have a function in the _userRepository called getPossibleUserRoles() or should I have a seperate _roleRepository with a function getRoles() ?
IS it a bad idea to inject a repository for every entity you encounter into your controller? or is it a bad idea to mix entities inside your repositories, making them cluttered.
I realise I have presented a very simplistic scenario, but obviously as systems grow in complexity you are potentially talking of 10s of repositories needing to be instantiated in a controller for every page call. and also possibly instantiating repositories that are not being used in current controller methods simply to have them available to other controller methods.
Any advice on how best to structure a project using repositories appreciated
is it ok to have a function in the _userRepository called
getPossibleUserRoles() or should I have a seperate _roleRepository
with a function getRoles() ?
Let's say you have some controllers call:
_userRepository.getUserDetails(userId);
but they never call:
_userRepository.getPossibleUserRoles(userId);
Then you are forcing your controllers to depend on methods they do not use.
Sot it's not just ok, you should split this.
But if getUserDetails and getPossibleUserRoles are chosive (sharing same entity, sharing same business logic etc..).
You can split this without changing implemantation of userrepository beside of creating new class for Roles.
public class UserRepsitory : IUserRoles, IUserRepository
{
}
I realise I have presented a very simplistic scenario, but obviously
as systems grow in complexity you are potentially talking of 10s of
repositories needing to be instantiated in a controller
If a constructor gets too many parameters, there is high posibility SRP violation. Mark Seemann shows how to solve this problem in here.
In a short way: While you are creating a behaviour, if you use always 2 or more than repositories together. Then, these repositories are very close. So you can create a service and orchestrate them in this service. After that, you can use this service as a paremeter beside of using 2 or more repositories in your controller constructor.
is it ok to have a function in the _userRepository called getPossibleUserRoles() or should I have a seperate _roleRepository with a function getRoles() ?
Both solutions are acceptable but consider how you're going to control the proliferation of repositories and methods on those repositories. IMHO, the typical repository usage scenario tends to end-up with too many repositories with too many methods on each. DDD advocates a repository per aggregate root. This is a good rule of thumb... if you're following DDD principles.
IS it a bad idea to inject a repository for every entity you encounter into your controller? or is it a bad idea to mix entities inside your repositories, making them cluttered.
Inject volatile dependencies, so yes, inject a repository for every entity your controller needs. However, once you start injecting more than four dependencies, chances are you've missed an abstraction somewhere in your design. Some solve this problem with RepositoryFactory but this, arguably, introduces the problem of opaque dependencies and, IMHO, fails to convey the class's real dependencies, reducing its usability and self-document-ability.
Take a look at using query objects rather than repositories (https://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/, etc.) and take a look at using orchestration/mediation (http://codeopinion.com/thin-controllers-cqrs-mediatr/) in your controllers. I think you'll find a better design emerges that will help you with your design issues.

When subclassing an object, what is the appropriate method to handle functions that don't make sense on the child?

Before I jump into the meat of the question, let me note that this is a purely theoretical query. I'm not interested in this for practical reasons, I'm interested in the underlying OOP theory on how to handle this type of situation.
In a project I'm working on, I have two closely related classes. One is the generic 'user' class. The other is subclassed, and adds additional features used by certain users -- for a generic example, think a 'moderator' class.
How do I handle public methods that are available on the user class that don't make sense for the child to have called?
For example, it makes perfect sense to call User::getUserWithId(id) (this method retrieves data from the DB and initializes and returns the user class with that data); it doesn't make as much sense (if any) to use that method with the moderator class.
Should I just ignore it -- if a user calls moderator::getUserWithId(id), they're still getting a user, exactly what they asked for. Should I override it to return a moderator, despite the method name? Or is there something in OOP land I'm not familiar with that lets me 'block' the call?
If you have methods in your base class that don't make sense in your subclass, then I think you need to re-evaluate if you should model these classes via an inheritance relationship. Needing to hide members of a base class in a subclass is a red flag that indicates modeling this via an inheritance relationship is problematic.
An inheritance relationship should indicate an "is a" relationship. For your example, a moderator object "is a" user object and thus should have the same methods and properties as the user object. If it does not, then it would appear that it does not have a true inheritance relationship with its base user class.
In this case, you might want to consider using interfaces instead of inheritance. You can factor the common functionality between the User and Moderator classes into an interface. If there is common code that they can share, then you can use composition to achieve this, by creating a common implementation of the interface and then passing it to the classes that need to reuse this code. For further information, see here and here.
As the author in the second link above puts it:
Does TypeB want to expose the complete interface (all public methods no less) of TypeA such that TypeB can be used where TypeA is expected? Indicates Inheritance.
Does TypeB only want only some/part of the behavior exposed by TypeA? Indicates need for Composition.
From your need to hide a member of the base class, it seems that you are in the second category, and might want to explore using composition and an interface.
Yesterday I left a response, that somehow got lost. I think, #Joe Alfano has a very good explanation that addresses your "theoretical" and also particular questions.
Beside that, In my opinion, one source of your problem might be that you are doing database access in your Domain Object. In general, unless there is a compelling reason, this is not a good practice. If you remove that database access into a separate layer like Data Access Layer (DAL) this problem goes away. You won't have User::getUserWithId(id) things in your classes, they will be handled in DAL. Like
class UserDao {
User getById(id)
}
Class ModeratorDao {
Moderator getById(id)
}
If you go with DAL-like approach, then you will also find ways to re-factoring code, which is a separate thing.

Notifying observers from nested structures

Currently, I am trying to dissect some tight coupling between the data model and the UI in an application by introducing the MVC pattern. Basically, this means making the model aware of the associated views in order to have them informed whenever properties inside the model change.
The data model is represented by a nested structure:
Model
- Node
- Leaf
- Leaf
- Node
- Leaf
Each element inherits from a common abstract base class (StructuredNode).
The problem I've been thinking about is: observers should be able to subscribe to the Model (and only the Model), but each element should be able to emit change notifications. This could be achieved in two ways - either notifications are routed up the hierarchy until they reach the Model, where they get pushed to the observers, or by implementing notifications in the base class, with a static observers list, as in this example:
public abstract class Base {
private static Map<IObserver> observers;
protected synchronized void internalSubscribe(final IObserver observer) {
observers.add(observer);
}
protected synchronized void notifyObservers(final Base obj) {
for (IObserver observer : observers)
observer.changed(obj);
}
// .. other base class operations
}
In this implementation, only Model would offer a public subscribe method, which internally would delegate to the protected internalSubscribe method of the base class. At the same time, each derivative of the base class could send a change notification, like this:
// Perform some operations that change the object's internal state
// ...
// Then notify all observers
notifyObservers(this);
Is this rather good or rather bad practice (using a static observers list)? Any opinions on this? Are there alternative solutions?
A static observer list is not a common solution, and I would not consider it a good practice for a generic use model.
Observers would be notified of changes to models they are not interested in. This means that all the burden of identifying the model firing the notification falls on the observers, which probably have no good and efficient way of doing it other than going up the hierarchy and finding the root node... a lot of code, that must potentially be implemented several times in several observers. In the end it would be simpler for the observer to ignore considerations and just update or recalc, even when the updated model is not the one it's interested in.
Of course all this may not apply in your case. If you know you will not have more than one model of this class in your application, then you can very well go with this solution.
Anyway, the requirement of having only the Model with a public subscribe method should not constrain you to using a static observer container to share among all Model instances. As you said, there is another way. Routing the notifications up the hierarchy is IMHO the correct way to go.
If you want to avoid routing, then you could choose to have the nodes keep a reference to their model. This may be more efficient if you know the tree structure will be deep an not very dynamic. If nodes can be moved from one Model to another, than this is a bit risky and requires some further code to keep the reference updated.

How to apply Single Responsibility Principle to a service class

Suppose we are designing a UserServiceImpl class which does CRUD (Create, Read, Update, and Delete) operations. In my view Create, Read, Update, and Delete are four reasons for a class to change. Does this class violates Single Responsibility Principle? If it violates,
then should we have four classes like CreateUserServiceImpl, ReadUserServiceImpl,
UpdateUserServiceImpl, and DeleteUserServiceImpl. Isn't it an overkill to have lots of
classes?
Suppose I define 4 interfaces each for create, read, update, and delete operations and my
service class implements all the four interfaces. Now I can only have a single
implementation class but by separating their interfaces I have decoupled the concepts as
far as rest of the application is concerned. Is this the right way or you see some problems
in it?
That's what I love about patterns and principles - they are a consist way for everyone to disagree on software design as much as agree :-)
My view would be to build the class in whatever way makes it a usable and easy to understand class - depending on the complexity and context within which the class lives. With a simple implementation and context, a single class will do. You could say it does adhere to the SRP because it's responsibility is to manage the CRUD operations. But if the implementation is complex, or there's a lot of shared code that would be suitable for placing in an abstract parent class, then perhaps 4 separate classes, one for each CRUD operation make more sense. it's all about how you look at it.
Patterns and principles are great things, but used incorrectly they can make a simple problem just as complex as not having them.
In my view Create, Read, Update, and Delete are four reasons for a
class to change.
Why?
If I have a Stack class, are Push and Pop reasons for the class to change?
I don't think so. These are two standard operations people do with a stack. The same with CRUD, it is a simple, established, well-known set of operations over a data storage.
Now your underlying storage technology itself IS a reason for your class to change. That is if your CRUD implementation is hard-coded to only work with a specific instance of an MS SQL 6.0 database, then you violate SRP and the class will not be easily reusable or extandable.
With regards to 4 interfaces, that is closer to another SOLID principle, the ISP, and the need here is determined by the patterns of usage of your data storage. For example, if some classes will only need to Read from the data storage it makes total sense to extract an interface with just the Read method and request that interface as an argument to such methods. By separating this interface you can later on make a separate implementation of it. Who knows, maybe for read-only clients you can issue a better optimized query or use a memory cache, but if not -- you can just pass them the instance of your default data storage implementing this interface.
It does not violate the single responsibility principle till the service is responsible for the data services of a single type or business info.

In which class would you put these methods?

If I have a User class, and his account can be suspended by adding an entry to the suspensions table, which of these class/method signatures do you think is more appropriate?
User::suspend($reason, $expiryDate);
Suspension::add($userid, $reason, $expiryDate);
This is a simple example, but I have this kind of situation everywhere throughout my application. On one hand, I'd want to make it a method of the User object, since the action performed is directly related to that user object itself, but on the other hand making it a method on the suspension object seems a bit cleaner.
What do you think?
you suspend a user.
User.Suspend()
In your User.Suspend method, you can actually add them to your "suspension" table, or call your suspension object. This will lead to a cleaner interface since all you have to do is call the one method.
Its definitely up to you. OO design is very subjective. Here, it depends on whether you view suspension as a noun (a suspension) or a verb (to suspend). If the former, it likely becomes its own object with appropriate methods and attributes. If the latter, it becomes a set of related methods and attributes of the User object.
This brings up another issue: are you a minimalist? There are those that try to keep many, light classes as opposed to a few heavy ones.
Personally, I see cohesion/coupling as outweighing all those factors by orders of magnitude. Basically, for me, it would hinge upon whether other system entities need to know about suspensions without having a User object to query with. If so, the Suspension class would be born. If not, I would keep it as a part of the User class.
Well if adding a suspension is the only real action, I would go with the first option and make it an action carried out by the User class.
However, if you intend on making more functionality for Suspensions, I would consider creating a class like:
class SuspensionManager
suspendUser(....)
getSuspendedUser(...)
....
*This is my opinion is 100% debatable given that I don't know your entire code base/intention
I would say neither. But it really depends on how you view OOAD. I consider both User and Suspension classes have a single purpose. The User class has the responsiblity of holding information directly associated with a User (user table), and the Suspension class has the responsibility of holding information directly associated with a Suspension (suspension table). I would suggest making a UserSuspention class that has the responsibility of suspending a user.
This approach to OOAD is related to SOLID design principals. Having either the User or Suspension class be responsible for suspending a user would violate SRP (single responsibility principal)...since each class already has the responsibilty of maintaining information from their respective tables.
Your potential API may look like something below:
public class UserSuspension
{
public void SuspendUser(User user, Suspension suspension) { ... }
public void SuspendUser(Guid userId, string reason, DateTime expiryDate) { ... }
}
From these two options I would vote for Suspension::add(), if in fact this call would add an entry to the suspensions table. That way the effect that this call in the code has, in terms of the code itself (i.e. not the concepts represented by the code), would be clear: if I saw the code User::suspend(), I would expect it to modify a "suspended" flag for the User object, not modify something else in some other object.
On the other hand, in this particular instance, I think User::suspend() is more clear in general, so I would vote for it if it would mean that a suspended flag would be set for that User object, or if it would seem that way from the interface, i.e. if you wouldn't have to care where the suspension is stored since the interface of the User class would make it seem as if it's one of its properties.
This situation is very typical in web application design. It often becomes easier to deal with objects as being disconnected entities, as it saves you from having to retrieve objects to perform an operation for which you didn't really need the object.
The former is nicer from an OOP sense, the question is whether the performance impact of this would bother you:
User user = GetUser($userId); // unnecessary database hit?
user.suspend(reason, expiryDate);
I would be inclined to have an Account which linked the User and the Suspension
It depends.
This could be one of those scenarios where there isn't a definitely right answer. It will depend on how data will move through your system, as to whether it's of more benefit to view this relationship in a data-centric, or a user-centric model.
An old rule-of-thumb is to view objects as nouns and methods as verbs, when you're trying to model things. This would tend to suggest that User is an object, and suspend is an action you might perform.
Simple ? Not really.
Someone else might argue that it made more sense to describe the suspension as an 'AccountAction', and the application of the suspension as a verb. That might lead you to a model where various subclasses of an AccountAction have an applyTo method that acts on other object types.
You may need to apply your objects to an existing database schema, in which case you'll have to take into account how your persitance layer or ORM will interact with existing record structures.
Sometimes it's down to technology. OO can be implemented in subtly different ways across different language families and this too can influence the design. Some systems favour more solid inheritance graphs, other languages emphasise more loosely interconnected objects, passing messages around.
You need to be thinking through your design in terms of how you're going to want to interact with data and state. If you think about objects, as instances of classes, representing states of data, with behaviours that you will wish to invoke, you might find the nouns and verbs pattern falling out of the sentences that you use to describe the system.
As others have stated, it's very subjective.
Personally, I prefer the User::suspend() alternative simply because it allows me to implement (or change the implementation of) suspension whenever I like. It leaves all the suspension logic hidden behind the User interface.
I often times struggle with the same problem and what I do is I ask myself if this would make sense outside of the programming world. Would you ask ,in real life , a user to suspend him/herself? Would you ask a loan application to approve itself? If the answer is no, then there needs to a specialized authority/component/service that handles that and similar scenarios. In case of loan application, the approval should best be a part of loan approval service or loan specialist. If in your case, asking a user to suspend himself makes sense in the domain you're modeling then it should belong to the user. If not then, a service that handles user account suspension and similar user account level services may be a better place.