MVC - where do you put methods relating to multiple instances of your model? - model-view-controller

This is a simple question but I can't find a straight answer anywhere. It's the base concepts I'm interested in so I've kept it simple...
Say I have a 'post' model for a blog, I'm going to have to use a getAllPosts method at some point - retrieving all the posts from the database, and instantiating a Post object for each so I can display a list of them
If a User owned the Posts then knowing where to put this code would be easy - you'd put a getPosts method on the User model and it would return posts belonging to the user.
The question is: Where do you put methods which handle multiple instances of a Model which aren't owned by anything else in the system?
I've considered these options, and listed my concerns:
Just interact with the database from the index method of a PostController. Surely this can't be right because my Controller shouldn't know about the database, I want them decoupled so that future changes won't be hard to implement
Put a getAll method on the Post model as a static method so that you don't need a Post instance to call it. I've read that static methods make things hard to test and that this is against the principles of OOP
Create a PostRepository with a getAllPosts method. This is my current preferred option but having read up about the repository pattern - with its links to unit of work etc. - it feels like overkill. It would also implement similar methods to those I think I'm supposed to have on the Post model, like update and delete
Create a PostCollection class which has responsibility for anything relating to many Posts, and leave the Post class for anything related to a single Post. This is ok, but I haven't seen any mention of it elsewhere
Create a pointless 'owner' of the posts, like a User or Admin class, of which there is only 1 instance, and it simply houses a getUserPosts method
What's the simplest way to solve this?

Option #3 is the best one, and it's preferred to create Unit of Work pattern in case there is transactional operations.
Another option is to create a service layer (ManagePostsService) which may be used as a DomainService that works with multiple entities, this service will invoke the repository or unit of work, see Domain-Driven Design.
Bear in mind, that in all cases it's not preferred to communicate with data sources e.g.database from Domain Entities (User, Post), these are independent and should only contain their natural behavior through encapsulation.
You may find these architectures helpful:Clean Architecture, The Onion Architecture, Hexagonal architecture and Ports & Adapters Architecture

Related

In Laravel, what is the advantage of single action controllers?

A topic about single action controllers is in the laravel documentation:
https://laravel.com/docs/5.5/controllers#single-action-controllers
My question is, what is the use case where you will use this controllers? How will you structure your controllers if you opt to use single action controllers for all your controllers?
Michale Dyrynda seems to sum up the pupose of Single Action Controllers in his blog: https://dyrynda.com.au/blog/single-action-controllers-in-laravel
Conclusion
Single action controllers are an effective way to wrap up simple functionality into clearly named classes.
They can be used in instances where you're not necessarily following a RESTful approach; be careful not to separate multiple actions for a single entity across multiple controllers.
Where you might have previously used a single controller for multiple static pages, you could consider separate named controllers for each static pages.
You can add other methods to this class, but they should be related to the single action this controller is responsible for.
He also states that, you should only use these when you only need a single action for an entity:
You may consider naming the controller ShowPost as a way of being explicit about the controller's intent but I'd suggest caution with this approach; if you start seeing ShowPost, EditPost, CreatePost, etc controllers creeping into your codebase, I'd reconsider the RESTful approach. More controllers never hurt anybody, but we should be smart about when this is done!
This is an intresting question and my answer is not related to laravel, but to the single vs multiple actions per controller.
I have found when trying to find the use case for a pattern that is new, is to ask the inverse questions, in this case, when is the use case of multiple actions per controller make sense?
The answer usualy comes to:
You have an object that has crud operations (because your using sql)
and its convenient to place all the stuff related to that object in
one spot.
This is akin to the answer of "I have a hammer, so everything is a screw" and IF your domain is as simple as a thin layer over a crud database, then that is the use case for multiple actions per controller.
What I have found is that any amount of complexity blows up the controllers, no matter how good your model is. The reason is CRUD opperations are apart of your model, not your controller.
We usually think that we will map nicely to a CRUD model in our controller, there are many front end frameworks that work amazing at that, untill....
Look at the most common aspect of applications, users. In the setup your going to have index of users, which I don't know who would look at that page besides admins, and they usualy want extra information. so for the index action, you need admin custom authentication.
Then creation, well, it does not make sense to have an user create an user, you need to ensure the user is not authentication.
Now we talk about reading. What data an admin, other users, current user, and anon user can see is massivily differnt, and will slowly build up in complexity.
Then delete, this is normally rare action, and on some models not needed, but you still put it up, because, well you have a hammer.
The update, do you put password updates in here too? what if the user forgot there password? do you put that in here? No, you make a new action called forgot password.
Well now you need update password action. What goes in the update is usually a gigantic mess of hell after a year.
Each pattern has its pros and cons, my general advice is to do multiple actions per controller when your system is trully CRUD OR you will not have to maintain the project for more than a year. If you have any amount of complexity that will have to maintained, avoid the model leaking into the controller and keep them seperate.

