Factory pattern definition: Provides an interface for creating objects.
Why use factory mode
The factory model is the most commonly used model we use. The famous Jive forum uses a lot of factory model. The factory model can be said to be everywhere in Java program systems.
Why is the factory model so commonly used? Because the factory pattern is equivalent to creating new instance objects, we often have to generate instance objects based on class Class. For example, A a=new A() Factory pattern is also used to create instance objects, so in the future, you need to be more careful. Can you consider the practical factory model? Although doing so may do more work, it will bring you greater scalability and as little modification as possible to your system.
Let's take the Sample class as an example. If we want to create an instance object of Sample:
The code copy is as follows:
Sample sample=new Sample();
However, the reality is that we usually do some initialization work when creating sample instances, such as assignment query databases, etc.
First of all, what we think of is that we can use Sample's constructor, so that the instance is generated and written as:
The code copy is as follows:
Sample sample=new Sample(parameter);
However, if the initialization work done when creating a sample instance is not as simple as assignment, it may be a long piece of code. If it is also written into the constructor, then your code will be ugly (refactor reorganization is required).
Why is the code ugly? Beginners may not have this feeling? We analyze it as follows: If the initialization work is a very long piece of code, it means that a lot of work needs to be done. Putting a lot of work into a method is equivalent to putting a lot of eggs in it. It is very dangerous in a basket, which is also contrary to Java's object-oriented principle. Object-oriented encapsulation and dispatch (Delegation) tell us that we should try to "cut" long code dispatch into each segment, and The segment is "encapsulated" again (reducing the coupling connection between segments), so that the risks will be diversified. If you need to modify them in the future, just change each segment and there will be no more things that will affect each segment.
In this example, first, we need to separate the work of creating an instance from the work of using an instance, that is, separate the large amount of initialization work required to create an instance from Sample's constructor.
At this time, we need the Factory factory pattern to generate objects, and we can no longer use the simple new Sample (parameters). Also, if Sample has an inheritance such as MySample, according to interface-oriented programming, we need to abstract Sample into an interface. Now Sample is an interface, with two subclasses MySample and HisSample. When we want to instantiate them, as follows:
The code copy is as follows:
Sample mysample=new MySample(); Sample hissample=new HisSample();
As the project deepens, Sample may "bring a lot of sons out", so we need to instantiate these sons one by one. What's worse, we may also need to modify the previous code: add instances that later give birth to sons. This is unavoidable in traditional programs.
But if you consciously use the factory model from the beginning, these troubles are gone.
Factory Method
You will build a factory that specializes in producing Sample instances:
The code copy is as follows:
public class Factory{
public static Sample creator(int which){
//getClass Generate Sample Generally, dynamic class loading can be used to load classes.
if (which==1)
return new SampleA();
else if (which==2)
return new SampleB();
}
}
Then in your program, if you want to instantiate Sample, use the copy code code as follows:
Sample sampleA=Factory.creator(1);
In this way, the specific subclass of Sample is not involved in the entire process. To achieve the packaging effect, it will reduce the chance of error modification. This principle can be compared in a very popular way: the more specific things are done, the easier it is to make mistakes. Everyone who has done specific work has a deep understanding of this. On the contrary, the higher the official is, the more abstract and general the words are, the less likely it is to make a mistake in the pattern. It seems that we can also understand the principles of life from programming?
Use factory methods to pay attention to several roles. First, you need to define the product interface, such as Sample above. There is an implementation class of Sample interface under the product interface, such as SampleA, and secondly, there is a factory class to generate the product Sample, as shown in the figure below. On the far right is the production object Sample:
To be more complicated, it is to expand on the factory class, which also inherits its implementation class concreteFactory.
Abstract factory
The factory model includes: Factory Method and Abstract Factory.
The difference between these two patterns is in the complexity of the creation of objects. If our method of creating an object becomes complicated, as in the above factory method, it is to create an object Sample, if we have a new product interface Sample2.
Assuming here: Sample has two concrete classes SampleA and SamleB, and Sample2 also has two concrete classes Sample2A and SampleB2. Then, we will turn the Factory in the above example into an abstract class, encapsulating the common part in the abstract class, and using different parts Subclass implementation, the following is to expand the Factory in the above example into an abstract factory:
The code copy is as follows:
public abstract class Factory{
public abstract Sample creator();
public abstract Sample2 creator(String name);
}
public class SimpleFactory extends Factory{
public Sample creator(){ ......... return new SampleA }
public Sample2 creator(String name){ ......... return new Sample2A }
}
public class BombFactory extends Factory{
public Sample creator(){ ...... return new SampleB }
public Sample2 creator(String name){ ...... return new Sample2B }
}
From the above, the two factories each produce a set of Sample and Sample2. Maybe you will wonder, why can't I use the two factory methods to produce Sample and Sample2 respectively?
There is another key point in the abstract factory, because there is a certain connection between the methods that produce Sample and Sample2 in SimpleFactory, so these two methods need to be bundled into one class. This factory class has its own characteristics. Perhaps The manufacturing process is unified, for example: the manufacturing process is relatively simple, so the name is SimpleFactory.
In practical applications, the factory method is used more frequently, and it is combined with dynamic class loaders.
Examples of Java factory model
Let's take Jive's ForumFactory as an example. We discussed this example in the previous Singleton mode, and now we will discuss its factory mode:
The code copy is as follows:
public abstract class ForumFactory {
private static Object initLock = new Object(); private static String className ="com.jivesoftware.forum.database.DbForumFactory"; private static ForumFactory factory = null;
public static ForumFactory getInstance(Authorization authorization) {
//If no valid authorization passed in, return null.
if (authorization == null) { return null; }
//The following uses Singleton singleton mode
if (factory == null) {
synchronized(initLock) {
if (factory == null) { ......
try {
//Dynamic reprint
Class c = Class.forName(className);
factory = (ForumFactory)c.newInstance();
} catch (Exception e) { return null; }
}
}
}
//Now, return proxy. Used to restrict authorized access to forum
return new ForumFactoryProxy(authorization, factory,factory.getPermissions(authorization));
}
//The method of creating forum is completed by a subclass inheriting forumfactory.
public abstract Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException;
....
}
Because Jive now stores forum posts and other content data through the database system, if you want to change it to be implemented through the file system, this factory method ForumFactory provides a dynamic interface:
The code copy is as follows:
private static String className = "com.jivesoftware.forum.database.DbForumFactory";
You can use the method you developed to create forum instead of com.jivesoftware.forum.database.DbForumFactory.
In the above code, there are three modes. In addition to the factory mode, there are also Singleton single-state mode and proxy mode. The proxy mode is mainly used to authorize users to access forum, because there are two types of people to access forum: one If you are a registered user and a guest, then the corresponding permissions will be different, and this permission runs through the entire system. Therefore, establishing a proxy, similar to the concept of gateway, can achieve this effect well.
Check out CatalogDAOFactory in Java pet store:
The code copy is as follows:
public class CatalogDAOFactory {
/**
* This method develops a special subclass to implement the DAO pattern.
* The specific subclass definition is in the J2EE deployment descriptor.
*/
public static CatalogDAO getDAO() throws CatalogDAOSysException{
CatalogDAO catDao = null;
try {
InitialContext ic = new InitialContext();
//Dynamic loading of CATALOG_DAO_CLASS
//You can define your own CATALOG_DAO_CLASS, so that you don't need to change too much code
//, complete the huge system changes.
String className =(String) ic.lookup(JNDINames.CATALOG_DAO_CLASS);
catDao = (CatalogDAO) Class.forName(className).newInstance();
} catch (NamingException ne) {
throw new CatalogDAOSysException(" CatalogDAOFactory.getDAO: NamingException while getting DAO type : /n" + ne.getMessage());
} catch (Exception se) {
throw new CatalogDAOSysException("CatalogDAOFactory.getDAO: Exception while getting DAO type : /n" + se.getMessage());
}
return catDao;
}
}
CatalogDAOFactory is a typical factory method. catDao obtains the CatalogDAOFactory specific implementation subclass through the dynamic class loader className. This implementation subclass is used to operate the catalog database in the Java pet store. Users can customize their own specifics according to the type of the database. Implement subclasses and give your own subclass name to the CATALOG_DAO_CLASS variable.
It can be seen that the factory method does provide a very flexible and powerful dynamic expansion mechanism for the system structure. As long as we change the specific factory method, there is no need for a little change in other parts of the system, and it is possible to change the system functions in a transformation.