Java design question - java

I want users to go through objectmanager for all persistence operation, instead of using UserDao directly, how can I make UserDao not visible to users. I am using spring to inject Implementation into UserDao.
public class ObjectManager {
public static UserDao USER_DAO;
#Inject
public void setUserDao(UserDao userDao) {
ObjectManager.USER_DAO = userDao;
}
}
public interface UserDao extends GenericDAO<User,Long>{
User findUserByUsername(String username);
}
what i am trying to achieve it that everyone follows one path to perform persistence operation, in my case it would be ObjectManager.USER_DAO.save(obj)..something like this instead of one developer doing userDao.save(obj)....the ObjectManger is purely for convenience. Any body can type objectManager. and the IDE will show a list of dao that are available

My advice: don't do this.
This would tightly couple your DAO classes to your central, static ObjectManager class for no obvious reason. This makes the code in your application hard to unit test, because static references like ObjectManager.USER_DAO.save(obj) can't be mocked. Also the application will be harder to maintain because any change to ObjectManager will hit nearly all your code (example future scenario: you want to move some DAO accessors out of the ObjectManager).
If you value testability and maintainability avoid global classes with static access.

It sounds like you want to add a layer between the persistence (DAO) layer and the service layer. I have a project where I do something similar, inserting a Repository layer.
When you have a layered application you can create a multi-module build and enforce dependencies between layers at build time. So the DAO layer is not on the compile-time classpath for the service layer.

You can make the Constructor private, Spring DI still will instantiate them using reflection.
Your users (programmers using your api/classes) can still instantiate classes if they use reflection too, however the normal use of "new MyClass()" will give you compile time errors. But the question remains, what do you want to achieve?

The normal way of achieving this is to change the UserDao scope to "package" level and let ObjectManager (assuming ObjectManager is part of the same package) act as a facade to it. Since UserDao is not accessible outside of the package no other client can instantiate it.
But since you are using Spring, I believe you can't do this. One work around I think of is to inject the UserDao with inner bean definition to ObjectManager. This way other code can't do a lookup using bean name or other cfg can't reference it.

Related

Why it's complex to get the applicationContext of a springboot application?

I am not a native English speaker...there maybe some errors in expression, please forgive me..
//import org.springframework.context.ApplicationContext;
//in a #Component class
#Autowired
private static ApplicationContext context
I hope that the above code can work, the field variable context can get the applicationcontext of the springboot application.. but actually it doesn't work.
I have searched for some means to realize this aim, but I think them complex, for example ,implementing ApplicationContextAware...
Please think of factory pattern. Some of the instances which the factory class may return have field variable which need #Autowired, so they have to be managed by Spring, and the factory has to return applicationContext.getBean(...), can't use return new ... or return Class.forName(...)....
I think the factory pattern should be used widely, which I want use to prove that it is meaningful to get the the instance of ApplicationContext of a spring-boot application simply just like the top code...And why it's still complex now?
Thanks.
You can think of Spring as a factory that can create objects for you. These objects are called 'Beans' in spring world.
So, usually the beans do not have an access to the factory that has created them.
For example, think about the factory that produces "cars" like Toyota of Ford.
In terms of OOP, you can "buy" or "drive" the car (an instance of the class Car), but that factory creates these instance (does new Car). Since the actual car is managed by spring, its a bean. Now if you describe the car as a class in Java, its not reasonable to have something like this, right?
#Component
public class Car {
...
private CarFactory carFactory;
}
So Spring already "hides" the factory for you and you have a class Car "clean" of the boilerplate.
Now, as for the application context itself. It is actually that factory - and as our colleagues have already stated, you shouldn't really use the application context reference in your beans.
If you really need it, you can inject the application context but then it should not be static, and in general its better to access it from the #Configuration classes that are supposed to provide the way to create beans in more flexible ways.

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?

Need Of Dao And Service Interfaces

I am new to spring Mvc and in a lot of tutorials, I found there is a Dao interface like this
public interface StudentDAO {
public List<Student> getStudents();
public void addEntry(Student student);
public void updateEntry(Student student);
public void deleteEntry(Student student);
public Student getStudentById(int id);
}
and also services like this
public interface StudentService {
public List<Student> getStudents();
public void addEntry(Student student);
public void updateEntry(Student student);
public void deleteEntry(Student student);
public Student getStudentById(int id);
}
And there are implementations for these interfaces.
My question is why we need interfaces rather than direct implementation classes?
I'm glad to see someone questioning that practice.
Spring Framework introduced long time ago the pattern of defining interfaces for their managed service / DAO beans. I think that practice was introduced due to limitations in the technology they used to create dynamic proxies.
When a Spring-managed bean is defined, the framework creates a proxy to the underlying instance with the purpose of decorating it with cross-cutting functionality using AOP techniques. Apparently, the tools they used to implement those proxies in the early versions of Spring Famework required an interface to create the proxy out of it.
This requirement no longer holds in the latest versions of Spring Framework and you're safe to dispose of those useless interfaces.
The reason for ease of testing does not hold nowadays, either, as mocking frameworks like Mockito are also capable of mocking concrete classes.
In addition, you can use the #Primary annotation to replace the real implementation with a custom mock in a testing context.
For those reasons, I would scrap interfaces for internal service and DAO classes that will never have multiple co-existing valid implementations.
Keep interfaces for design patterns that really need them.
In theory, it creates interfaces to decrease the coupling. In other words you create interfaces that are the communication contracts. And with that you can have more of an implementation for the same contract. Example: In PersonDao you can have implementation with hibernate and one with native SQL. With that in places where you used, you only inject interace and CDI itself solves the implementation, then you easily change the implementation without affecting the places where it is used interfaces.
In practice in my projects, depending on the situation, do not create the interfaces, but I will emphasize, it depends on the project. Example: A DAO in the majority of the time it never changed its implementation, that is, I see no need to create the interfaces in these cases directly implement the concrete classes.
The post Jiri Tousek is an example for the use of interfaces. However in my tests, I always use the complete flow, including the database.
Perhaps the simplest concrete illustration for the need is testing.
With the DAO interface, you can test your application's logic without the need to have a DB running that's accessible from the machine running tests, simply by swapping your DAO implementation for a dummy one during tests. That dummy implementation can then provide consistent data for tests that doesn't change between test runs, cannot be overwritten in DB by accident, is versioned in you Git/SVN/whatever etc.
In general, this is part of the Program to an interface, not an implementation design principle.
In my experience, this separation of interface vs. implementation is a good idea even if you're never going to have multiple implementations, because it encourages programmers to think more deeply about the contract of the class.
Note that the principle is not universally accepted, here are some counter-arguments for example.
if you are doing project it includes some database so you must define function in interface in this way Which you use is easily seen.

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