Applying design Patterns in Java--factory method

Source: Internet
Author: User
Tags abstract define implement interface return string client
Design in design mode, Factory method is also a relatively simple one, but the application is very broad, ejb,rmi,com,corba,swing can see the shadow of this pattern, It is one of the most important patterns. In many places we see xxxfactory classes like this, so what is factory method, why use this pattern, how to use the Java language to implement the pattern, this is what this article wants to bring to you.

Basic concepts

Factory method is a creation pattern that defines an interface for creating objects, but lets subclasses decide which class to instantiate. When a class cannot predict which kind of object to create or a class needs a subclass to specify the object to create, we need to use the Factory Method mode. In short, Factory methods can produce different instances based on different conditions, of course these different instances are usually of the same type and have a common parent class. Factory method encapsulates the process of creating these instances, simplifies the application of the client, and improves the extensibility of the program so that the smallest changes can be made in the future to add new classes to be created. Usually we use factory method as a standard way to create objects, and when we find that we need more flexibility, we start thinking about converting to other creation patterns.

Simple analysis

Figure 1 is a structure diagram of the factory method pattern, which provides some terminology that allows us to make a more convenient description:


Figure 1:factory Method Pattern Structure

1. Product: An abstract class that needs to be created.
2. Concreteproduct:product, a series of specific products.
3. Creator: An abstract creator interface that declares the factory method that returns the object of the product type.
4. Concretecreator: The specific creator, overriding the factory method in creator, returns an instance of the Concreteproduct type.

This can be clearly seen in this parallel relationship: Product <====> Creator; Conreteproduct <====> Conretecreator

Abstract the product corresponds to the abstract creator, the specific product corresponding to the specific creator. What are the benefits of doing this? Why don't we just use specific products and specific creators to complete the requirements? But we can do that in fact. But through the factory method mode, the customer (client) By simply referencing the abstract product and creater, there can be no concern for specific concreteproduct and concretecreator, and we can gain additional benefits by doing so:

First, the client can unify the resulting instances from the abstract creator, and creator's role separates the client from the product creation process, and the customer does not have to worry about returning a specific product or how the product was created. Concreteproduct is also hidden behind product, Conreteproduct inherits all of the attributes of product and implements the abstract method defined in product, according to the object Modeling (CAST) principle in Java, The concreteproduct generated by Concretecreator can be automatically traced back to product. Thus, different concreteproduct of substance can be formally unified as product, Provided to the client through creator to access.

Second, when we add a new concretecreator, because the interface provided by creator is unchanged, the client program will not have the slightest change, will not bring a move and lead the whole body of the disaster, This is the embodiment of good encapsulation. But if you use Concreteproduct and concretecreator two classes directly, you can't do it anyway. Excellent object-oriented design encourages the use of encapsulation (encapsulation) and delegates (delegation) , and the factory method pattern is a typical example of encapsulation and delegation, where the encapsulation is embodied by the abstract creator creator, while the delegate is represented by the abstract creator to the specific creator concretecreator the responsibility to create the object.

Now, please look back at the basic concept of that paragraph, the beginning may feel jerky difficult to understand, now is not a lot of clarity.

Let's take a look at how to implement factory method in Java to further deepen our understanding of it.

Specific implementation

To be clear, creating objects with factory method does not necessarily make our code shorter, things are often longer and we use more classes, and the real purpose is to be flexible and resilient in creating uncertain objects. Moreover, the reusability of the code improves and the client's application simplifies , the client program's code will be greatly reduced and become more readable.

Standard implementation: Here I use the classic example of Bruce Eckel to describe Oo thought. This will make everyone more familiar. I wrote the following section of the demo code exactly as defined in Figure 1. The purpose of this code is to create different Shape instances, each of which completes two operations: Draw and erase. Specific creation process delegate? Shapefactory to complete.

1.a first defines an abstract class shape, defining two abstract methods.

Abstract class Shape {
Sketch Shape
public abstract void Draw ();
Erase shape.
public abstract void erase ();

public String name;
Public Shape (String aname) {
name = Aname;
}
}

1.B defines two subclasses of shape: Circle, Square, which implements the abstract method defined in shape

Round Subclass
Class Circle extends Shape {
public void Draw () {
System.out.println ("It'll draw a circle.");
}
public void Erase () {
System.out.println ("It'll erase a circle.");
}
Constructors
Public Circle (String aname) {
Super (ANAME);
}
}

Square Sub Class
Class Square extends Shape {
public void Draw () {
System.out.println ("It'll draw a square.");
}
public void Erase () {
System.out.println ("It'll erase a square.");
}
Constructors
Public Square (String aname) {
Super (ANAME);
}
}

