In the design mode, Factory Method is also a relatively simple, but the app is very wide, EJB, RMI, COM, CORBA, Swing can see the shadow of this mode, which is one of the most important modes. In many places we I will see the class named by XXXFactory, then, what is Factory Method, why use this mode, how to use Java language to implement this mode, this is what you want to bring to you.
Basic Concept Factory Method is a creative model that defines an interface to create an object, but allows the subclass to determine which class of specific instantiation. When a class cannot be expected to create which type of object or a class We need Factory Method mode when you need to specify the objects created. Simply, Factory Method can produce different instances according to different conditions. Of course, these different instances are usually the same type, which has common The parent class. Factory Method encapsulates the specific process of creating these instances, simplifies the client's application, and improves the program's scalability, so that you can do the minimum change in the future to add new to the class to be created. Usually we Use Factory Method as a standard to create objects, when you find more flexibility, you will start considering transformation to other creation mode
Simple analysis Figure 1 is a structural diagram of the Factory Method mode, which provides some terms that allow us to make more convenient description:
Product: The abstraction of the product you need to create. ConcreteProduct: Product's subclass, a series of specific products. Creator: Abstract creator interface, declaration returns Factory Method. Concretecreator: Concretecreator: Specific creator, rewrite Creator Factory Method, returns an instance of the ConcreteProduct type.
Figure 1: Factory Method mode structure
It can be clearly seen that such parallel correspondence: product <====> Creator; conreteproduct <====> Conretecreator
Abstract products correspond to abstract creators, specific products corresponding to specific creators. What is the benefit of this? Why don't we use specific products and specific creators to complete your needs? In fact, we can do this. But through Factory Method mode is completed, customer (Client) simply refers to abstract Product and Creater, which can do not care about specific ConcreteProduct and ConcreteCreator, so we can get additional benefits:
First of all, the client can unify the example from the abstract creator, the Creator's role is separated by the CLIENT and the product creation process, and the customer does not have to pay back the specific product, nor to care about how these products are created. ConcreteProduct is also hidden behind the Product, and ConreProduct inherits all properties of the Product and implements the abstract method defined in the product. Follow the principle of the object in Java, the ConcreteProduct generated by Concretecreator can automatically trace into Product In this way, the concreteproduct different from the substantive content can be unified in the form, and it is accessed by Creator to the client. Second, when we add a new ConcreteCreator, the client program is unchanged because the interface provided by Creator is unchanged. There will be no change in change, and the disaster that will not be moved. This is a good encapsulation. But if you use CONCRETEPRODUCT and CONCRETECREATOR two classes, you can't do this, excellent Object-oriented design encourages the encapsulation and delegation, and the Factory Method mode is a typical example of encapsulation and commission. The package is reflected by abstract creator Creator, and the delegation is through abstract creator. The responsibility of the creation object is fully handed over to the specific creator ConcreteCreator.
Now, please look back to see the paragraph in the basic concept, starting to think that it is difficult to understand, now it is already unclear.
Let's take a look at how to implement the Factory Method mode in Java, further deepen its understanding. Details first, create objects with Factory Method mode, do not necessarily let our code shorter, often longer, We also use more classes, the real purpose is to be flexible and elastic to create uncertain objects. Moreover, the reusability of the code is improved, the client's application is simplified, and the customer code will greatly reduce the code. , More readable.
Standard Realization: Here I use Bruce Eckel to describe the classic example shape of OO thinking. This is more familiar. I have written the following paragraph one segmentation code in full according to the structure defined in Figure 1. This code is created Different Shape instances, each instance completions two operations: DRAW and ERASE. The specific creation process is commissioned to shareFactory. 1.A First define an abstract class shape to define two abstract methods.
Abstract class shape {
// Sour Shape
Public Abstract void Draw ();
// Wipe out Shape
Public abstract void erases;
Public String Name;
Public Shape (String Aname) {
Name = aname;
}
} 1.B Define two subclasses of Shape: Circle, Square, implement the abstract method defined in Shape
// round subclass
Class Circle Extends Shape {
Public void draw () {
System.out.println ("IT Will Draw A Circle.");
}
Public void erase () {
System.out.println ("IT WILL ERASE A CIRCLE.");
}
// Constructor
Public circle (string aname) {
Super (aname);
}
}
// square subclass
Class Square Extends Shape {
Public void draw () {
System.out.Println ("IT Will Draw A Square.");
}
Public void erase () {
System.out.println ("IT WILL ERASE A Square.");
}
// Constructor
Public Square (String Aname) {
Super (aname);
}
}
1.c Define an abstract creator, Anoperation Call FactoryMethod Create an object and performs a series of operations on the object.
Abstract class shapefactory {
Protected Abstract Shape FactoryMethod (String Aname);
// Define a series of behaviors in the archeration
Public void anopertons (String Aname) {
Shape s = factorymethod (aname);
System.out.println ("THE CURRENT Shape IS: S.NAME);
s.draw ();
S.RASE ();
}
} 1.D defines two specific creator CircleFactory, SquareFactory corresponding to Circle and Square, and implement the MethodFactory method for the parent class.
// Define the CircleFactory that returns a Circle instance
Class Circraftory Extends ShapeFactory {
// Reserve the FactoryMethod method, return Circle object
Protected Shape FactoryMethod (String Aname) {
Return New Circle (CREATED BY CIRCLEFAACTORY) ")
}
/ / Define SquareFactory for returning Square instance
Class SquareFactory Extends ShapeFactory {
/ / Reload the FactoryMethod method, return Square object
Protected Shape FactoryMethod (String Aname) {
Return New Square (CREATED BY SQUAREFActory);
}
}
1.e Test Class: Please note that this client program is so simple, there is no need to judge the statement, and there is no need to care about the details of ConcreteProduct and Concretecreator (because I am using the ANOPERATION two methods in Product, so even Product The shadow did not see, of course, the specific call of the method in the product is also nice to the client program).
Class main {
Public static void main (String [] args) {
ShapeFactory sf1 = new squarefactory ();
ShapeFactory sf2 = new circlectory ();
sf1.anoperation ("shape one");
sf2.anoperation ("shape two);
}
}
Results are as follows: The current shape is: Shape one (created by SquareFactory) It will draw a square.It will erase a square.The current shape is: Shape two (created by CircleFactory) It will draw a circle.It will erase a Circle. Parameterized Factory Method: This method relies on the specified parameters as a flag to create a corresponding instance. This is a very common way. For example, BorderFactory in JFC is a very good example. The following example is String as a tag, if the type of parameter is different, then you can use the overload function to solve this problem, define a series of parameters and method of the same name function, here java.util.calendar.GetInstance ( It is an excellent example. The parameterized creation method overcomes the most significant defect in Factory Method mode, which is when the specific product is more, we have to establish a series of specific constructors. But at the client We must specify parameters to determine which class to create. .
Class Nothisshape Extends Exception {
Public Nothisshape (String Aname) {
Super (aname);
}
}
2.b Remove the two subclasses of ShapeFactory, changed by ShapeFactory directly responsible for the creation of instances. ShapeFactory turns into a specific creator, direct FactoryMethod to multiple objects with parameterized methods.
Abstract class shapefactory {
Private static shape s;
Private shapefactory () {}
Static Shape FactoryMethod (String Aname, String Atype) Throws Nothisshape {
IF (atype.compareto ("square") == 0)
Return New Square (Aname);
Else IF ("Circle") == 0) Return New Circle (aname);
Else Throw New Nothisshape (atype);
}
// Define a series of behaviors in the archeration
Static void Anoperation (String Aname, String Atype "throws nothiisshape {
S = FactoryMethod (aname, atype);
System.out.println ("THE CURRENT Shape IS: S.NAME);
s.draw ();
S.RASE ();
}
}
2.C Test Class: Here the client must specify parameters to determine which class created specifically. This example is a static function and can be referenced directly.
Class main {
Public static void main (string [] args) throws nothisshape {
ShapeFactory.anoperation ("Shape One", "Circle");
ShapeFactory.anoperation ("Shape Two", "Square");
ShapeFactory.anoperation ("Shape Three", "Delta");
}
}
The results of the operation are as follows:
THE CURRENT Shape IS: Shape ONE
IT WILL DRAW a CIRCLE.
IT WILL ERASE A CIRCLE.
THE CURRENT Shape IS: Shape Two
IT WILL DRAW A Square.
IT WILL ERASE A Square.
Exception in Thread "Main" Nothisshape: DELTA
At ShapeFactory.FactoryMethod (ShapeFactory.java: 10)
At ShapeFactory.anoperation (ShapeFactory.java: 15)
At main.main (main.java: 5)
Dynamic loading mechanism: Sometimes we pass the instance of ConcreteProduct to the creator as a parameter, in which case if you complete the creation process in the creator, you must judge the specific type of parameters (instanceof), and then can generate the corresponding Examples, more than a good practice is to use Java's dynamic loading mechanism to complete this matter. For example: we get a subclass of Shape, but don't know if the subclass is specifically, you can use the Class class to bring a method. NewInstance () Get an instance return (shape) s.getClass (). Newinstance (); this method is interested in the reader can try itself, limited to space, and do not write specific code.
After reading this article, I believe that the reader has a relatively clear understanding of the Factory Method mode. What I want to say is that we should not only care about a specific model, how to implement this mode, more Through the phenomenon, it is not only known, but also knows it, but it is necessary to deepen the understanding of object-oriented ideas through the learning of the model, let your understanding will sublimate. Factory method model seems simple, and it is deep. Abstraction, Package, inheritance, commission, polymorphism, conceptual concepts of objects, etc., is here to be referred to here. Only have the essence of it, we can not use the form of flexible use, not to use Model mode mode.