MVC - which methods should be in Model class except set/get members?

Should methods that manipulate the Model class members be implemented in the Model or in the Controller? Does it depend on how "heavy" this manipulation is ?
By "manipulation" I mean:
get a class member
make a long calculation based upon this class member
return another value which relates to this class
For example, a Board class which hold a cell matrix member.
Now I want to implement a method which returns all the surrounding cells according to specific cell location.
Is the model or view responsible to for implementing the above ?
If this question belongs to another Stack Exchange QA site I will welcome the recommendation to move my post to that site.
Keep your controllers thin, don't let them do much, this aligns with the Single Responsibility Principle in SOLID for Object Oriented Design. If you have fat controllers, they become hard to test and maintain.
As for the models, I used to have dumb models before that did nothing but to map to database tables and that was inspired by most of the sample applications that you see on the web, but now I don't do that.
I (try to) follow the principles from Domain Driven Design, where models (entities in DDD terms) are at the center of the application, they are expected to encapsulate behaviour related to the entity, they are smart models (so yes, the logic related to an object will live with it in that case). DDD is a much bigger topic and it is not related directly to MVC, but the principles behind it helps you better design your applications, there is a lot of materials and sample apps available if you google DDD.
Additionally, Ruby On Rails community - which seems to inspire most of MVC frameworks - also seems to have a hype around having Fat Models and Skinny Controllers.
On top of that, you can add View Models to your mix which I find helpful. In this case, you can have a ViewModel to represent a dumb subset of your model(s) just to use for generating the view, it makes your life easier and further separate your Views from your Models so that they don't affect your design decisions unnecessarily.
What you call "model" is are actually domain objects. The actual model in MVC is just a layer, not concrete thing.
In your particular example, the Board should have a method that returns this list. I assume, that you are actually acquiring it because you then need to do further interaction with those cells.
This is where the services within the model layer comes in to play. If you use them, they are the outer part of model layer and contain the application logic - interaction between different domain objects and the interaction between the persistence (usually either data mappers or units of work) and domain objects.
Let's say you are making a game, and you and player performs and AoE attack. Controller takes a hold of service, which is responsible for this functionality and sends a command: this player aimed AoE in this direction, perform it.
Service instantiates Board and asks for surrounding cells of the target location. Then it performs "damage" on every cell in the collection that it acquired. After the logic is done, it tell the Unit of Work instance to commit all the changes, that happened on the Board.
Controller does not care about the details of what service does. And it should not receive any feedback. When execution gets to the view, it request from model layer the latest changes and modifies the UI. As the added benefit - services let you stop the business logic from leaking in the presentation layer (mostly made up from views an controllers).
The domain object should contain only methods, that deal with their state.
I think this has little to do with MVC, and a lot more to do with regular software engineering.
I personally wouldn't hesitate to stick trivial calculations in a model, but would be extremely wary of fat models.
Now, the fact that MVC stands for Model View Controller doesn't necessarily mean that everything should be either a view, a model or a controller. If you feel the need to move responsibilities to a separate class that doesn't really qualify as an M, a V or a C, I don't see why you shouldn't do it.
The way you implement it is up to you. You could either use this separate class as a "top level" (for lack of a better term) object, or make a method of the model delegate to it, so as to hide the fact that you're using it. I would probably go for the latter.
Everything is debatable, though. Everybody and their sister seem to have a different opinion on how to do MVC right.
Me, I just consider it a guideline. Sure, it's a great idea because it leads you to a better separation of concern, but in the end—as it always happens—there's no one-size-fits-all way to apply it, and you should not be overly constrained by it, to the point where everything has to be either a view, a model or a controller.
As per best practice we should use properties for Calculated fields with get access only. example public double TotalCost {
get
{
return this.Role.Cost * TotalHour;
}
}

How to encapsulate web2py business logic?

