I'm currently working on an application where I can see the following:
Controller A : service.getSession(userId, Status.Started);
Controller B: service.getSession(userId, Status.Done);
(where Status represent an enum of possible statuses)
Service: getSession(Long id, Status status);
I find it not right, as users who are going to access controller A have certain roles and users accessing B others and there should be 2 services methods:
getSessionReady(Long id);
getSessionClosed(Long id);
Doing so I can clearly use Spring security and make sure that the right role access the right service methods. It makes me create two methods but it makes easier to secure the app and the goal of the service layer is to actually restrict access to limit logic errors right?
Yes. The more generic you make the service layer (or any class, in fact), the less value it adds.
You want your service layer to restrict access and make sure only valid calls make it into the domain.
Also, more methods is not a bad thing! As long as they make sense, feel free. Usually a method with an extra parameter that triggers different behaviour is a code smell, and should be split up.
Related
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));
currently I'm learning the SpringMVC + Hibernate. And I'm confused while implementing a simple user account manager application.
In my case:
the user account should be read from the database;
the password should be compared before any modification;
the user account information should be modified according to the frontend form;
the user account with new information should be save back to the database;
My questions are:
Should this whole process be implemented in the Service or in the Controller? And why?
In many examples I read that the service methods are usually tiny and contains only one DAO call, is this a good practice? Or we do the contrast to put several DAO calls into one service methods?
Should this whole process be implemented in the Service or in the Controller? And why?
Business logic is done in the service layer (the M in MVC) - see the link below for explanations.
In many examples I read that the service methods are usually tiny and contains only one DAO call, is this a good practice? Or we do the contrast to put several DAO calls into one service methods?
Service methods are of the proper size for the logic they perform. If for a particular logic you need access to several DAOs, or other services for that fact, you do so. If the logic is 10 lines of code or 100 then that's the size of the method. The thing is that most examples out there use a service layer (which your application should have) but because they are just that, examples, there isn't any logic in them. For this reason most of them just delegate to some DAO, confusing people about what their purpose should be.
Read the following for details: The Purpose of a Service Layer and ASP.NET MVC 2 (it's for .NET but the principles still apply).
I'm learning AOP and am comfortable with Pointcuts, Advices etc.
What am going to ask, am pretty sure is not possible, but want to ask anyways.
I have a method which takes a userId, fetches the user's record from a database and then does something to the record. I have like twenty different methods that do different things, but all of them take the userId as input and fetch the record from database. This to me looks like a cross cutting concern that can be pulled into an aspect.
But how? I know I can access the arguments (userId in this case), access the return value of the method and catch the methods exception. But how do I give the method something to work with (record in the database in this case?)
public String printUserDetails(String userId)
{
Record record = Database.fetchRecord(userId);
System.out.println(record.getDetails());
return record.getTitle();
}
So, is there a way to pull that database accessing code into an aspect?
One way I can think of is declare something like the following for input
class RequestObject
{
String userId;
Record record;
}
and inject the record in the Aspect and then call proceed(). But this somehow feels wrong.
IMO, resolving a user, using the userid, is not a cross-cutting concern and hence aspect is not the right way. The first landing page that receives a userId should actually resolve it to UserRecord and from then on, the userRecord should be the one moving around in the application.
A simple analogy I can draw to your scenario from one of my applications is, all authenticated servlets expect the servletRequest.getRemoteUser() to return the valid user login corresponding to the user sending the request. We decorated the HttpServletRequest to resolve this to a User object in our application and all the authenticated servlets downcast the HttpServletRequest to AuthenticatedServletRequest and extract this object. No one else within the application tries to resolve a user login anymore.
You cannot access a method's local variables from AspectJ if this is what you wanted to know.
The rest of the question is rather about design and the answer dependent on what you want to achieve. You can avoid code duplication in multiple methods using a template method design pattern. You can inject real or mock objects into classes if you refactor them to have a member instead of local variables. It is another question if you create the member by directly refactoring your classes or via AspectJ's (ITD)[http://www.eclipse.org/aspectj/doc/next/progguide/starting-aspectj.html#inter-type-declarations] mechanism. A third question would be if you possibly want to use an aspect for caching in order to avoid fetching the same object from the database multiple times.
I am not sure what exactly you want to achieve, so I cannot answer more specifically.
Background:
I have a design pattern problem that I was hoping someone may be able to solve. I program in PHP but I believe DAO/VO is popular in Java.
I have been using MVC for many years now. I designed a shopping that was MVC but used procedural programming. Thus recently I decided to develop the cart again, using OO.
Problem:
The problem I was faced with was that my Product class did not make sense to have a RetrieveAll() method.
E.g. If I had 10 products listed, from which instance would I call the RetrieveAll() method? I would have 10 choices.
Solution:
Thus, I found the DAO/VO pattern.
Unless I have not researched this pattern enough - I believe that each DB table must have a Model + DAO. No model or DAO should know about another set of models or DAO's. Thus being encapsulated.
The pattern makes perfect sense, pulling the database layer away from the Model.
However. In the shopping cart, my products are assigned categories.
A category could be electronics, clothing, etc.
There are 3 tables:
- Category (pid, name)
- Category Item (iid, name)
- Category Link (pid, iid)
From an MVC approach, it doesn't make sense of which DAO the controller should be talking to?
Should it be:
The controller talks to all 3 DAO's and then return the appropriate data structure to the View?
Or should the DAO's talk to one-another (somehow) and return a single structure back to the Controller?
Please see here for example (image)
I'm not sure what do you mean by VO. Is it value object?
I'm a huge fan of the DDD (domain driven design) approach (though I don't consider my self as guru in it). In DDD you have so called Services. Service Is an action that operates on your domain and returns data. Service encapsulates the manipulation with you Domain data.
Instead of having the controller to do all the domain logic like what items to retrieve, what DAO's to use and etc (why controller should care about the Domain anyway?), it should be encapsulated inside the Domain it self, in DDD case inside a Service.
So for example you want to retrieve all the Category items of the category "electronics".
You could write a controller that looks like this (forgive me if the code have invalid syntax, its for the sake of example):
public function showItemsByCategoryAction($categoryName) {
$categoryId = $categoryDAO->findByName($categoryName);
if(is_null($categoryId)) {
//#TODO error
}
$itemIds = $categoryLinkDAO->getItemsByCategoryId($categoryId);
if(empty($itemIds)) {
//#TODO show error to the user
}
$items = $categoryItemDAO->findManyItems($itemIds);
//#TODO parse, assign to view etc
}
This introduces at least two problems:
The controller is FSUC (Fat stupid ugly controller)
The code is not reusable. If you would like to add another presentation layer (like API for developers, mobile version of the website or etc), you would have to copy-paste the same code (expect the part of the view rendering), and eventually you will come to something that will encapsulate this code, and this is what Services are for.
With the Services layer the same controller could look like
public function showItemsByCategoryAction($categoryName) {
$service = new Item_CategoryName_Finder_Service();
$items = $service->find($categoryName);
if(empty($items)){
//#TODO show empty page result, redirect or whatever
}
$this->getView()->bind('items', $items);
}
The controller is now clean, small, and all the Domain logic is encapsulated inside a service that can be reused anywhere in the code.
Now some people believe that the controller should know nothing about DAOs and communicate with the Domain only by using Services, other says that its ok to make calls to DAOs from the controller, there are no strict rules, decide what suits better for you.
I hope this helps you!
Good luck :)
I'm not an expert in DDD either , but this is my opinion. This is the situation where the repository patern is applied. Basically, the Domain doesn't know nor care about DAO or anything else rpesistence related. At most knows about the repository inteface (which should be implemented at the infrastructure level).
The controller knows about the domain and the repository. The repository encapsulates everything db related, the application knows only about the repository itself (in fact the interface as the actual implementation should be injected). Then within the repository you have DAOs however you see fit. The repository receives and sends back only application/domain objects, nothing related to db acess implementation.
In a nutshell, anything db related is part and it's an implementation detail of the repository.
return type can be considered when deciding which dao method should go to which dao class, hence which dao should the controller talk to:
Implement one DAO class per Data Entity is more cleaner,
CRUD operations should go in to Dao classes,
C-Create, R-Read, U-Update, D-Delete
Read operations are not like Create, Update, Delete, most of the time Read operations have different flavors when considering what they return.
for Read operations, return type can be considered when deciding which dao method should go to which dao class
following are some Business Entities and there Dao
Exchange -> ExchangeDao
Company -> CompanyDao
Stock -> StockDao
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.