Factory Mode
Factory mode definition: Provides an interface for creating objects.
Why use factory mode
Factory mode is our most commonly used mode. The well-known Jive Forum uses factory mode extensively. Factory mode can be seen everywhere in Java programming systems.
Why is factory mode so common?Because factory mode is equivalent to creating new instance objects, we often need to generate instance objects based on class Class, such as A=new A() factory mode, which is also used to create instance objects, so in the future, there will be more eyes for new. Can we consider the practical factory mode, although doing so may do more, but it willGive your system more scalability and fewer modifications.
Let's take the class Sample for example, if we want to create an instance object of Sample:
Sample sample = new Sample();
However, the reality is that we usually do point initialization when we create a sample instance, such as assigning queries to databases, and so on.
First, we want to use Sample's constructor so that the generated instances are written as:
Sample sample=new Sample(parameter)
However, if the initialization you do when you create a sample instance is not as simple as assignment, it can be a long period of code, and if you write it to the constructor, your code will be ugly (requiring Refactor restructuring).
Why is the code ugly? Beginners may not feel this way. Let's analyze the following. If initialization is a long code, it means there is a lot of work to do. Loading a lot of work into one method, which is equivalent to putting a lot of eggs in a basket, is dangerous. This is also contrary to Java face-to-face.The principle of image, object-oriented encapsulation and delegation, tells us that long code is "cut" into each segment as much as possible, and "encapsulated" each segment again (reducing the coincidence between segments and segments), so that risk is spread out and modified later, as long as each segment is changed, no moreA hundred things happen.
In this example, first, we need to separate the work of creating an instance from that of using it, that is, separate the large amount of initialization required to create an instance from Sample's constructor.
At this point, we need Factory Factory mode to generate objects, so we can't use the simple new Sample above.Also, if Sample has an inheritance such as MySample, we need to abstract Sample into an interface for Interface-oriented programming.Sample is now an interface with two subclasses, MySample and HisSample.When we want to instantiate them, here are the following:
Sample mysample=new MySample(); Sample hissample=new HisSample()
As the project progresses, Sample may be "giving birth to many sons", so we need to instantiate each of these sons, or worse, we may have to modify the previous code: by adding an instance that later gave birth to a son. This is unavoidable in traditional programs.
But if you start using the factory mode consciously, these problems will be gone.
Factory method
You'll set up a factory that specializes in producing Sample instances:
public class Factory{ public static Sample creator(int which){ //A getClass produces a Sample that typically loads classes using dynamic classes. if (which==1) return new SampleA(); else if (which==2) return new SampleB(); } }
So in your program, if you want to instantiate Sample, use
Sample sampleA=Factory.creator(1);
In this way, no specific subclasses of Sample are involved in the whole process, and the encapsulation effect is achieved, which reduces the chance of error modification. This principle can be compared with a very common saying: the more specific things you do, the easier it is to model errors.Everyone who has done specific work knows it well. On the contrary, the higher an official does, the more abstract and general his words are, the less likely he is to make mistakes.It seems that we can also understand the truth of life from programming?
There are several roles to note when using the factory approach:
First you need to define a product interface, such as Sample above, an implementation class with a Sample interface under the product interface, such as SampleA, and then a factory class to generate a product Sample, as shown below, with the object Sample being produced at the far right:
A slightly more complex point is to expand on the factory class, which also inherits its implementation class concreteFactory.
Abstract factory
There are factory methods and abstract factories in the factory mode.
The difference between the two modes is in the complexity of the object that needs to be created.If our method of creating objects becomes complex, such as creating an object Sample in the factory method above, if we also have a new product interface, Sample2.
Let's assume that Sample has two concrete classes, SampleA and SamleB, and Sample2 has two concrete classes, Sample2A and SamplleB2. So, let's make Factory an abstract class in the above example, encapsulate the common part in the abstract class, and implement the different parts using subclasses. Here's how to expand Factory in the above example into an abstract factory:
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 } }
Seeing from above that two factories each produce a set of Samples and Samplle2, you may wonder why I can't use two factory methods to produce Samples and Samplle2 separately?
Another key point about abstract factories is that there is a link between the methods of producing Sample and producing Sample2 within SimpleFactory, so the two methods should be bundled together in a class that has its own characteristics. Maybe the manufacturing process is uniform, for example, the manufacturing process is simple, soThe name is SimpleFactory.
In practice, the factory method is used more often and in combination with the dynamic class loader.
Java Factory Mode Example
Let's take Jive's ForumFactory example, which we discussed in the previous Singleton pattern, and now its factory pattern:
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; } //Singleton singleton mode is used below if (factory == null) { synchronized(initLock) { if (factory == null) { ...... try { //Dynamic reload class Class c = Class.forName(className); factory = (ForumFactory)c.newInstance(); } catch (Exception e) { return null; } } } } //Now, returns proxy. Used to restrict authorized access to forum return new ForumFactoryProxy(authorization, factory,factory.getPermissions(authorization)); } //The real way to create a forum is by inheriting a subclass of forumfactory. public abstract Forum createForum(String name, String description) throws UnauthorizedException, ForumAlreadyExistsException; .... }
Because Jive now stores content data such as forum posts through a database system, this factory method, ForumFactory, provides a dynamic interface if you want to change it to a file system:
private static String className = "com.jivesoftware.forum.database.DbForumFactory";
Instead of com.jivesoftware.forum.database.DbForumFactory, you can create forums yourself.
In the above section of code, there are three modes in common, Singleton singleton mode and proxy mode. The proxy mode is mainly used to authorize users to access forum, because there are two types of people accessing forum: one registered user and one visitor guest, so the corresponding permissions are different.And this privilege runs through the system, so a proxy, similar to the concept of a gateway, works well.
Look at the CatalogDAOFactory in the Java Pet Store:
public class CatalogDAOFactory { /** * This method establishes 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 CATALOG_DAO_CLASS //You can define your own CATALOG_DAO_CLASS so that you don't have to change too much code //On the premise of this, complete the tremendous changes of the system. 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 : " + ne.getMessage()); } catch (Exception se) { throw new CatalogDAOSysException("CatalogDAOFactory.getDAO: Exception while getting DAO type : " + se.getMessage()); } return catDao; } }
CatalogDAOFactory is a typical factory method. catDao obtains the specific implementation subclass of CatalogDAOFactory through dynamic class loader className. This implementation subclass is used to operate the catalog database in Java Pet Store. Users can customize their own implementation subclass according to the type of database and subclass themselves.Name it to the CATALLOG_DAO_CLASS variable.
Thus, 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, it is possible to change the system function without any change elsewhere in the system.