1.C defines an abstract creator, Anoperation calls FactoryMethod to create an object and perform a series of operations on that object.

Abstract class Shapefactory {
Protected abstract Shape FactoryMethod (String aname);
A series of behaviors that define shape in anoperation
public void Anoperation (String aname) {
Shape s = FactoryMethod (Aname);
System.out.println ("The current shape is:" + s.name);
S.draw ();
S.erase ();
}
}

1.D defines the two specific creator circlefactory,squarefactory corresponding to circle and square, and implements the Methodfactory method of the parent class

Defines a circlefactory that returns an instance of circle
Class Circlefactory extends Shapefactory {
Overloaded FactoryMethod method, returning Circle Object
Protected Shape FactoryMethod (String aname) {
Return to New Circle (Aname + "(created by Circlefactory)");
}
}

Defines the squarefactory that returns the Square instance
Class Squarefactory extends Shapefactory {
Overloaded FactoryMethod method, returning square object
Protected Shape FactoryMethod (String aname) {
Return to New Square (Aname + "(created by Squarefactory)");
}
}

1.E Test class: Please note how concise the client is, without wordy conditional judgments, and without concern for the details of Concreteproduct and Concretecreator (because I have anoperation encapsulated two methods in product here, So even the shadow of the product did not see, of course, the product in the method of the specific call into the client program is also good.

Class Main {
public static void Main (string[] args) {
Shapefactory SF1 = new Squarefactory ();
Shapefactory SF2 = new Circlefactory ();
Sf1.anoperation ("Shape One");
Sf2.anoperation ("Shape two");
}
}

The results of the operation are as follows:
The current shape Is:shape one (created by squarefactory)
It'll draw a square.
It'll erase a square.
The current shape Is:shape two (created by Circlefactory)
It would draw a circle.
It would erase a circle.

Parameterized factory Method: This is a common way to create a corresponding instance by using a specified parameter as a flag. For example, the borderfactory in JFC is a good example. The following example is judged by a string as a tag, and if the type of the argument is not the same, then the overload function can be used to solve the problem, defining a series of parameters and different method bodies with the same name function, here Java.util.Calendar.getInstance () This is an excellent example. The method of parameterized creation overcomes the most obvious flaw in the factory methods model, that is, when the specific product is more than once, we have to establish a series of specific constructors corresponding to it. But at the client we have to specify the parameters to decide which class to create.

2.a we modify on the basis of the first method, and first customize an exception so that more error information can be obtained when incorrect parameters are passed in.

Class Nothisshape extends Exception {
Public Nothisshape (String aname) {
Super (ANAME);
}
}

2.b removed the two subclasses of Shapefactory, and instead was directly responsible for the creation of the instance by Shapefactory. Shapefactory itself into a specific creator, directly using parameterized methods to achieve factorymethod return a variety of objects.

Abstract class Shapefactory {
private static Shape s;
Private Shapefactory () {}

Static Shape FactoryMethod (String aname, String atype) throws nothisshape{
if (Atype.compareto ("square") ==0)
Return to New Square (Aname);
else if (Atype.compareto ("Circle") ==0)
return new Circle (ANAME);
else throw new Nothisshape (Atype);
}

A series of behaviors that define shape in anoperation
static void Anoperation (String aname, String atype) throws nothisshape{
s = FactoryMethod (Aname, atype);
System.out.println ("The current shape is:" + s.name);
S.draw ();
S.erase ();
}
}

2.C Test class: Here the client must specify a parameter to determine which class to create. The anoperation in this example is a static function that 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 would draw a circle.
It would erase a circle.
The current shape Is:shape two
It'll draw a square.
It'll 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 the creation process is completed in the creator, the exact type of the parameter (with instanceof) must be judged before the corresponding instance can be produced. It's a good idea to take advantage of Java's dynamic loading mechanism to do this. For example:

We get a subclass of shape s, but we don't know exactly that subclass, we can get the instance by using the method of the Class class newinstance ()

Return (Shape) S.getclass (). newinstance ();

This method is interested in readers can try, limited to space, not to write specific code out.

Something:

After reading this article, I believe that the reader has a clearer understanding of the factory method model. What I want to say is that we should not only care about what a specific model does, but also how to implement it, and we should look at the nature of the phenomenon, not only know it, We must know the reason why. We should deepen our understanding of object-oriented thinking through the study of pattern, and let our own understanding be sublimated. Factory method mode seems simple, it's deep. Abstract, encapsulation, inheritance, delegation, polymorphism, object-oriented concepts such as interface programming are shown here in one by one. It is only by grasping its essence that we can be flexible in form and not use patterns for use.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.