Should #Service classes have the same interface as #Controller classes? - java

We are a small team starting a new project, and developing the back-end using Spring-Boot framework.
The back-end project will have the following standard layers of a Spring-Boot application:
Controller (map the endpoints and handle)
Service (to handle business logic)
Repository (to abstract and interact with the database)
We also have an entity package where all the classes representing database entities are located.
We also use a library to map entities with Api models.
It did not last long and our first debate within the team occurred. So I thought it's a good idea to ask for advice out there.
My other partners think that the controllers should contain as few lines of code as possible.
Ideally containing only one line of code, where the respective Service is called, and the rest is handled in the Service.
I am against that approach, because if we would do that, the Service and the Controller would end up having the same interface, which feels wrong.
However, I agree with the principle that the controllers should have as few lines of code as possible.
I think that the controllers methods should accept and return only Api models, and no concept of entities should be present in the controllers.
At the same time, I think that the services method should accept and return entities, and not work with ApiModels.
Should we introduce a new layer between Controller and Service? Is there some standard, for which I am not aware, related to this topic?
I am going to give you a concrete example with two approaches (mine and my partners'):
First approach:
public class UserController implements UsersApi {
#Autowired
private UserService userService;
#Override
public ResponseEntity<UserAPIModel> createUser(#Valid UserAPIModel body) {
User createdUser = userService.save(UserMapper.INSTANCE.toUserEntity(body));
return ResponseEntity.ok(UserMapper.INSTANCE.toUserAPIModel(createdUser));
}
}
And the service:
public class UserService {
#Autowired
private UserRepository repository;
public User save(User entity) {
return repository.save(entity);
}
}
The second approach:
public class UserController implements UsersApi {
#Autowired
private UserService userService;
#Override
public ResponseEntity<UserAPIModel> createUser(#Valid UserAPIModel body) {
return ResponseEntity.ok(userService.createUser(body));
}
}
and the service:
public class UserService {
#Autowired
private UserRepository repository;
public UserAPIModel createUser(UserAPIModel body) {
User user = repository.save(UserMapper.INSTANCE.toUserEntity(body));
return UserMapper.INSTANCE.toUserAPIModel(user);
}
}
As you can see in the first approach, the mapping from entity to Api Model and vice versa is done in the Controller. In the second approach this mapping is done in the Service.
Which one would you recommend? Or do you think it's better to introduce a new layer between Controller and Service?
Making a decision on this simple example, can help us to create a more general rule and set a standard for similar problems in the future.

First of all, your question is very broad, which incorporates many questions in one post, which you should not be doing on this site. In the future, try to have more focused questions instead.
TL;DR:
#Controller is a Web-Layer, i.e. layer responsible to handle HTTP Request-Response responsibility, where your Java code should semantically talk web, i.e. responsibility of your controller should be to accept the HTTP Request, and respond with HTTP Response. Whether or not you do some logic in between, should not be much a pure responsibility of controller, it should stand on the shoulders of its dependencies (#Service, in most cases).
#Service is a Business-Layer, i.e. layer responsible to process business-related tasks, where all the major business-logic, transactions, file processing, batch processing or etc. may be taking place.
You can mix-and-match these two, but it's not a good idea. Rather follow a clear separation of concerns pattern, where #Controller will be responsible for web layer, and #Service - for business logic.
Your points:
My other partners think that the controllers should contain as few lines of code as possible
Not necessarily, it depends. Controller might do some work, depending what is the given circumstance and there is no controller-specific Clean Code practice. Clean Code instructs you, that generally, your methods should not be too long and messy (there is a funny rule, that no method should go longer than a height of your 5 fingers, when laid horizontally), but again, this is very generic and debatable rule;
Ideally containing only one line of code
Do not follow this as a rule. This is rarely real, unless your controller does nothing except calling some service API (like return findAll(););
where the respective Service is called, and the rest is handled in the Service
You partner is right, if he/she means, that business-related (that is transactional, DB accessor, Batch, or any other type of process, that is OUT OF the web-layer responsibility) should better be handled in a Service layer;
#Service components are oriented to be acting as
Business Service Facade;
I am against that approach, because if we would do that, the Service and the Controller would end up having the same interface, which feels wrong.
No, they will not. #Controller does not need any Java Interface, in the classical sense of this phrase (e.g. public interface Foo{..}), it's a Spring managed component, and you don't inject its implementations, which is not the case when we're talking about #Service components;
However, I agree with the principle that the controllers should have as few lines of code as possible.
Don't conceptualize this on controller. Method, generally, should be as clear as possible, and there is nothing wrong if controller is a bit long.. it's not about controller, as such, it's about your methods' design, whether or not you can extract/abstract something out and make your code cleaner. However, apply YAGNI principle when possible and don't rush with premature optimization with respect of the controller's code lines. Don't go too long.. but don't bother yourself much here on counting lines;
I think that the controllers methods should accept and return only API models, and no concept of entities should be present in the controllers.
Wrong. #Controller's responsibility is not directly bound to the API model, it's responsibility is to accept HTTP Message, do something with it (either with the help of #Service, UtilityClass, or etc.) and respond back with HTTP Response. In some cases, you can make your controller be dependent on Data Access layer directly, but again - it depends.
Whether you'll have accepting models or not, it also very much depends and you can see my other answer explaining whether you should use DTO or not;
Should we introduce a new layer between Controller and Service?
NO, unless it's necessary. Controller should be the first layer where your request ends up; it should usually rely on Service, and Service, eventually, will rely on Data Persistence layer (Spring Data, JDBC, Integrations, or any other thing).

Ho guys!
I too started working on Springboot a few months ago, I can tell you that from personal experience it is better to create a Mapper between Controller and Service in order to proceed better. Generally, especially in this type of projects, it is imperative to diversify and not to make the Controller or the Service do tasks outside of their use. The controller in this case you only need to start a command, there shouldn't be any kind of direct connections to Repo either. from experience I tell you that in larger projects this mentality pays off

Related

Spring entities and business logic?

I am developing a spring application, where I have three layers as most of other spring apps. The Rest Controllers on front, Services in middle, and JPA repositories in behind. Now we have spring entities mapped to the db, in my case they are plain old java objects(POJO), with only some fields and getters and setters which I usually prefer and don't want to put any business logic in there. However, in this project, I find out that in a lot of services I am repeating the same piece of code, something like that
User user=userRepository.findUserByName("some name here");
if(user==null){
throw new UserNotFoundException("User not found");
}
Now, this is not only for a single entity, there are many other similar repeated parts too. So, I have started to worry about it and looking possible areas to push that code and eliminate the repeated parts. One thing makes sens as stated in domain driven design, put that business logic inside the entity, now they will have both data and part of business logic. Is that a common practice?
Pretty much looks like a simple code reuse problem. If you are always throwing the same exception in all contexts then what about implementing a findExistingUserByName method on the repository that throws if the user doesn't exist?
Your code would become:
User user = userRepository.findExistingUserByName("username");
If you do not want to change the repository contract you could also implement a UserFinderService at the application level which wraps over a UserRepository and provides that service-level behavior.
Another more generic idea could be to implement a generic method and make it available to your application services either by inheritance, composition or a static class which would allow you to do something like:
withExistingAggregate<User>(userRepository.findUserByName("username"), (User user) -> ...)
You cat return Optional<User> from repository in this and similar cases.
Then you service code will look like:
userRepository.findUserByName("some name here")
.ifPresent(user -> doThmsWithUser(user));

MVC practices. Service within another service

Service1 injects Repository1. Service2 injects Repository2.
Suppose two different scenarios:
1)
Some method of Service2 needs to retrieve data from Repository1.
Should Service2 inject Service1 or Repository1 when both of them provide respective get() method?
2) Some method of Service1 at it's end should call another method from Service2. Is it a bad practice to inject Service2 to Service1 for such needs? Is it a good practice to use event listen techniques like AOP for such needs?
There are many factors to consider here when we talked about best practices.
As a good start, try to understand the concept of SOLID principles.
Generally, it is good to have multiple classes with very focused roles that calls the other rather than combining all functionalities in one class. High reusability and least code duplication which in turn gives maintainability.
For scenario 1.)
It is perfectly fine to have a service calling another service if that business code defined in the method is the same business functionality needed by the other service. This follows the DRY principle, no redundant codes.
But it is also perfectly fine to just directly call the Dao from a service instead of calling a different service to do that for you if it is just a simple call with no further business logic. Especially if the two services are in the same module anyway, there is no strong reason to make another service a bridge class for an obvious simple single line of code unless you want to abstract it, but in your case, its just a simple get call.
For scenario 2.)
But another thing to consider is modularity and direction of dependency. If each service calls each other, there could be problem in your design, as much as possible avoid circular dependency on different modules because this could lead to spaghetti code, better to extract same code to a different class declared on common module that can be shared by many modules.
Final note, as what Robert Martin says, you won't be able to code at once the cleanest code in one round. Best codes are forged by continuous refactoring and code cleanup. To quote Robert Martin,
The Boy Scouts have a rule: "Always leave the campground cleaner than you found it."
I am not greatly experienced with this problem, but personally I would avoid coupling controllers. My first approach would be trying to create an interface that would fit all models if possible. It would then be possible to create a model that wires multiple models together to access the data you need without adding references to the controller. For instance:
Model1 implements iModel{}
Model2 implements iModel{}
ModelWrapper implements iModel{
private iModel model1;
private iModel model2;
public ModelWrapper(iModel model1, iModel model2)
{
this.model1 = model1;
this.model2 = model2;
}
public SomeDataType getSomeValue(){
SomeObject.param1 = model1.method();
SomeObject.param2 = model2.method();
return SomeObject;
}
}
I am sure there is a better way to approach the number of models passed into the constructor and also a way to search each model for the data you are looking for. If the data is not found a null reference or better a custom error could be thrown. If the implementation is consistent perhaps the wrapper could combine all models and allow access to many custom combinations. At least this way, when requirements change you can simply add an additional wrapper to get what you need without changing the current implementation.
Perhaps a more experienced developer will build on my response to provide you a better implementation, but I hope this helps.

