While working on an web-application , I need to get a set of classes at few steps and I am thinking to separate this logic to a simple Factory so as based on the Class type We can create class instance as well init it with default values.
Current structure of Class hierarchy is
public interface DataPopulator<Source,Target>{
// some method decaration
}
Abstract class
public abstract class AbstractDataPopulator<Source,Target> implements DataPopulator<Source, Target>{
// some common implimentation
}
And now classes which will be used as actual implementations like
Type1Populator extends AbstractDataPopulator.
Type2Populator extends AbstractDataPopulator.
Each of these implementation needs a set of common dependencies based on what functionality is being executed by those Populators.
As of Now I am creating instance with new and than filling those dependencies with simple setter methods.
I am thinking about creating a simple factory pattern like
public interface PopulatorFactory{
<T extends Object> T create(String className) throws Exception;
<T extends Object> T create(Class populatorClass) throws Exception;
}
Abstract class
public abstract class DefaultPopulatorFactory impliments PopulatorFactory{
public <T> T create(final Class populatorClass) throws Exception{
return Class.forName(populatorClass);
}
// other method.
}
Implementation classes
public Type1PopulatorFactory extends DefaultPopulatorFactory {
public <T> T create(final Class populatorClass) throws Exception{
final T populator= super.create(populatorClass);
}
}
I also want to initialize newly created instances with some default values specific to each implementation, but I'm not sure what's the best way to do this?
Should I define another method say initDefaults?
What is the best way to pass those dependencies to these poulators.
Is the approach outlined by me fine or is it overly complicated?
In cases when you are building not-so-trivial objects it is usually better to use the Builder pattern instead of a Factory.
In your case if you don't need external data sources you can simply write constructors for your classes where you can supply the default values and get rid of the contraption in your question.
If you use the Builder pattern you can simplify your framework by using a Builder object for the common data and a SomeOtherBuilder which extends from Builder and adds the custom values of the specialized implementation. You can make your classes constructors which are taking a Builder object.
public class Builder {
// your fields go here
}
public class SomeOtherBuilder extends Builder {
// your specialized fields go here
}
public class YourClass {
public YourClass(Builder builder) {
// construct it here
}
}
You can also make your classes generic with using something like T extends Builder.
Related
I have a AbstractBaseRepository. All my Repositories extends from this class. I created another class RepositoryFactory to create any instance of Repository. Due to early binding of static method, I am facing problem.
public abstract class AbstractBaseRepository {
public static <T extends AbstractBaseRepository> T getNewInstance(EntityManagerFactory entityManagerFactory) {
throw new RuntimeException("Override and provide valid initialization");
}
...
}
public class RepositoryFactory {
public static <T extends AbstractBaseRepository> T getRepository(Class<T> cls) {
return T.getNewInstance(entityManagerFactory);
}
...
}
an example subclass
public class DeviceModelRepo extends AbstractBaseRepository {
public static DeviceModelRepo getNewInstance(EntityManagerFactory entityManagerFactory) {
return new DeviceModelRepo(entityManagerFactory);
}
...
}
Whenever I call getRepository() with a valid subclass of AbstractBaseRepository, runtime exception is thrown. This is due to early binding of static methods. During compile time, getNewInstance gets bound with AbstractBaseRepository rather than at runtime with actual type of the class. Any good workarounds?
My first suggestion is using Spring. It is very easy to get a list of all beans created with a certain interface.
Also, if you think of your Repository instances as a type of "plug-in" you might see how Java's ServiceLoader class can help.
Also, another approach is to use a switch statement in the factory and create the instances for each case rather than using static methods on the Repository subclasses.
Finally, I don't recommend reflection solutions but there are ways to load the class based on its name and reflectively creating a new instance.
But overriding static methods is not possible.
What I have understood by seeing your code is that you want to have different implementations of AbstractBaseRepository such as DeviceModelRepo. Then you want a factory class to create the instance of specific implementation of AbstractBaseRepository. Here the major problem is you try to overriding static methods which can never be overwritten but subclass will hide the parent implementation. Please don't use static method for overriding. You can change your implementation as given below and this issue will be resolved.
public abstract class AbstractBaseRepository {
public AbstractBaseRepository(EntityManagerFactory entityManagerFactory){
...
}
//removed method getNewInstance(EntityManagerFactory entityManagerFactory)
...
}
Then below implementation for subclass.
public class DeviceModelRepo extends AbstractBaseRepository {
public DeviceModelRepo(EntityManagerFactory entityManagerFactory) {
super(entityManagerFactory);
...
}
//removed method getNewInstance(EntityManagerFactory entityManagerFactory)
...
}
Now I am providing you two implementation of factory class.
One is having different method for each of implementation, such as getDeviceModelRepository().
Another solution is to use reflection and get repository instance by passing the implementation repository class.
public class RepositoryFactory {
//Solution-1, create separate method for each of repository like below
public static AbstractBaseRepository getDeviceModelRepository() {
return new DeviceModelRepo(entityManagerFactory);
}
//Solution-2, use reflection to get instance of specific implementation
//of AbstractBaseRepository
public static <T extends AbstractBaseRepository> T
getRepository(Class<T> repoClass) throws Exception{
return repoClass.getConstructor(EntityManagerFactory.class)
.newInstance(entityManagerFactory);
}
...
}
With reflection solution, you can get the repository instance as given below.
RepositoryFactory.getRepository(DeviceModelRepo.class)
I recently ran across this scenario in code that I didn't write and while there may be some design benefit to this approach, I can't seem to squeeze this rationale out of my own brain. So before I go and look foolish, I'm hoping for some feedback here.
Service interface something like this:
public interface Service {...}
Then, a base class that adds a generic reference to the Service interface where T extends the Service, but then the overall base class also implements the interface. Something like this:
public class ServiceBase<T extends Service> implements Service {...}
Why would you do this? I'm noticing that in practice the extension of ServiceBase always uses the same class name as T as the one that is being declared; so there's not really any magic polymorphic benefit here. Something like this:
public class MyService extends ServiceBase<MyService> {...}
and, the MyService class is never a container for the generic (e.g., I don't believe this is signaling some kind of self-containing list, where MyService could contain a list of MyServices).
Any ideas/thoughts on why someone would do this?
Why would you do this? I'm noticing that in practice the extension of
ServiceBase always uses the same class name as T as the one that is
being declared; so there's not really any magic polymorphic benefit
here.
Generics don't exist to create magic polymorphim. It is mainly a way to add constraints on types at compile time in order to reduce clumsy cast and error type at runtime.
In your case, suppose that ServiceBase class is abstract and has a process() method which needs to create at each call a new instance of the concrete class we declare in the parameterized type.
We call this abstract method createService().
Without using generics, we could declare the method like that public abstract ServiceBase createService().
ServiceBase without generics
public abstract class ServiceBase implements Service {
public abstract ServiceBase createService();
#Override
public void process() {
createService().process();
}
}
With this declaration, the concrete class may return any instance of ServiceBase.
For example, the following child class will compile because we are not forced to change the returned type of createService() to the current declared type.
MyService without generics
public class MyService extends ServiceBase {
#Override
public ServiceBase createService() {
return new AnotherService();
}
}
But if I use generics in base class :
ServiceBase with generics
public abstract class ServiceBase<T extends Service> implements Service {
public abstract T createService();
#Override
public void process() {
createService().process();
}
}
The concrete class has no choice, it is forced to change the returned type of createService() with the parameterized type declared.
MyService with generics
public class MyService extends ServiceBase<MyService> {
#Override
public MyService createService() {
return new MyService();
}
}
I made up an example using your class and interface declarations (except that I made ServiceBase abstract) which should illustrate the use of the generic types:
public interface Service {
int configure(String cmd);
}
public abstract class ServiceBase<T extends Service> implements Service {
private ServiceManager manager;
public ServiceBase(ServiceManager manager){
this.manager = manager;
}
public final void synchronize(T otherService){
manager.configureEnvironment(otherService.configure("syncDest"), configure("syncSrc"));
synchronizeTo(otherService);
}
protected abstract void synchronizeTo(T otherService);
}
public class ProducerService extends ServiceBase<ConsumerService> {
public ProducerService(ServiceManager manager) {
super(manager);
}
#Override
protected void synchronizeTo(ConsumerService otherService) {
/* specific code for synchronization with consumer service*/
}
#Override
public int configure(String cmd) { ... }
}
public class ConsumerService extends ServiceBase<ProducerService> {
public ConsumerService(ServiceManager manager) {
super(manager);
}
#Override
protected void synchronizeTo(ProducerService otherService) {
/* specific code for synchronization with producer service */
}
#Override
public int configure(String cmd) { ... }
}
Imagine we have services managed by a ServiceManager which can configure the environment of the services so that they are ready for synchronization with each other. How a configure command is interpreted is up to the specific service. Therefore a configure() declaration resides in our interface.
The ServiceBase handles the basic synchronization stuff that has to happen generally when two services want to synchronize. The individual implementations of ServiceBase shouldn't have to deal with this.
However ServiceBase doesn't know how a specific implementation of itself synchronizes to a specific other implementation of service. Therefore it has to delegate this part of synchronization to its subclass.
Now generics come into the play. ServiceBase also doesn't know to which type of service it is able to synchronize to. He has also to delegate this decision to its subclass. He can do this using the construct T extends Service
Given this structure now imagine two concrete subclasses of ServiceBase: ProducerService and ConsumerService; The consumer service can only synchronize to the producer service and the other way around. Therefore the two classes specify in their declaration ServiceBase<ConsumerService> respectively ServiceBase<ProducerService>.
Conclusion
Just like abstract methods can be used by superclasses to delegate the implementation of functionality to their subclasses, generic type parameters can be used by superclasses to delegate the "implementation" of type placeholders to their subclasses.
You haven't posted any of the definitions of these classes where the type parameter is used (which would most likely convey the rationale behind this design, or maybe the lack of it...), but in all cases, a type parameter is a way of parameterizing a class, just like a method can be parameterized.
The ServiceBase class implements a Service. This tells us that it implements the contract (methods) of a Service (to be more precise, subclasses of it can act as the implementation).
At the same time, ServiceBase takes a type argument that is a subtype of Service. This tells us that a service implementation probably has a "relationship" with another implementation type (possibly the same type as the current one). This relationship could be anything needed by the specific design requirement, e.g. the type of Service that this implementation can delegate to, the type of Service that can call this service, etc.
The way I read the following declaration
public class ServiceBase<T extends Service> implements Service {...}
is roughly: ServiceBase is a base implementation of a service, which can have a statically typed relationship with some other type of service.
These two aspects are completely independent.
I've got around 5 objects that I want to do similar things with.
I figured out that not to polute the code I will put a logic for those objects in one place.
public class MetaObjectController<T extends MetaObject> {
#Autowired
private final MetaObjectRepository<T> repository;
// generic logic
Here's how repository looks:
public interface MetaObjectRepository<T extends MetaObject> extends GraphRepository<T> {
T findByName(String name);
}
Now, I create concrete class which uses delegation:
public class ExperimentalController {
#Autowired
private final MetaObjectController<MetaCategory> metaController;
#RequestMapping(method = RequestMethod.POST)
public void add(#RequestBody MetaCategory toAdd) {
metaController.add(toAdd);
}
Now, when I look at the generated queries I see, that although instantiated correctly, repository puts MetaObject as an entity name instead of runtime type.
Is there a way to force the repository to use runtime type?
Please don't advise to put a #Query annnotation. That's not what I am looking for.
This is most probably due to type erasure: at runtime there is only the type constraint available which is MetaObject. If you want to use (via spring-data) the actually relevant subclass you will have to create explicit interfaces of the MetaObjectRepository like this:
public class Transmogrifier extends MetaObject
public interface MetaTransmogrifierRepository
extends MetaObjectRepository<Transmogrifier> {}
Using the generic dao pattern, I define the generic interface:
public interface GenericDao<T extends DataObject, ID extends Serializable> {
T save(T t);
void delete(ID id);
T findById(ID id);
Class<T> getPersistentClass();
}
I then implemented an default GenericDaoImpl implementation to perform these functions with the following constructor:
public GenericDaoImpl(Class<T> clazz) {
this.persistentClass = clazz;
DaoRegistry.getInstance().register(clazz, this);
}
The point of the DaoRegistry is to look up a Dao by the class associating to it. This allows me to extend GenericDaoImpl and overwrite methods for objects that requires special handling:
DaoRegistry.getInstance().getDao(someClass.getClass()).save(someClass);
While it works, there are a few things that I don't like about it:
DaoRegistry is an singleton
The logic of calling save is complicated
Is there a better way to do this?
Edit
I am not looking to debate whether Singleton is an anti-pattern or not.
First of all, what is your problem with DaoRegistry being singleton?
Anyway, you could have an abstract base class for your entities that'd implement save like this
public T save(){
DaoRegistry.getInstance().getDao(this.getClass()).save(this);
}
then you could simply call someEntity.save()
Or it may be more straightforward if the entity classes itself implemented the whole GenericDao interface (save, delete and find methods), so the contents of your GenericDaoImpl would be in the base class of your entities.
It could be better to use instance of DaoRegistry instead of static methods. It would make it more manageable for test configurations. You could implement it as
#Component("daoRegistry")
public class DaoRegistry {
#Autowired
private List<GenericDao> customDaos;
private GenericDao defaultDao = new GenericDaoImpl();
public <T> T getDao(Class<T> clazz) {
// search customDaos for matching clazz, return default dao otherwise
}
}
Also you could add save method to it and rename accordingly. All customised daos should be available as beans.
I want to know when we need to use the abstract factory pattern.
Here is an example,I want to know if it is necessary.
The UML
THe above is the abstract factory pattern, it is recommended by my classmate.
THe following is myown implemention. I do not think it is necessary to use the pattern.
And the following is some core codes:
package net;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
DaoRepository dr=new DaoRepository();
AbstractDao dao=dr.findDao("sql");
dao.insert();
}
}
class DaoRepository {
Map<String, AbstractDao> daoMap=new HashMap<String, AbstractDao>();
public DaoRepository () throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
Properties p=new Properties();
p.load(DaoRepository.class.getResourceAsStream("Test.properties"));
initDaos(p);
}
public void initDaos(Properties p) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String[] daoarray=p.getProperty("dao").split(",");
for(String dao:daoarray) {
AbstractDao ad=(AbstractDao)Class.forName(dao).newInstance();
daoMap.put(ad.getID(),ad);
}
}
public AbstractDao findDao(String id) {return daoMap.get(id);}
}
abstract class AbstractDao {
public abstract String getID();
public abstract void insert();
public abstract void update();
}
class SqlDao extends AbstractDao {
public SqlDao() {}
public String getID() {return "sql";}
public void insert() {System.out.println("sql insert");}
public void update() {System.out.println("sql update");}
}
class AccessDao extends AbstractDao {
public AccessDao() {}
public String getID() {return "access";}
public void insert() {System.out.println("access insert");}
public void update() {System.out.println("access update");}
}
And the content of the Test.properties is just one line:
dao=net.SqlDao,net.SqlDao
So any ont can tell me if this suitation is necessary?
-------------------The following is added to explain the real suitation--------------
I use the example of Dao is beacuse it is common,anyone know it.
In fact,what I am working now is not related to the DAO,I am working to build a Web
service,the web serivce contains some algorithms to chang a file to other format,
For example:net.CreatePDF,net.CreateWord and etc,it expose two interfaces to client:getAlgorithms and doProcess.
The getAlogrithoms will return all the algorithms's ids,each id is realted to the
corresponding algorithm.
User who call the doProcess method will also provide the algorithm id he wanted.
All the algorithm extends the AbstractAlgorithm which define a run() method.
I use a AlogrithmsRepository to store all the algorithms(from
the properties file which config the concrete java classes of the algorithms by the web
service admin).That's to say, the interface DoProcess exposed by the web service is
executed by the concrete alogrithm.
I can give a simple example:
1)user send getAlgorithms request:
http://host:port/ws?request=getAlgorithms
Then user will get a list of algorithms embeded in a xml.
<AlgorithmsList>
<algorithm>pdf</algorithm>
<algorithm>word<algorithm>
</AlgorithmsList>
2)user send a DoProcess to server by:
http://xxx/ws?request=doProcess&alogrithm=pdf&file=http://xx/Test.word
when the server recieve this type of requst,it will get the concrete algorithm instance according to the "algorithm" parameter(it is pdf in this request) from the AlgorithmRepostory. And call the method:
AbstractAlgorithm algo=AlgorithmRepostory.getAlgo("pdf");
algo.start();
Then a pdf file will be sent to user.
BTW,in this example, the each algorithm is similar to the sqlDao,AccessDao.
Here is the image:
The design image
Now,does the AlgorithmRepostory need to use the Abstract Factory?
The main difference between the two approaches is that the top one uses different DAO factories to create DAO's while the bottom one stores a set of DAO's and returns references to the DAO's in the repository.
The bottom approach has a problem if multiple threads need access to the same type of DAO concurently as JDBC connections are not synchronised.
This can be fixed by having the DAO implement a newInstance() method which simply creates and returns a new DAO.
abstract class AbstractDao {
public abstract String getID();
public abstract void insert();
public abstract void update();
public abstract AbstractDao newInstance();
}
class SqlDao extends AbstractDao {
public SqlDao() {}
public String getID() {return "sql";}
public void insert() {System.out.println("sql insert");}
public void update() {System.out.println("sql update");}
public AbstractDao newInstance() { return new SqlDao();}
}
The repository can use the DAO's in the repository as factories for the DAO's returned by the Repository (which I would rename to Factory in that case) like this:
public AbstractDao newDao(String id) {
return daoMap.containsKey(id) ? daoMap.get(id).newInstance() : null;
}
Update
As for your question should your web-service implement a factory or can it use the repository like you described? Again the answer depends on the details:
For web-services it is normal to
expect multiple concurrent clients
Therefore the instances executing the
process for two clients must not
influence eachother
Which means they must not have shared state
A factory delivers a fresh instance on
every request, so no state is shared
when you use a factory pattern
If (and only if) the instances in your
repository are stateless your
web-service can also use the
repository as you describe, for this
they probably need to instantiate
other objects to actually execute the
process based on the request
parameters passed
If you ask to compare 2 designs from UML, 2nd API on UML have following disadvantage:
caller needs to explicitly specify type of DAO in call to getDAO(). Instead, caller shouldn't care about type of DAO it works with, as long as DAO complies with interface. First design allows caller simply call createDAO() and get interface to work with. This way control of which impl to use is more flexible and caller don't have this responsibility, which improves overall coherence of design.
Abstract Factory is useful if you need to separate multiple dimensions of choices in creating something.
In the common example case of windowing systems, you want to make a family of widgets for assorted windowing systems, and you create a concrete factory per windowing system which creates widgets that work in that system.
In your case of building DAOs, it is likely useful if you need to make a family of DAOs for the assorted entities in your domain, and want to make a "sql" version and an "access" version of the entire family. This is I think the point your classmate is trying to make, and if that's what you're doing it's likely to be a good idea.
If you have only one thing varying, it's overkill.