Given:
Spring MVC - Hibernate.
Controller -> Service -> DAO
Now I have a method which retrieves something from the DB and EVERYTIME it does this, has to do another method say "processList" (something like just changing some values in the list depending on some screen parameters).
Question:
What layer do I put this "processList"? (Controller, Service or DAO? and why)
I really need some j2ee clarifications now, I know that MVC is the same across languages but I just need to be sure :) If I am doing this in .net I would have undoubtedly put this in service.
This really depends on what processList is doing exactly. There is no golden rule. Some rules I try to follow are:
Never make calls between main objects on the same layer.
ManagementServiceImpl should never call NotificationServiceImpl.
Don't make circular dependencies between objects.
This is very similar to the one above.
If you find yourself repeating some logic across multiple main object, try to restructure the code and extract it in specialized logical classes (this will improve unit-testing as well).
E.g. UserUpdateHandler or NotificationDispatcher (these are still owned by the service layer -> noone else is allowed to call them)...
Put the code where it logically belongs.
Don't get distracted by the fact, that some class needs to do something. It might not be the right place for the code.
Never write fully generalised code before you need to.
This has its term as premature generalisation, which is a bad practice similar to premature optimisation. Saving few lines of code now can lead to pulling your hair out in the future.
Always write code which is able to become generalised.
This is not a contradiction with the previous. This says - always write with generalisation in mind, however don't bother with writing if it is not needed. Think ahead, but not necessarily act ahead.
Leave business logic to service layer, data persistence logic to data layer and user interaction logic to presentation layer.
Don't try to parse user input in service layer. This does not belong there similarly as counting final price in e-shop application does not belong to presentation layer.
Some examples for processList:
Example I - fetching additional relations via Hibernate#initialize
This is something which is really in between the service and DAO layer. On older projects we had specialized FetchHandler class (owned by service layer). In newer projects we leave this completely to DAOs.
Example II - go through list and add business validation messages to the result
service layer, no doubt
Example III - go through the list and prepare UI messages based on the validation errors
presentation layer
Side note:
MVC is a different thing from three-layered architecture.
M model spans across all three layers. Presentation layer includes both V views and C controllers.
Related
I have a question about Gateway to Entity dependency in Clean Architecture.
I think that the following concentric figures are often introduced as clean architecture.
In the figure above, Gateway does not look directly at the Entity.
However, there is another famous illustration of Clean Architecture. (2nd figure)
When it comes to actually creating a class, I think it will have the following structure.
Looking at this, the DataAccessInterface, which has the role of Gateway, refers to the Entity.
I think that the gateway in the first figure violates the rule that it does not refer to Entity. What does this mean? ??
Also, if Gateway refers to Entity, if you want to return your own error from Gateway, you need to put your own error definition in Entity. The original error is an error specific to the application, and I feel that it does not match the domain logic. Is such a definition method correct for clean architecture? ??
The most important thing is that dependencies point inwards. That means, that the layer containing the most precious business logic should not have dependencies to the outer layers.
If the Gateway works directly with some entity from the domain (or logic layer, in the diagram you're referencing named "Entities") and has a good reason to directly access it and bypass the application layer altogether, this can be a valid and pragmatic decision.
Sometimes there is no complex application logic that might justify introducing the indirection in the application layer. However, it is good to keep an eye on such decisions and make sure the application is being refactored when the time comes that an application service that translates from the Gateway to the entity layer is making sense. Just make sure you work with what is provided by the entity (business) layer to fit the business logic and invariants. As soon as you would have to change something in your entity just to fit some needs of the outer layers this is a smell and some indirection (such as the application layer in between translating between the two layers) is definitely needed.
Concerning the error it is a similar decision. As long as the entity (in the domain
logic layer) does only have to know about errors that are meaningful from the business perspective it could be to okay directly use that error if it fits the needs of the "outside" world the Gateway is talking to
So again, it is a decision depending on your situation. Just keep in mind that it is important to NOT extend the entities in the business/domain logic layer just to fit any infrastructure related needs, such as providing different structuring of error information or additional technical details that have no meaning in the business world.
I guess traditionally, one would for a RESTful web service use one type of DTO objects for POJO/JSON conversion, and a separate DTO object for database entity/POJO conversion?
Spring Boot should be more opinionated and easier to use, but would you still use different DTO object types for JSON and database entity representation, or do you convert entity objects directly to JSON?
Let me share my opinion.
At first, I think your question has nothing to do with spring boot. Spring boot just provides a fancy and lightweight way to start the application and allows to build the app in an easier manner.
But still you have your rest controller there and from that point it doesn't differ much for any other type of application.
So what you're actually asking is whether it makes sense to maintain an abstraction of JSON objects and converting them to the Business Logic Entity objects and later on converting them once again to Database objects or its enough to maintain only 2 levels and ditch the Json level.
I think the answer is "it depends".
First of all, In general currently the trend is a simplification. So maybe its enough to maintain only 1 level of objects.
There are a lot of advantages of such an approach:
Obviously less code to maintain
Speed of development and testing (POJOs should be checked, converters should be tested and so forth)
Speed of execution - you don't need to waste the CPU time on conversion. A kind of obvious implication.
Less obvious: Memory consumption. Lets say you work with a big bulk of data returned by your DAO. Let's say it occupies 10MB of memory (just for the sake of example). Now if you start to convert, to Business Entities, you'll spend yet another 10MB and now if its A JSon objects, well its again 10MB. The point is that all these objects may co-exist in memory simultaneously. Of course GC will probably take care of them if you implemented everything right, but this is a different story.
However there is one drawback of such a simplification.
In one word I would call it a Commitment
There are three Types of APIs in the application.
The API you're committed to at the level of Web Service - The JSon structure.
The chances are that various clients (not necessary using the JVM at all) are running against your Web service and consume the data. So they really expect you to provide a JSon objects of the given structure.
The API of your business. If your Business logic layer is pretty complicated, you probably have an entire team that develops that logic. So you usually work at the level of APIs between the teams.
The level of DAO - the same story as Business Logic actually.
So now, what happens if you, say, change that API at one level. Does it mean that all the levels will be broken?
Example
Lets say, we don't maintain "JSon" level. In this case, if we change the API at the level of Business Logic, the JSON will also change automatically. All the rest frameworks will happily convert the object for us, and the chances are that the user will get another data.
Another example
Lets say, your BL layer provides a Person entity that looks like this:
class Person {
String firstName;
String lastName;
List<Language> languages;
}
class Language {
...
}
Now, let's say you have a UI that consumes your REST service that provides a list of Persons upon request. What if there are 2 different pages in UI. One that shows only the Persons (in this case it doesn't make sense to provide a list of language, spoken by a person).
In the second page however you want to get the full information.
So, you'll end up exposing 2 web services or complicating the existing one by some parameters (the more params like this you have, the less it resembles the rest :) )
Maybe separation would help a little here? I don't know.
Bottom line.
I would say that as long as you can live without such a separation - do it. It can work even for quite big projects. And of course it can work for small or middle-sized projects.
If you find yourself struggling around fixes and you feel like such a separation would solve the issues - do the separation.
Hope this helps to understand the implications and chose what works for you
I've been reading a lot of blogs which advocate the fat models and skinny controllers approach, esp. the Rails camp. As a result the routers is basically just figuring out what method to call on what controller and all the controller method does is call the corresponding method on the model and then bring up the view. So I've two concerns here which I don't understand:
The controller and router are really not doing much different tasks other than just calling a method on the God-like model based on the route.
Models are doing too much. Sending emails, creating relationships, deleting and modifying other models, queuing tasks, etc. Basically now you have God-like objects that are supposed to do everything that may or may not concern with modeling and dealing with data.
Where do you draw the line? Isn't this just falling into the God pattern?
It might not be the best idea to look at Rails as a staple of MVC design pattern. Said framework was made with some inherent shortcomings (I kinda elaborated on it in a different post) and the community only just now has begun addressing the fallout. You could look at DataMapper2 development as the first major step.
Some theory
People giving that advice seem to be afflicted by a quite common misconception. So let me begin by clearing it up: Model, in modern MVC design pattern, is NOT a class or object. Model is a layer.
The core idea behind MVC pattern is Separation of Concerns and the first step in it is the division between presentation layer and model layers. Just like the presentation layer breaks down into controllers (instances, responsible for dealing with user input), views (instances, responsible for UI logic) and templates/layouts, so does the model layer.
The major parts that the model layer consists of are:
Domain Objects
Also known as domain entities, business objects, or model objects (I dislike that latter name because it just adds to the confusion). These structures are what people usually mistakenly call "models". They are responsible for containing business rules (all the math and validation for specific unit of domain logic).
Storage Abstractions:
Usually implemented using data mapper pattern (do not confuse with ORMs, which have abused this name). These instances usually are tasked with information storage-from and retrieval-into the domain objects. Each domain object can have several mappers, just like there are several forms of storage (DB, cache, session, cookies, /dev/null).
Services:
Structures responsible for application logic (that is, interaction between domain objects and interaction between domain objects and storage abstractions). They should act like the "interface" through which the presentation layer interacts with the model layer. This is usually what in Rails-like code ends up in the controllers.
There are also several structures that might be in the spaces between these groups: DAOs, units of work and repositories.
Oh ... and when we talk (in context of web) about a user that interacts with MVC application, it is not a human being. The "user" is actually your web browser.
So what about deities?
Instead of having some scary and monolithic model to work with, controllers should interact with services. You pass data from user input to a specific service (for example MailService or RecognitionService). This way the controller changes the state of model layer, but it is done by using a clear API and without messing with internal structures (which would cause a leaky abstraction).
Such changes can either cause some immediate reaction, or only affect the data that the view instance requests from model layer, or both.
Each service can interact with any number (though, it's usually only a handful) of domain object and storage abstractions. For example, the RecogitionService could not care less about storage abstractions for the articles.
Closing notes
This way you get an application that can be unit-tested at any level, has low coupling (if correctly implemented) and has clearly understandable architecture.
Though, keep in mind: MVC is not meant for small applications. If you are writing a guestbook page using MVC pattern, you are doing it wrong. This pattern is meant for enforcing law and order on large scale applications.
For people who are using PHP as primary language, this post might be relevant. It's a bit longer description of the model layer with a few snippets of code.
If the "model" classes are implemented poorly yes, your concern is relevant.
A model class shouldnt be doing Email (infrastructure tasks).
The real question is what does model in MVC imply.
It isnt restricted to POCO classes with a few methods.
Model in MVC means Data and Business logic. Treat it as a superset of classic core POCO models.
View ==== Controller ==== Model ---> Business Process layer --> Core models
Throw in Infrastructure assemblies and Data Access layers and use injection to hand that into the BPL then your a process is using MVC as intended.
BPL may invoke UoW / Respository patterns, and execute business rules and call Infrastructure features by way of injected Objects or interface patters.
So the recommendation to keep a controller skinny doesnt mean the "person" class in a classic Core model should have 50 methods, and call Email directly. You are right to think this is wrong.
The Controller May still be required to instantiate and inject Infrastructure classes into the BPL or core layer if called directly. There should be a business layer or at least classes orchestrating calls across Classic Object model classes.
Well thats my "view" anyway ;-)
For generic take on MVC the wiki description http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
A Little Blog that talks about the "M" in MVC. http://www.thedeveloperday.com/skinny-controllers/
I think you can make a distinction between a single fat model (possibly named App or Application), and several fat models broken down into logical groups (Business, Customer, Order, Message). The latter is how I structure my apps, and each model roughly corresponds to a database table in a relational database or collection in a document database. These models handle all aspects of creating, updating, and manipulating the data that makes up the model, whether it is talking to the database or calling an API. The controller is very thinm responsible for little mor that calling the appropriate model and selecting a template.
Assuming the you are implementing a user story that requires changes in all layers from UI (or service facade) to DB.
In what direction do you move?
From UI to Business Layer to Repository to DB?
From DB to Repository to Business Layer to UI?
It depends. (On what ?)
The best answer I've seen to this sort of question was supplied by the Atomic Object guys and their Presenter First pattern. Basically it is an implementation of the MVP pattern, in which (as the name suggests) you start working from the Presenter.
This provides you with a very light-weight object (since the presenter is basically there to marshal data from the Model to the View, and events from the View to the Model) that can directly model your set of user actions. When working on the Presenter, the View and Model are typically defined as interfaces, and mocked, so your initial focus is on defining how the user is interacting with your objects.
I generally like to work in this way, even if I'm not doing a strict MVP pattern. I find that focusing on user interaction helps me create business objects that are easier to interact with. We also use Fitnesse in house for integration testing, and I find that writing the fixtures for Fitnesse while building out my business objects helps keep things focused on the user's perspective of the story.
I have to say, though, that you end up with a pretty interesting TDD cycle when you start with a failing Fitnesse test, then create a failing Unit Test for that functionality, and work your way back up the stack. In some cases I'm also writing Database unit tests, so there is another layer of tests that get to be written, failed, and passed, before the Fitnesse tests pass.
If change is likely, start in the front. You can get immediate feedback from shareholders. Who knows? Maybe they don't actually know what they want. Watch them use the interface (UI, service, or otherwise). Their actions might inspire you to view the problem in a new light. If you can catch changes before coding domain objects and database, you save a ton of time.
If requirements are rigid, it's not as important. Start in the layer that's likely to be the most difficult - address risk early. Ultimately, this is one of those "more an art than a science" issues. It's probably a delicate interplay between layer design that creates the best solution.
Cheers.
I'd do it bottom up, since you'll have some working results fast (i. e. you can write unit tests without a user interface, but can't test the user interface until the model is done).
There are other opinions, though.
I would start modeling the problem domain. Create relevant classes representing the entities of the system. Once I feel confident with that, I'd try to find a feasible mapping for persisting the entities to the database. If you put too much work into the UI before you have a model of the domain, there is a significant risk that you need to re-work the UI afterwards.
Thinking of it, you probably need to do some updates to all of the layers anyway... =)
I read a text recently saying the MVC pattern describes the layers in an application. But personally I see MVC showing several key roles in an application.
Which word do you think is better, layer or role, to describe the three main pieces of MVC?
Layers should imply a very narrow coupling between the respective sets of code. MVC involves relatively tight coupling between the model, view, and controller. Therefore, if you characterize this as a layering pattern, it becomes problematic in terms of defining an API between the layers. To do this properly, you would have to implement some unintuitive patterns.
Because of this, I would agree with your tendency to view it as a pattern that defines roles within a single layer.
I think roles is a better description. The view and the controller are both in the same "layer" and usually the model is described as a layer but is used between layers.
Usually my applications are centered around the domain model with stuff like presentation, persistence and file-io around it. Thinking about an architecture as layered doesn't really work for me.
MVC clearly defines ROLES. these are 3 roles you can implement in any number of layers. For example u can have a multi layer controller
Roles, not layers. Layers are completely dependent on the underlying implementation of the MVC pattern. For instance, a service layer may be a single layer on one implementation, but it could have a web service remoting layer and a database layer (for two differing service layers) on another implementation. The concept of layers is just to help you organize it, as is the pattern, but layers are not as easy to spot as patterns, and layers can change, whereas the pattern remains the same despite the layers changing due to different implementations.
You cannot compare those two words, because they describe different concepts.
To me, a layer is something opaque that offers some functions I can use to do things. For example, a good hardware layer for a wireless transmitter would just give me a send and a receive-function (based on bytes, for example), hiding all the ugly, ugly details from me.
A role is a way an object will behave. For example, a transformation in one of my compilers is going to take an abstract syntaxtree and return an abstract syntaxtree or an affection in my current project is going to take a state-difference and return a specifically altered state-difference.
However, coming with those two definitions, I do not see the need to chose a single "correct" term and burn the other as wrong, because they don't conflict much. A part of a layer has a certain role, and a set of objects conforming to certain roles form a layer. Certainly, the controller forms a certain layer between the UI and the model (at least for input), however, ot also has a role - it turns certain event into certain other events (and thus, it is some sort of adapter).
I think either can be reasonably argued for, but I think describing the parts as "layers" is more consistent with other conventions, like the OSI model. Since the View, Controller, and Model get progressively closer to your data, it's more of a layered structure. It seems that "roles" would apply to different parts of an application on the same layer.
Why not Both? I see it as 3 separate layers implementing 3 different roles.
It's all terminology, but I think the correct software architecture term would be "layer", as in logical layer. You could use the term "architectural layer" if it is clearer.
The thing is, it's just a different way of slicing an application: a classic n-layer app would be:
UI
Business Logic
Persistence
You could have the following logical layers in a simple MVC application:
UI
Controller
Model
Persistence
But you could still talk about the "UI" and "Controller" together as forming the User Interface layer -- I usually split out the Controller into a separate layer when describing and diagramming these architectures, though.