Advice wanted on a complex structure in java (DAO and Service Layer linking/coupling)

Introduction
I am trying to make a rather complex structure in Java with interfaces, abstract classes and generics. Having no experience with generics and only average experience with creating good OOP designs, this is beginning to prove quite a challenge.
I have some feeling that what I'm trying to do cannot actually be done, but that I could come close enough to it. I'll try to explain it as brief as I can. I'm just going to tell straight away that this structure will represent my DAO and service layers to access the database. Making this question more abstract would only make it more difficult.
My DAO layer is completely fine as it is. There is a generic DAO interface and for each entity, there is a DAO interface that extends the generic one and fills in the generic types. Then there's an abstract class that is extended by each DAO implementation, which in turn implement the corresponding interface. Confusing read for most probably, so here's the diagram showing the DAO for Products as an example:
Now for the service classes, I had a similar construction in mind. Most of the methods in a service class map to the DAO methods anyway. If you replace every "DAO" in the diagram above with "Service", you get the basis for my service layer. But there is one thing that I want to do, based on the following idea I have:
Every service class for an entity will at least access one DAO object, namely the DAO of the entity that it is designed for.
Which is...
The question/problem
If I could make a proper OO design to make each service class have one instance variable for the DAO object of their respective entity my service layer would be perfect, in my view. Advice on this is welcome, in case my design is not so good as it seemed.
I have implemented it like this:
Class AbstractService
public abstract class AbstractService<EntityDAO> {
EntityDAO entityDAO;
public AbstractService() {
entityDAO = makeEntityDAO(); //compiler/IDE warning: overridable method call in constructor
}
abstract EntityDAO makeEntityDAO();
}
Class ProductServiceImpl
public class ProductServiceImpl extends AbstractService<ProductDAOImpl> {
public ProductServiceImpl() {
super();
}
#Override
ProductDAOImpl makeEntityDAO() {
return new ProductDAOImpl();
}
}
The problem with this design is a compiler warning I don't like: it has an overridable method call in the constructor (see the comment). Now it is designed to be overridable, in fact I enforce it to make sure that each service class has a reference to the corresponding DAO. Is this the best thing I can do?
I have done my absolute best to include everything you might need and only what you need for this question. All I have to say now is, comments are welcome and extensive answers even more, thanks for taking your time to read.
Additional resources on StackOverflow
Understanding Service and DAO layers
DAO and Service layers (JPA/Hibernate + Spring)
Just a little note first: usually in an application organized in layers like Presentation / Service / DAO for example, you have the following rules:
Each layer knows only the layer immediately below.
It knows it only by it's interfaces, and not by it's implementation class.
This will provide easier testing, a better code encapsulation, and a sharper definition of the different layers (through interfaces that are easily identified as public API)
That said, there is a very common way to handle that kind of situation in a way that allow the most flexibility: dependency injection. And Spring is the industry standard implementation of dependency injection (and of a lot of other things)
The idea (in short) is that your service will know that it needs a IEntityDAO, and that someone will inject in it and implementation of the interface before actually using the service. That someone is called an IOC container (Inversion of Control container). It can be Spring, and what it does is usually described by an application configuration file and will be done at application startup.
Important Note: The concept is brilliant and powerful but dead simple stupid. You can also use the Inversion of Control architectural pattern without a framework with a very simple implementation consisting in a large static method "assembling" your application parts. But in an industrial context it's better to have a framework which will allow to inject other things like database connection, web service stub clients, JMS queues, etc...
Benefits:
Your have an easy time mocking and testing, as the only thing a class depends on is interfaces
You have a single file of a small set of XML files that describe the whole structure of your application, which is really handy when your application grows.
It's a very widely adopted standard and well - known by many java developers.
Sample java code:
public abstract class AbstractService<IEntityDAO> {
private IEntityDAO entityDAO; // you don't know the concrete implementation, maybe it's a mock for testing purpose
public AbstractService() {
}
protected EntityDAO getEntityDAO() { // only subclasses need this method
}
public void setEntityDAO(IEntityDAO dao) { // IOC container will call this method
this.entityDAO = dao;
}
}
And in spring configuration file, you will have something like that:
<bean id="ProductDAO" class="com.company.dao.ProductDAO" />
[...]
<bean id="ProductService" class="com.company.service.ProductService">
<property name="entityDAO" ref="ProductDAO"/>
</bean>

