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.
Related
I am currently going through a Spring Boot tutorial to build a Spring Data REST application.
The EmployeeRepository interface extends the Crud Repository interface. It is then used in a DatabaseLoader where we use its save, find, and delete methods that are inherited from EmployeeRepository.
My question is how can a class use an inherited method of an interface without defining it? I always thought that on implementation of an interface I must override all of its methods.
From the tutorial: "That is how we can write an empty interface and inherit already built save, find, and delete operations."
Spring data will create an implementation of that interface when the app is running and creating the necessatu beans and of course the persistance context and entity manager too
for that reason when you extends from CrudRepository you need to add the object class and the type of the id of your entity like arguments in order to create this specific object to be persisited in your database
Remember Spring Data JPA will help you with a jpa provider in this case hibernate in order to avoid EntityManagerFactory object and so on.
you can find more information about it here.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference
EmployeeRepository is an interface in your example, not an implementation, so it need not implement the methods. The actual implementation of the interfaces you are using is being provided by Spring Data.
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.
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.
I'm mostly speaking about Java and classical OOP. Say I'm using DAO pattern. So I create interfaces like CustomerDao, AccountDao and others. I would place then into org.example.dao package:
org.example.dao.CustomerDao
org.example.dao.AccountDao
...
This all seems good to me so far. Then I create implementations for these interfaces. Here rises my first question: How do I name them? One practice that I have seen is to use *Impl postfix like CustomerDaoImpl. Or perhaps the name should reflect the nature of the implementation, e.g. AccountDatabaseDao or DatabaseBasedAccountDao? Or may be the name should be left intact and then the package would describe the nature of these implementations? If you suggest one or another way, then where should those implementations be placed? A separate package (what naming logics?) or the same package?
There are two camps: functional and technical naming.
The one like:
org.example.customer
org.example.account
The other like:
org.example.dao
org.example.service
I personally like to have the interface and the implementations in one spot and make only the interface public and to package by functionality as the packages have a higher cohesion this way.
With growing size you can still split the packages in for example org.example.customer.dao, org.example.customer.service and org.example.customer.ui. (Technically this is the same as org.example.dao.customer.dao, org.example.service.customer and org.example.ui.customer as Java packages are not nested.)
For your example I'd start with:
org.example.customer.CustomerDao
org.example.customer.DatabaseCustomerDao (package private)
org.example.account.AccountDao
org.example.account.DatabaseAccountDao (package private)
To make the implementation package private you need a factory to create the instances. If you're using DI. The DI-framework implements the factory for you and you can inject the instances in the users classes that depend only on the interface contract.
There are some who do
src
org
companyname
dao
impl
and have in impl e.g.
import org.companyname.dao.UserDao;
public class MySQLUserDAO implements UserDao;
or
src
org
companyname
dao
import org.companyname.dao.UserDao;
public class UserDaoImpl implements UserDao;
The reason I like the first option is that you browse the impl folder to place the DAO implementation of the interface. It's neater.
I'm not sure there is an established best practice for this. Generally we use sub-packages depending on how we implemented.
For example: The interface may be com.company.product.dao.ExampleDAO, and (if we were using MyBATIS) the implementation would be in: com.company.product.dao.mybatis.ExampleDAOMyBatis
I don't know if that's the best way of doing it but I think consistency here is more important than doing it the 'best' way - i.e. whichever scheme you pick, make sure that you stick to it throughout your codebase.
This is all up to you.
Everything that you have listed are viable solutions to your problem, and you wouldn't be the first to do any of them.
That said, I prefer to keep the naming of the Class as the biggest descriptor:
public interface AccountDao {}
public class MySqlAccountDao implements AccountDao {}
I would place both in org.company.dao
Sometimes, I find some class names including Aware such as ApplicationContextAware and MessageSourceAware (spring). Does this Aware have any special meanings or is it a famous rule?
Those are not classes, are interfaces. The name is just a convention on Spring meaning that some special framework object is going to be injected to that class if it is managed by the framework.
Directly from the docs of ApplicationContextAware:
Interface to be implemented by any object that wishes to be notified of the ApplicationContext that it runs in.
In this case, the bean that implements this interface will get a reference to the ApplicationContext managing the application.
Appending adjectives like "aware" to the end is a naming scheme often used for Java interfaces. This can then be implemented by classes, and the resulting is code which is more fluent to read for human beings, like
class Broker implements ApplicationContextAware { /* ... */ }
where it's quite easy to see that this class is a broker for something, and it knows how to deal with application contexts. Besides that, the "Aware" suffix has no special meaning from the Java (compiler) perspective.
The interfaces you cite seem to be a Spring-specific convention for allowing objects to interact with the dependency injection container that created them. By implementing the interface, a class signals that it wants certain information from the container and at the same time provides a method through which to pass that information.
I'd see it simply as an attempt to find a generic name for an interface that offers such functionality, not necessarily a strong convention with a specific technical meaning.
The concept of aware interfaces:
If I want the reference of objects of spring classes like XmlBeanFactory,ApplicationContext... In 2 or more classes, then there are 3 possible ways are there.
creating 2 BeanFactories in two classes.
creating at one class and sharing to all required classes .
In the 1st case ,we are unnecessarely creating 2 BeanFactories.
In the 2nd case, classes are tightly coupled with each other.
If our class implements BeanFactoryAware interface and overrides the contractual method called public BeanFactory setBeanFactory(BeanFactory factory) then IOC container see that special interface and calls setBeanFactory method by setting BeanFactory reference to that.
In 3. case above two problems are not there.