Using methods of one DAO into another - java

I have 3 Service classes in my application each written for specific functionalities with respective DAO interfaces & their implementation classes.
All services have different packages.
Say I have
AService.java & ADAO.java ADAO interface is injected into AService.java class. Similarly I have
BService.java & BDAO.java
CService.java & CDAO.java
Now I want to refer some methods of BDAO & CDAO implementation classes in AService.java
What should be the best way to do that?
I inject BDAO & CDAO in AService.java. Would that be a good practice? Services are tightly coupled in this scenario.
I write the redundant code in respective DAOs.
I create a generic DAO & try to extract all the common methods from all the individual DAOs & put into that. This is an extensive task. Also I am not sure in future which method of which DAO will be required in which particular service.

I would go by the first option in this case. A service can be of a higher level of abstraction than the DAOs.
For sure i wouldn't go by the second approach, the third option could be valid if the common code is some utility code, i wouldn't do this if the common code is from different entities/logical domain.

If you share behaviour in the DAO layer you should do it with inheritance or composition(Association) inside the DAO layer.
You sliced your application by Domains like "A", "B", "C", so the AService should not by pass the BService to access any kind of B's logic implemented in the B-Domain.
See #oliver-gierke talk "Whoops! Where did my architecture go?". Because of this easy Bypassing he proposes to organize packages like this
public class com.product.a.AService
/*package*/ class com.product.a.ADao
public class com.product.b.BService
/*package*/ class com.product.b.BDao
public class com.product.c.CService
/*package*/ class com.product.c.CDao
With this you enforced that no other "Domain" is using the Daos of your Domain. Otherwise you can violate your Architecture rules.
The problem with sharing DAOs of different domains, is that you may bypass businesslogic implemented in the other domains service layer.
For example, with every "delete" operation on B a email should be send to a customer. In case the AService uses the BRepository directly, it grants access to delete a B instance and bypass the logic to send an email.

Related

Singleton on method with Context parameter

I code CRUD methods and wonder if it's useful to define my DAO class as singleton. While they have as a parameter the context of the activity that requires them.
I do not try to do it because I learned about the net. And I notice that the singleton is used in the classes that manage a database outside the activities
I wouldn't use a singleton. It's a recognised anti-pattern, and makes testing difficult. I would much rather inject in a concrete implementation, and have your service reference a DAO interface (allowing you to inject different implementations in)
Basically I have a database with each table linking to a DAO class and a class that defines my table. My DAO class when I instantiate it I have in parameter the context to activate it. This makes it possible not to have calls from everywhere. Do I still need to implement a singelton?

Java Naming Convention between different layer classes

How would you guys elegantly name/baptize these classes, assuming prefix/sulfix like I, Impl, Dao, etc, are bad conventions!
I know it is possible to find many topics about naming convensions, but they are more about it than suggesting on how to handle those cases.
The ideia is to decouple any possible implementation between layers/modules and let the container to handle injections.
model: Company
company service interface: ICompanyService
service implementation class: CompanyService implements ICompanyService
persistence interface: ICompanyDao
persistence implementation class: CompanyDao implements ICompanyDao
I can't get rid of "I" at interface names cause interface and implementations would be named as the same (I know it is possible to use full name including package, but it is even uglier). Same case for CompanyDao. Also the same issue when DAO sulfix is removed because of model class name.

Spring DAO class method - protected vs public?

In my Java Spring application I have a DAO class with methods. I would like to know which access modifier use: protected or public?
In which situation we should use protected modifier? I don't know when I should use a protected modifier, so I always use public. Is it proper way?
DAO layer is mostly used for database transactions. For eg: saving, updating, fetching, etc.
Now they don't have any business logic in them, because we put the business logic in the Service layer. Usually this Service layer makes a call to the DAO layer whenever it needs to perform a database related work.
Therefore, public should be used in most cases (as they are getting called from a different layer/package) all together.
Protected is good when you are sure that you will make call only from the same package(or sub classes), which may not always be the case. So no, protected is not recommended.
Protected doesn't really make sense for DAOs, since you need the methods in other packages, in classes which don't implement the DAO. Therefore public is almost always the way to go.
For DAO classes, you should make an interface with Dao methods declared(Which will obviously be public). Your DAO classes should extend the interface. In this way your Dao methods will be accessed from other classes via the interface reference.
It's the better way, because it will be easy to test. You can provide a mock implementation of the DAO interface to test your code. You can do this before you write your actual DAO class. If you are calling DAO methods with interface reference variable, then you can change your DAO class and it will still work because you are changing the class not the interface whose reference you are using for calling the methods(renaming class name for an example).
It's the important design principle that you should always code for interface wherever possible. I recommend you to see this answer to read about why you should code for interfaces in DAO.
You should use protected modifier in case of inheritance. When you want outside the package only child classes should be able to access the methods and properties of your class. when you need to do somethings that should not exposed in public API but still needs to be overriden by subclasses for example template method pattern.