On properly implementing complex service layers

I have the following situation:
Three concrete service classes implement a service interface: one is for persistence, the other deals with notifications, the third deals with adding points to specific actions (gamification). The interface has roughly the following structure:
public interface IPhotoService {
void upload();
Photo get(Long id);
void like(Long id);
//etc...
}
I did not want to mix the three types of logic into one service (or even worse, in the controller class) because I want to be able to change them (or shut them) without any problems. The problem comes when I have to inject a concrete service into the controller to use. Usually, I create a fourth class, named roughly ApplicationNamePhotoService, which implements the same interface, and works as a wrapper (mediator) between the other three services, which gets input from the controller, and calls each service correspondingly. It is a working approach, though one, which creates a lot of boilerplate code.
Is this the right approach? Currently, I am not aware of a better one, although I will highly appreciate to know if it is possible to declare the execution sequence declaratively (in the context) and to inject the controller with and on-the fly generated wrapper instance.
Also, it would be nice to cache some stuff between the three services. For example, all are using DAOs, i.e. making sometimes the same calls to the DB over and over again. If all the logic were into one place that could have been avoided, but now... I know that it is possible to enable some request or session based caching. Can you suggest me some example code? BTW, I am using Hibernate for the persistence part. Is there already some caching provided (probably, if they reside in the same transaction or something - with that one I am totally lost)
The service layer should consist of classes with methods that are units of work with actions that belong in the same transaction. It sounds like you are mixing service classes when they could be in the same class and method. You can inject service classes into one another when required too, rather than create another "mediator".
It is perfectly acceptable to "mix the three types of logic", in fact it is preferable if they form an expected use case/unit of work
Cache-ing I would look to use eh cache which is, I believe, well integrated with hibernate.

How to learn "separation of concern" in java

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!

Categories

Resources