I just found web2py a couple days ago, and have been reading the documentation and through the source of a few example applications. I want to start programming more in Python. It seems that my take on MVC is a little skewed from theirs [web2py community].
After learning and working with PHP (and the Kohana framework), I'm used to the thin controller - fat model principle, where all business logic is placed in the model and the controller does nothing more than delegate what methods to perform on the model, and then passes data onto the view for rendering. However, it seems that 99% of the applications I've seen for web2py have fat controllers (putting all business logic in the actions), and the models are nothing more than table/constraint definitions.
I'm pretty well set on my view of a model, and I would rather put the business logic in the models (for re-usability and DRY code) but I haven't seen any code online that does this, although, to be fair, I haven't found an ample amount of applications. Can somebody point me in the right direction.
To be clear, I would like to make my models actual classes and encapsulate all business logic and database interactions into explicit methods. Something along the lines of...
class Article(object):
def get_article(self, id):
# Retrieve article by id, using db instance
pass
def get_latest_articles(self, limit):
# Retrieve latest articles
pass
def get_hot_articles(self, limit):
# Retrieve hot articles, based on algorithm for "hot"
pass
def create_article(self, data):
# Insert article
pass
def define_tables(self):
# Define schema the web2py way
pass
I haven't found the right way to do this.
I'm not very well rehearsed on web2py, but I know there are a lot of features. The DAL, for instance, seems to be a very powerful feature which is tightly integrated with other helpers. I wonder if splitting my business logic as stated above would limit any of these features?
I think part of the difference is that web2py uses a DAL (database abstraction layer) rather than an ORM. You might find this explanation helpful. As it points out, in some cases, computed fields or virtual fields may do what you want. Also, some of the methods defined in your example class would be quite simple DAL statements and would probably not be worth writing methods for.
Of course, if you want, you can define classes and functions in your models (or modules) and simply call them from your controllers -- whatever works best for you.

What are your best practices when using an MVC-based web framework?

A few general questions to those who are well-versed in developing web-based applications.
Question 1:
How do you avoid the problem of "dependency carrying"? From what I understand, the first point of object retrieval should happen in your controller's action method. From there, you can use a variety of models, classes, services, and components that can require certain objects.
How do you avoid the need to pass an object to another just because an object it uses requires it? I'd like to avoid going to the database/cache to get the data again, but I also don't want to create functions that require a ton of parameters. Should the controller action be the place where you create every object that you'll eventually need for the request?
Question 2:
What data do you store in the session? My understanding is that you should generally only store things like user id, email address, name, and access permissions.
What if you have data that needs to be analyzed for every request when a user is logged in? Should you store the entire user object in the cache versus the session?
Question 3:
Do you place your data-retrieval methods in the model itself or in a separate object that gets the data and returns a model? What are the advantages to this approach?
Question 4:
If your site is driven by a user id, how do you unit test your code base? Is this why you should have all of your data-retrieval methods in a centralized place so you can override it in your unit tests?
Question 5:
Generally speaking, do you unit test your controllers? I have heard many say that it's a difficult and even a bad practice. What is your opinion of it? What exactly do you test within your controllers?
Any other tidbits of information that you'd like to share regarding best practices are welcome! I'm always willing to learn more.
How do you avoid the problem of "dependency carrying"?
Good object oriented design of a BaseController SuperClass can handle a lot of the heavy lifting of instantiating commonly used objects etc. Usage of Composite types to share data across calls is a not so uncommon practice. E.g. creating some Context Object unique to your application within the Controller to share information among processes isn't a terrible idea.
What data do you store in the session?
As few things as is humanly possible.
If there is some data intensive operation which requires a lot of overhead to process AND it's required quite often by the application, it is a suitable candidate for session storage. And yes, storage of information such as User Id and other personalization information is not a bad practice for session state. Generally though the usage of cookies is the preferred method for personalization. Always remember though to never, ever, trust the content of cookies e.g. properly validate what's read before trusting it.
Do you place your data-retrieval methods in the model itself or in a separate object that gets the data and returns a model?
I prefer to use the Repository pattern for my models. The model itself usually contains simple business rule validations etc while the Repository hits a Business Object for results and transformations/manipulations. There are a lot of Patterns and ORM tools out in the market and this is a heavily debated topic so it sometimes just comes down to familiarity with tools etc...
What are the advantages to this approach?
The advantage I see with the Repository Pattern is the dumber your models are, the easier they are to modify. If they are representatives of a Business Object (such as a web service or data table), changes to those underlying objects is sufficiently abstracted from the presentation logic that is my MVC application. If I implement all the logic to load the model within the model itself, I am kind of violating a separation of concerns pattern. Again though, this is all very subjective.
If your site is driven by a user id, how do you unit test your code base?
It is highly advised to use Dependency Injection whenever possible in code. Some IoC Containers take care of this rather efficiently and once understood greatly improve your overall architecture and design. That being said, the user context itself should be implemented via some form of known interface that can then be "mocked" in your application. You can then, in your test harness, mock any user you wish and all dependent objects won't know the difference because they will be simply looking at an interface.
Generally speaking, do you unit test your controllers?
Absolutely. Since controllers are expected to return known content-types, with the proper testing tools we can use practices to mock the HttpContext information, call the Action Method and view the results to see they match our expectations. Sometimes this results in looking only for HTTP status codes when the result is some massive HTML document, but in the cases of a JSON response we can readily see that the action method is returning all scenario's information as expected
What exactly do you test within your controllers?
Any and all publicly declared members of your controller should be tested thoroughly.
Long question, longer answer. Hope this helps anyone and please just take this all as my own opinion. A lot of these questions are religious debates and you're always safe just practicing proper Object Oriented Design, SOLID, Interface Programming, DRY etc...
Regarding dependency explosion, the book Dependency Injection in .NET (which is excellent) explains that too many dependencies reveals that your controller is taking on too much responsibility, i.e. is violating the single responsibility principle. Some of that responsibility should be abstracted behind aggregates that perform multiple operations.
Basically, your controller should be dumb. If it needs that many dependencies to do its job, it's doing too much! It should just take user input (e.g. URLs, query strings, or POST data) and pass along that data, in the appropriate format, to your service layer.
Example, drawn from the book
We start with an OrderService with dependencies on OrderRepository, IMessageService, IBillingSystem, IInventoryManagement, and ILocationService. It's not a controller, but the same principle applies.
We notice that ILocationService and IInventoryManagement are both really implementation details of an order fulfillment algorithm (use the location service to find the closest warehouse, then manage its inventory). So we abstract them into IOrderFulfillment, and a concrete implementation LocationOrderFulfillment that uses IInventoryManagement and ILocationService. This is cool, because we have hidden some details away from our OrderService and furthermore brought to light an important domain concept: order fulfillment. We could implement this domain concept in a non-location-based way now, without having to change OrderService, since it only depends on the interface.
Next we notice that IMessageService, IBillingSystem, and our new IOrderFulfillment abstractions are all really used in the same way: they are notified about the order. So we create an INotificationService, and make MessageNotification a concrete implementation of both INotificationService and IMessageService. Similarly for BillingNotification and OrderFulfillmentNotification.
Now here's the trick: we create a new CompositeNotificationService, which derives from INotificationService and delegates to various "child" INotificationService instances. The concrete instance we use to solve our original problem will delegate in particular to MessageNotification, BillingNotification, and OrderFulfillmentNotification. But if we wish to notify more systems, we don' have to go edit our controller: we just have to implement our particular CompositeNotificationService differently.
Our OrderService now depends only on OrderRepository and INotificationService, which is much more reasonable! It has two constructor parameters instead of 5, and most importantly, it takes on almost no responsibility for figuring out what to do.