Multiple Inheritance in Java - Spring Data

I want to create a DAO class named BaseDAO that should have the JPA and JDBC capabilities in Spring. I mean, I want to extend JPADAOSupport and JDBCDAOSupport classes of spring in to my BaseDAO class. I am aware that multiple inheritance is not an option in Java.
I have created two separate Base classes like BaseJPADao and BaseJdbcDao extending the respective classes. Is it possible to have a single class to extend both? Is there any design pattern solving this issue. Please advise.
Why don't you have a DaoGateway bean having injected the actual JPA DAO and the JDBC DAO beans.
This gateway can then decide which DAO to delegate a given request (to JPA or to JDBC).
You should always favour composition vs inheritance when reusing functionalities.
no it is not. if it was possible, you would still have the same result as in
one class extending JPADAOSupport and JDBCDAOSupport, which you yourself say you know is not possible because multiple inheritance is impossible.
you can write to an interface, and provide two implementations, though.
This would be easy to do with delegation if they both had interface level access you want:
public class MyUberClass implements WhateverJPADAOSupportDoes, WhateverJDBCDAOSupportDoes {
private JPADAOSuport jpa;
private JDBCDAOSupport jdbc;
// now implement all methods specified by the interfaces on the class signature and delegate to their respective member
}
But it seems you want access to all of their public methods. As there is no interface for both you can do the same as above but it can't be of both types simultaneously. The language expressly denies you this.
Your only other option is to create an adapter interface that your code can rely on and then use the combination delegation. If you're hoping to have one class that you can just drop in as a substitution for both then the answer is you can't.

Avoiding tight coupling between Service classes

Say I have 2 service classes:
UserService
ProductService
Is it wrong if within my ProductService class I inject the UserService?
public class ProductserviceImpl implements ProductService {
#Autowired
UserService userService;
#Override
public void someThing() {
..
userService.otherThing(..);
..
}
}
I know as an alternative I could create yet another class that injects both UserService and ProductService, but coming up with a name for this class is very tricky :) Is there a name for these types of classes in the SOA world?
1) Is it wrong if within my ProductService class I inject the UserService?
There is nothing wrong with this per se, with the following caveats:
Be aware that you could be potentially heading in the direction of one class doing too much (here, the ProductService)
Be careful that you don’t introduce cyclic dependencies (you should not have UserService also depend on ProductService)
Limit tight coupling by wiring your dependency to the interface rather than the concrete class (here you are autowiring UserService instead of UserServiceImpl, which is good)
2) Is there a name for this type of class (that injects both UserService and ProductService) ?
Yes, as was mentioned, you could call this class a Mediator since the Mediator Pattern seems to describe this.
You can have both low-level services and high-level services, with the low-level ones (ProductService, UserService) injected into the high-level ones (say, PurchaseOrderService or PurchaseOrderMediator). Alternatively, for this particular case you might think of the product service as being a single high-level service that depends on UserService. At that point it’s more about which construct is more cohesive in the context of your business logic and your application.
For me, there's no problem to inject a service into another one. That's the point with services and SOA as you said.
Services can help each others in order to give you the final result. Besides, as told JB Nizet, if there is no cyclic dependencies, no problem.
What you are describing is called Mediator Pattern.
Btw what is SOA?
Injecting one service into another using spring like you have mentioned will couple, the 2 services only to the extent of the interface used.
If you need more decoupling, think of using a message to pass between the 2 services.
Message can be strongly typed like a value object/xml with schema
or weakly typed like a HashMap
While weakly typed messages can increase the decoupling, it means you and your client will forfeit compile time checking and debugging issues will be cumbersome at runtime
What you describe is object oriented integration and most likely not a SOA one. The fact that you may get (and should avoid) cyclic dependencies demonstrate that.
If you're services know other service Java level Interfaces you are also in a big risk to introduce tight coupling.
For instance, what's the return type from the User service? is it yet another interface that belong to the User service? do you pass it around in the code of product service?

Categories