MVC practices. Service within another service - java

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.

Related

Reuse a request DTO in other services or decouple it by an identical copy?

Let's say there is a simple REST controller in a Spring Boot application. This controller receives a CalculationDetails object which is commonly referred to as a request DTO.
#PostMapping
public CalculationResponse calculateAverage(#RequestBody CalculationDetails details) {
return calculationService.calculateAverage(details);
}
public record CalculationDetails(#JsonProperty("value_1") BigDecimal bd1,
#JsonProperty("value_2") BigDecimal bd2,
#JsonProperty("sourceList") List<CalculationSource> sources) {}
Now, the CalculationDetails class is also used in other service methods and mapper classes which use the same data structure, but these services don't represent the same "feature".
I'm asking myself which of these approaches would make more sense:
Move the CalculationDetails class to a "common" package and reuse it as is in other services.
Keep the CalculationDetails class specific to this controller/service invocation and create a copy altough the copy would look identically (at least for now).
Approach 2 would surely pay in to decoupling but that would come with the cost of duplication. Approach 1 would allow me to reuse existing code; however, it would create a tighter coupling?
I would say, go for the first approach. Let's say you add 10 more features which need the same DTO with the same structure. Then you need to duplicate the same code 10 more times. In my eyes it's some sort of technical debt and increases the maintenance cost (in case you change the structure of the DTO).

pitfalls in builder inside singleton method controller?

Lets say I have controller RequestController in Spring which is marked as Singleton. Inside this controller there is a builder which is injected using dependency injection. The main goal for this class is to receive requests and build responses.
#Singleton
class RequestController {
private ResponseBuilder responseBuilder;
private RequestController(ResponseBuilder responseBuilder){
this.responseBuilder=responseBuilder;
}
public Response getResponse(Request request) {
return responseBuilder.getRequest(request).build();
}
}
My question:
What kind of pitfalls does this code hide? What could go wrong when we try to use it in normal spring application. #Singleton is only an information that this class will be created only once per applications.
I know that builder should be thread-safe since it will be responsible for handling multiple requests. But is anything else dangerous here?
Before going into your question there's one thing to be mentioned. You have declared your class RequestController as Singleton with #Singleton. If your class is a singleton you should make sure it is immutable, so no state change after creation. So I assume it is a stateless class. So you don't need to have a private constructor, which looks rather messy. Instead you can use,
#Inject
private RequestController(ResponseBuilder responseBuilder){
this.responseBuilder=responseBuilder;
}
Please note that, if you maintain a a good design, ResponseBuilder class should be an inject-able one. And RequestController class should be called only by injection.
Back to your problem, I think you have almost no problem. We should be very careful about what our real problem is? rather than what patterns we could drag and drop into our code?
Making a Controller, a Singleton is pretty much fine. But I don't find any need to use Builder pattern to your ResponseBuilder (you can change the name also). If your classes are rather simple and have just limited number of operations (a sign of a good design), you would never need builder pattern for your lifetime. It's more like we try to tear the paper with an axe. Why don't you use bare hands?
We should only use Builder in situations where we have to make considerably large scope class for some reason. You can have a good example of the use of Builder pattern in Hamcrest. It's an assertion tool for Java testing developed by Google. They have used builder pattern for some classes just to make life easier for the programmer who uses that by providing multiple list of tasks out of a single object.
Thank for a reply...I have an idea what it can be wrong with this code...Of course I should use injection on ResponseBuilder. But classically builder pattern have a state so in stateless controller we're using statefull class provided by ResponseBuilder. So automatically builder if it's not thread safe it can cause concurrency problems (race condition). Whenever multiple threads try to get access to builder fields they can get different state (because builder is not thread safe). So when we try to make builder thread safe it will work but a new problem will arise. Since our builder become thread safe only one thread will be able to use it and this can lead us to bootleneck for requests (multiple requests/threads use our method but they will be blocked by builder which is thread safe). Gimme a shout if my thinking is good :)

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.

Shortcut methods

My original question was quite incorrect, I have classes (not POJO), which have shortcut methods for business logic classes, to give the consumer of my API the ability to use it like:
Connector connector = new ConnectorImpl();
Entity entity = new Entity(connector);
entity.createProperty("propertyName", propertyValue);
entity.close;
Instead of:
Connector connector = new ConnectorImpl();
Entity entity = new Entity();
connector.createEntityProperty(entity, "propertyName", propertyValue);
connector.closeEntity(entity);
Is it good practice to create such shortcut methods?
Old question
At the moment I am developing a small framework and have a pretty nice separation of the business logic in different classes (connectors, authentication tokens, etc.), but one thing is still bothers me. I have methods which manipulates with POJOs, like this:
public class BuisnessLogicImpl implements BusinessLogic{
public void closeEntity(Entity entity) {
// Business Logic
}
}
And POJO entities which also have a close method:
public class Entity {
public void close(){
businessLogic.closeEntity(this);
}
}
Is it good practice to provide two ways to do the same thing? Or better, just remove all "proxy" methods from POJOs for clarity sake?
You should remove the methods from the "POJOs"... They aren't really POJO's if you encapsulate functionality like this. The reason for this comes from SOA design principles which basically says you want loose coupling between the different layers of your application.
If you are familiar with Inversion of control containers, like Google_Guice or Spring Framework-- this separation is a requirement. For instance, let's say you have a CreditCard POJO and a CreditCardProcessor service, and a DebugCreditCardProcess service that doesn't actually charge the CC money (for testing).
#Inject
private CardProcessor processor;
...
CreditCard card = new CreditCard(...params...);
processor.process(card);
In my example, I am relying on an IoC container to provide me with a CardProcessor. Whether this is the debug one, or the real one... I don't really care and neither does the CreditCard object. The one that is provided is decided by your application configuration.
If you had coupling between the processor and credit card where I could say card.process(), you would always have to pass in the processor in the card constructor. CreditCards can be used for other things besides processing however. Perhaps you just want to load a CreditCard from the database and get the expiration date... It shouldn't need a processor to do this simple operation.
You may argue: "The credit card could get the processor from a static factory". While true, singletons are widely regarded as an anti-pattern requiring keeping a global state in your application.
Keeping your business logic separate from your data model is always a good thing to do to reduce the coupling required. Loose coupling makes testing easier, and it makes your code easier to read.
I do not see your case as "two methods", because the logic of the implementation is kept in bussinessLogic. It would be akin of asking if it is a good idea java.lang.System has both a method getProperties() and a getProperty(String), more than a different method is just a shortcut to the same method.
But, in general, no, it is not good practice. Mainly because:
a) if the way to do that thing changes in the future, you need to remember that you have to touch two implementations.
b) when reading your code, other programmers will wonder if there are two methods because they are different.
Also, it does not fit very well with assigning responsabilities to a specific class for a given task, which is one of the tenets of OOP.
Of course, all absolute rules may have a special case where some considerations (mainly performance) may suggest breaking the rule. Think if you win something by doing so and document it heavily.

Categories

Resources