Using MVC, how should one handle communication between Views? Between Models?

Question number three in my quest to properly understand MVC before I implement it:
I have two cases in mind:
The primary application
window needs to launch the
preferences window. (One View
invoking another View.)
The primary Model for an application
needs to access a property
in the preferences Model. (One Model
accessing another Model.)
These questions are related in that they both involve communication across Model-View-Controller triplets, a topic that I haven't found much discussion of in my Googling.
The obvious way to fix this is to wrap everything in a top-level "application" object that handles transactions between Models and allows Controllers to invoke one another's methods. I have seen this implemented, but I'm not convinced its a good idea. I can also see possibilities involving Controllers observing more than one Model and responding to more than one View, but this seems like its going to become very cluttered and difficult to follow.
Suggestions on how best to implement this sort of cross-talk? I feel like its a very obvious question, but I've been unable to find a well-documented solution.
On a broader note, if anyone has a link that shows typical approaches to these sorts of MVC issues, I would love to see it. I haven't had much luck finding solid, non-trivial references. Examples in Python would be lovely, but I'll gladly read anything.
Edit 1:
I see some pretty interesting things being said below and in general no-one seems to have a problem with the approach I've described. It is already almost a lazy form of the FrontController design that Vincent is describing. I certainly don't foresee any problems in implementing that pattern, however, it doesn't seem that anyone has really addressed the question in regards to communication amongst Models. All the answers seem to be addressing communication among objects in a single Model. I'm more interested in maintaining separate Models for separate components of the application, so that I'm not stuffing fifty state properties into a single Model class. Should I be maintaining them as sub-Models instead?
With respect to (1), views don't invoke other views. They invoke controller actions that may result in other views being rendered. In your case, the primary application window contains a user interface element (button, link) that invokes a controller action to display the preferences window.
With respect to (3), model components certainly could be related to one another. This isn't unexpected nor to be avoided, necessarily. For instance your Customer model may have an associated set of Orders. It would be perfectly natural to access the customer's orders via a method in the Customer class.
You might want to take a look at the MVC page on wikipedia for an overview.
You may want to consider looking up the Front Controller design pattern.
The Front Controller pattern defines a single component that is responsible for processing application requests. A front controller centralizes functions such as view selection, security, and templating, and applies them consistently across all pages or views. Consequently, when the behavior of these functions need to change, only a small part of the application needs to be changed: the controller and its helper classes.
This way all requests from the view goes to the FrontController who then decides which specific action (controller) to invoke. Sometimes, it could forward straight to another view as in your first case.
There is no problem with multiple objects in the model talking to each other. In fact that will be very common. The way I see it, all the objects in the Model act like one component to represent the data and operations on the data.
This article might help. And this one.
Model does not mean a single model object. The model is the subset of the entirety of your domain model which is directly related to the controller actions and the views in question.

Resources