Ideally, controllers in a Spring MVC application must receive a request, despatch the request to an API, load the results (of the invocation) on to the model (for the view to subsequently render it) and forward to a view. They should do no more.
My controllers do far more than this today and I would like to move certain resposibilities away from the controller on to other APIs. My application design today (pretty typical):
controller <-> Service API <-> DAO <-> DB
The controller today fills up the delta between what the web app needs and what the Service API delivers.
I would like to place extra layer/layers between the controller and service API that chew away at this delta. My question is what layer(s) should these be and what should the responsibilities of these new layer(s)?
My current Idea is as follows
controller <-> controller helper <-> Business API <-> Service API <-> DAO <-> DB
Controller helper (web context aware - will depend on Model, HttpServlet and other web context classes):
Convert entities to DTO objects (2 way)
Resolve IDs to entities. E.g. Controller looks up a student i.d. (using a key) and converts it to a Student entity.
Business API (no web context dependency - can be JUnit tested):
Acts as a Facade. Invoking multiple service APIs to achieve one
business request.
Providing APIs that are specifically tailered for the web app.
Would you solve this a different way? Are there any resources (books, articles etc...) relating to this specific issue?
Some of previous discussions that did not answer my question:
Designing mvc controller layer
Service layer = Application layer = GRASP Controller layer
Moving Validation, Html Helpers to Service Layer in MVC
Thanks,
Vijay
Services contain the general business logic of an application. They are pretty much anything between Controllers and DAO/DB.
Your "business layer" and "controller helper" are just more services. I would keep the classic design for the sake of simplicity :
Controllers <-> possible Services <-> possible DAOs <-> DB
If I had lots of services (I usually don't) that happened to perform the same kind of logic, I would naturally split them into sub-packages. For example :
services.facade, or services.business
services.adapter for DTOs (except if you use simple classes to do this job)
A facade service is called by controllers like so : someFacade.someMethod(SomeDTO someDto). Then the facade handles DTO <-> Entity conversion thanks to other services (or simple classes).
That's how I would do in your context. In an ideal world (no legacy systems, or in a project from scratch), I'd directly use entities as form objects (instead of DTOs), and most of my services would be facades (the rest would be simple classes, if possible).
I'm new to Spring MVC and am also faced with this dilemma. Although Spring is new to me, I've been working with MVC for several years. I agree a controller should do no more than accept requests, dispatch them, and render the results in the correct format. I'm of the opinion that a service isn't necessarily the best place for the helper abstraction to exist though. I believe a service should encapsulate a specific API and do nothing more. I feel creating many 'types' of services convolutes this pattern and makes it unclear where the responsibilities fall.
It's my belief that helpers are better suited as siblings to services; they should be decorated with #Component instead of #Service. Their role is to act as a facade for the underlying APIs that are needed to transition state on the models exposed through the endpoint. The Controller->Helper->[Services] pattern promotes a clear separation of concerns, code-reusability, and is highly testable. The nature of this pattern is to prevent controller bloat, so you end up with ultra-thin controllers that really do nothing more than dispatch requests and render responses.
Related
I'm implementing a series of REST micro services in Java - let's call them "adapters".
Every service reads the data from a particular source type, and provides result in the same way. The main idea is to have the same interface (service contract) for all of them, to get interchangeability. I would like to avoid code duplication and reuse the service contract for the services.
And it seems that I'm reinventing the wheel. Is there a standard approach for this?
I tried to extract the service contract in form of Java interface for Spring MVC Controller class and accompanying DAO class CustomObject:
public interface AdapterController {
#RequestMapping(method = RequestMethod.GET, value = "/objects/{name}")
CustomObject getObject(#PathVariable final String name);
}
Then put them into separate Maven project, set it as a dependency in the original project, and rewrote REST controller class as following:
#RestController
public class DdAdapterController implements AdapterController {
#Override
public CustomObject getObject(String name) {
return model.getByName(name);
}
I can reuse DAO object in a client code as well, but the interface class is useless at client side.
1) Summarizing: is it OK to reuse/share service contract between different service implementations? What's the cost of this? Is there the best practice how to share service contract?
2) The next question is about service contract and consuming client. Is it OK to share the contract between service and client? Is there some tools in Java / approach for this?
This goes against the microservice mentality and in the long run is a bad idea to share code.
If you start sharing code you will slowly just build a distributed monolith, where multiple services are dependent on each other.
Many have talked about this earlier:
microservices-dont-create-shared-libraries
The evils of too much coupling between services are far worse than the problems caused by code duplication
Micro services: shared library vs code duplication
The key to build microservices is:
One service should be very good at one thing
Keep them small
Have an extremely well documented api
When you need to delete a microservice this should be done with as few needs to update other services
Avoid code sharing, and treat all libraries like 3rd party libraries even your own
Microservises should by loosely coupled = minimum dependencies.
Microservices is an
architectural style that structures an application as a collection of
services that are
Highly maintainable and testable
Loosely coupled
Independently deployable
Organized around business capabilities.
https://microservices.io/
Contract can be defined with WADL
Using contract between client and server means less bugs, less missunderstandings when implementing client. That is what the contract good for.
First I'd like to begin by illustrating the basic idea that I want to get done.
I'm designing a system by following the layered model view controller design. I essentially have a server and I would like to use tablets as the view/display. Now because I want to send data to and from the tablets through serialization, I can't figure out where to play the view controller classes for those tablets.
Ideally, when you'll boot up the tablet, you will have an option as to which view you wish the tablet to display (1 through whatever), but a view can't instantiate it's own controller I don't think.
So I just don't know where to have the view controller that technically creates the said views and how to allow it to communicate to said tablets. (This will be done in java/android)
MVC pattern is meant for one machine. So you can have the MVC pattern on your tablet. The controller here is kind of the glue code which instantiates the view and also creates the models (DAOs - Data Access Objects) to get data from the server.
This is all independent from what you will use on the server. You could say that on the server you also want to have something similar like MVC - in that case, the controller handles the REST, SOAP, ... - requests and instantiates a DAO which will retrieve the information from a file, database, ... The view afterwards could be seen as a serialiser which creates XML or JSON documents out of the fetched data.
What you might rather ask yourself, is if you want to have a Rich- or a Thin-Client. Rich-Clients have more independent logic, can maybe cache the data, ...; while Thin-Clients only display data and forward every performed action to the server.
Actually I think you're mixing two different concepts which go well together but still, are different. The MVC pattern is a pattern for implementing user interfaces and is only used as an architectural pattern on very small project. On the other hand the layered architecture can be used server-side to implement a more complex application.
The two are often mixed because of the well-known 3-tier architecture (Presentation tier - Application tier - Data tier) on which analogy to the MVC pattern is easy (View = Presentation tier / Controller = Application tier / Model = Data tier) yet false.
About your problem specifically see zahorak's response about the thin/fat client choice you'll have to make.
I have been doing Java and Ruby (and used frameworks) for some while and I know MVC is a way to separate code. The thing is, I think I never really used it in the way it should.
The first question is: Business logic, what does it mean? Does Business logic mean the logic that is special for that application? Let say you are building a Satellite system. Is the business logic the code that is unique for that Satellite system and make it work?
What does "domain" mean? Like in domain logic or domain as a term.
"Keep your model smart, controllers thin and view dumb". This statement clearly indicates that the controllers which I load with too much code is the wrong way of writing it.
As an example. If you have a BankAccount class. Then should this class provide methods for behavior such as validating etc as well as getter/setter?
What should the controller be doing? Just redirecting input/events in the view to the model and maybe update view (which is the case in webframeworks).
For example in Java and JPA you have the entityManager that you use for finding entities, maybe do something on them etc. Should this entitymanager be used in the controller, or should you make another layer named e.g. "Service" which the controller uses. But again, does this server layer then belong to the Model in MVC? How would you do this in Rails?
I don't get the Model nor the Controller concept right I think.
Think of applications as being layered. When working on each layer, always think to yourself, "Is this layer dependent on the layer above it or can it work independently?" That is the basis to a good MVC application.
When thinking of layers in an MVC style application, there are a few.
In my mind the layers (from top to bottom) are the view, controllers, business logic, and data access.
The view could be JSP or even AJAX requests from jQuery. This is where the user interacts with your application. The view sends information to the business logic layer to do work.
Controllers should be written to collect data sent to it from the view, transform it in a way that the business logic can understand it, and then pass the information into the business logic layer. Controllers may also take information retured from the business logic layer, transform it, and send it back to the view. No real "business logic" should happen here. Think of it as a broker between the view and the business object layer. This is also a great spot for validating data submitted by the view.
Business logic is a layer you would find in the middle, typically between the controllers and data access layer. This could also be called a service layer. It should be written to not know anything about what is calling it. If written correctly, you could use this layer in a standalone application. Here is where a lot of the application smarts should take place. A lot of times, this layer is simply here to call the data access layer and return the results back to the controllers. But, a lot of other things could go on here like data manipulation, calculations, data security, validation, etc.
The data access layer should be written in such a way that it takes it's input, retrieves the appropriate data, transforms it into a useable form, and returns it. This layer should not know or care what is calling it and should be written in that way. Again, this layer should not know it is in a web application or a stand alone application. There are a lot of options here to make your life simpler in the form or ORM (Object Relational Mapping) frameworks. If your application is a step above trivial, you should think about using one.
In the traditional sense, the model could be the business logic layer and the data access layer as well as the domain objects that go along with them.
Using "BankAccount" as an example:
"BankAccount" sounds more like a domain object (representation of data in a database) than a class that has logic in it. Typically domain objects only have the fields they need (account number, balance, etc.) with getters and setters.
The user might log into their bank website. On login, the view sends the username to the controller (BankAccountController). The controller takes this information out of the request and sends it to the service layer (BankAccountService). The service layer would send this information to the data access layer which does a query for the BankAccounts that the user might have and return them to the service layer which returns them to the controller. The controller will manipulate this information in some way that the view layer can display them to the user. There would be a similar series of events when the user transfers money between accounts, for instance.
Hope this helps... let me know if you have any more questions or if something isn't clear.
Edit:
Besides the links posted by the other users, Wikipedia has a brief, but pretty good article on MVC.
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
In another question, someone told me to implement the following in my java program. But, I am very new to Java and I do not know how to start to convert my simple program into this structure:
Data Access Layer (read/write data)
Service Layer (isolated business logic)
Controller (Link between view and model)
Presentation (UI)
dependency injection.
program to the interface:
Does that come inside some framework? Should I start learning Spring and this structure will evolve naturally? Or, can I implement above technologies one by one without using a framework?
You can implement them without a framework if you wish, but you give up whatever benefits the framework offers you.
The layering you cite is correct and independent of any framework; it's just programming to interfaces and separation of concerns. You're free to do it without Spring if you wish to minimize the number of new technologies you want to learn right now.
If you don't know what persistence is, then you shouldn't jump into Spring. Persistence means storing data in relational databases using SQL to most people. If you don't know that, I'd recommend starting there.
All the patterns books in the world won't help you if you've never used the underlying technologies.
If you've never done any of this, I'd recommend sticking to straight JDBC, servlets, and JSPs using only JSTL (no scriptlets). Anything beyond that will just be confusing.
If you had a Foo model object, with persistence, service, and view tiers, the interfaces might look like this:
package model;
/**
* A model object that's interesting from your problem's point of view
*/
public class Foo
{
}
package persistence;
/**
* CRUD operations for a Foo
*/
public interface FooDao
{
Foo find(Long id);
List<Foo> find();
void saveOrUpdate(Foo foo);
void delete(Foo foo);
}
package service;
/**
* Just a data service that wraps FooDao for now, but other use cases would
* mean other methods. The service would also own the data connection and manage
* transactions.
*/
public interface FooService
{
Foo find(Long id);
List<Foo> find();
void saveOrUpdate(Foo foo);
void delete(Foo foo);
}
package view;
/**
* A class that owns services, validates and binds input from UI, and handles routing
* to the next view once service is complete.
*/
public interface FooController
{
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response);
}
These are just interfaces, of course. You'll need to provide implementations.
You might want to check out Domain Driven Design. The Code samples are in Java. The things you listed are design related more than any specific technology.
In short:
Data Access Layer is a module of your application that provides interface to your data. Data may be in SQL database, XML, file wherever. You write interfaces and classes that provide interface to access data usually as VO or DTO via DAOs
Service Layer contains most of the use-case logic. Service layer interacts with Data Access Layer to perform tasks in given use case. I did not find a good article on introductory service layer. You may see here and there
Controller is the one that interacts with Service Layer and/or Data Access Layer and/or other controllers in order to perform a specified client's tasks. For example, a sign-off button controller will request a sign-off action/service to invalidate user's sessions on all services that user is logged on to, then it will choose an appropriate view or log-off web-page to forward user to.
Presentation is your user interface. It can be a web-page made of HTML or Java Swing window or anything that user interacts with. GUI commonly known term for it. This is what your users will be interacting with using mouse clicks, scrolls, swipes, drag-and-drop. These actions are mapped with controller which performs action based on what user performed on UI.
Dependency Injection is a way to wire various components. There are a lot of resources on web. You can look in Martin Fowler's this article. It's basically a mechanism that allows components to behave much like plug-and-play devices, if you know what plug goes where.Spring is a good implementation of dependency injection. You may not want to write your own framework, and at this stage, you should rather not. There is a Spring MVC framework that can do things for you.
But I suggest you start from very basic. Instead of jumping on jargon, read from basic. Start with a good book on application development using Java. You can also look into
Design Patterns - Gang of Four
Core J2EE Patterns
Developing a Spring Framework MVC application step-by-step
dependency Injection with the Spring Framework
You can implement all of this is you want -- it's been done many times before, but nothing prevents you from doing it again.
What would be a better use of your time is to make sure you understand the separation of concerns you listed above (which are generally right) and identify the most efficient integration of existing frameworks to leverage (e.g., Hiberante, Spring, Guice, etc). There are multiple answers for that one (and no shortage of opinions!), but all things being equal, the less frameworks you have to integrate, the easier and better fitting it's likely to be.
Spring has a very well known framework which covers many of these things, so it would be wise to start there. It also allows you to work with other frameworks (i.e., you can use selective parts of Spring). For example, you can use Spring for dependency injection and use a different MVC framework.
It is very hard to answer this question. First of all, I don't know what your program looks like. Second, I don't think 'converting' it is something that can be done, or should be done for that matter. What you're talking about are architectural concepts that the developers usually have in mind while designign the application.
If these concepts interest you, I suggest reading a bit about Model-View-Controller pattern (MVC) and service-oriented Architecture (SOA).
These are general concepts that do not apply specifically to Java. However, they are widely used in Java enterprise development. Various frameworks allow you to create applications utilizing these concepts. For example, Spring Web MVC, as others have pointed out, is part of the Spring Framework that lets you create web applications that adhere to the MVC pattern.
If your program is really simple this separation might be done by using one calss for each
category.
Data Access Layer (read/write data) -> one class for presisting laoding
Service Layer (isolated business logic) -> one calss with bussiness logic
Controller (Link between view and model) -> in simple swing app this merges with UI
Presentation (UI) -> one class for one widnow
dependency injection -> not used in small apps
program to the interface -> Your service class should use interface tah is used by other class instead of directly your serivce implementation:
if it's not as simple program you might want to have package for each category.
BUT - don't overdesign! These concepts are ment to help you manage large scale applications, not to ruin you in your programming begginigs!
Being pretty unfamiliar with design patterns and architecture, I'm having trouble explaining to others exactly how my latest application is designed. I've switched between thinking it's a pure n-tier, pure MVC and n-tier with MVC in the presentation layer. Currently I think the latter is correct, but I want thoughts from more experienced developers.
How it works:
Browser sends HTTP request to Tomcat. Maps the request via web.xml to a servlet (which I call controller)
The controller instantiates one or more business object and calls methods on these, i.e. customerBO.getById(12) which again will perform business logic/validation before calling one or more DAO methods, i.e. customerDAO.getById(12). The BO returns a list of CustomerVO's to the controller
The controller prepares attributes for the view (JSP) (request.setAttribute("customers", customers);) and chooses a .jsp file to use which in turn will iterate the list and render XHTML back to the browser.
Structure (my proposal/understanding)
Presentation tier: currently using what I think is a MVC web-implementation: servlets (controllers), jsp (views) and my own implementation of OO XHTML forms (ie. CustomerForm) lies here. It should be possible to use a Swing/JavaFX/Flex GUI by switching out this presentation layer and without the need to change anything on the layers below.
Logic tier: Divided into two layers, with Business Objects (BO) on top. Responsible for business logic, but I haven't found much to put in here besides input validation since the application mostly consists of simple CRUD actions... In many cases the methods just call a method with the same name on the DAO layer.
DAO classes with CRUD methods, which again contacts the data tier below. Also has a convertToVO(ResultSet res) methods which perform ORM from the database and to (lists of) value objects. All methods take value objects as input, i.e. customerDAO->save(voter) and return the updated voter on success and null on failure.
Data tier: At the bottom data is stored in a database or as XML files. I have not "coded" anything here, except some MySQL stored procedures and triggers.
Questions (besides the one in the title):
The M in MVC. I'm not sure if I can call this n-tier MVC when the models are lists/VO's returned from business objects in the logic tier? Are the models required to reside within the presentation layer when the controller/view is here? And can the form templates in the presentation layer be called models? If so; are both the forms and lists from BO to be considered as the M in MVC?
From my understanding, in MVC the view is supposed to observe the model and update on change, but this isn't possible in a web-application where the view is a rendered XHTML page? This in turn leads me to the question: is MVC implemented differently for web-applications vs. regular desktop applications?
I'm not using a Front Controller pattern when all HTTP requests are explicitly mapped in web.xml right? To use Front Controller I need to forward all requests to a standard servlet/controller that in turn evalutes the request and calls another controller?
The Business Layer felt a little "useless" in my application. What do you normally put in this layer/objects? Should one always have a business layer? I know it should contain "business logic", but what is this exactly? I just perform input validation and instantiate one or more DAOs and calls the appropriate methods on them...
I realize there is MVC frameworks such as Struts for Java, but since this my first Java web-application I tried to get a deeper understanding of how things work. Looking in retrospect I hope you can answer some of the questions I stumbled upon.
I'm not sure if I can call this n-tier MVC when the models are lists/VO's returned from business objects in the logic tier
Those are perfectly good models. I also consider the ActionForms in Struts to be models. ActionForms are what Struts uses to represent/model HTML forms.
in MVC the view is supposed to observe the model and update on change, but this isn't possible in a web-application
Yep, and that is a matter of debate as to whether you can have true MVC with web-applications.
Should one always have a business layer?
It depends on the type of application. Some applications are database-driven, and are essentially a UI for the database. In that case, there's very little business logic required.
Data Tier:
The stored procedures aren't really part of the data tier code. You should be creating data access objects (DAOs) which are called by the business objects. The DAOs call the stored procedures. Further, the DAO interfaces should give no hint to the business objects as to where the data is stored, whether that be a database or file system or from some web service.
I think you are getting hung up in the terminology. The MVC pattern (I believe) pre-dates the classic web app arch you describe. It use to be that people called web app arch MVC 2 (Model 2 etc.) to differentiate it from the original MVC pattern...
see this link > http://www.javaranch.com/drive/servlet/#mvc2
HTH