Factory pattern)

Source: Internet
Author: User
Tags define abstract getcolor new set

1. What is the factory model?

1. "Simple factory mode", simple factory pattern

That is, it is commonly used to define static methods in the factory class to take charge of the new object method.

The abstract mentions that "strictly speaking, this method called" simple factory mode "cannot be called" Mode "at all, although the static factory method is not a real" design mode ", however, this method is also widely used and can also bring some benefits, so we cannot discard it because it is not a "Design Pattern.

2. Factory method pattern

Is the core of the factory Model

Define an abstract "Factory method" to take charge of the new object. The extension class of this class is used to implement the new process.

This method successfully separates the object creation process from the object behavior (not to be explained at the moment), specifically to create an object"Decentralization"To the subclass. (Note the verb "decentralization" here ")

3. abstract factory pattern

Is an application and extension of the factory method model.

Encapsulate multiple "factory methods" in an abstract factory class to achieve the goal of "a new set of objects"

II. General mode (no factory Mode)

To open a store to sell clothes, we first need the colthesstore class to receive the order and return the prepared clothes. The clothesstore class must depend on the clothes class. After all, the specific object to be operated is clothes, in clothesstore, there is also a process for making clothes (making, processing, and decorating ..)

Then our clothesstore will be like this:

Package factorypattern;/*** @ author ayqy * directly create a specific object **/public class clothesstore {string type; // define clothes; // clothes object/*** @ author ayqy * defines the internal class clothes **/class clothes {string type; // type string DESC; // describes the string cloth; // cloth public clothes (string type, string DESC, string cloth) {This. type = type; this. desc = DESC; this. cloth = cloth;} Public String tostring () {return type + "," + DESC + "," + cloth;} public clothesstore (string type) {This. type = type;}/*** @ return unfinished clothes */private clothes createclothes (string type) {If (type. equals ("coat") {return new clothes ("coat", "a nice coat", "linen");} else if (type. equals ("underwear") {return new clothes ("underwear", "comfortable underwear", "cotton");} elsereturn NULL ;} /*** @ return the prepared clothes */Public clothes getclothes () {clothes = createclothes (type); decorate (clothes); // return clothes for clothes decoration ;} private void decorate (clothes) {// Add decoration (pattern, pattern, etc.) to clothes system. out. println ("carefully decorated, clothes become more beautiful ");}}

P.s. The Code defines clothes as an internal class, just to save space and simplify the structure, the effect is the same

We found that clothesstore has a strong dependence on clothes (it is not a good thing to rely too much on "specifics ..), Once clothes changes (if new member variables and member functions exist), our clothesstore may have to be modified, especially for the new clothes object:

/*** @ Return: undecorated clothes */private clothes createclothes (string type) {If (type. equals ("coat") {return new clothes ("coat", "a nice coat", "linen");} else if (type. equals ("underwear") {return new clothes ("underwear", "comfortable underwear", "cotton");} elsereturn NULL ;}

Once a new type is available, we need to add an else if to cope with the change.

Besides, because clothesstore is bound with a specific clothes class, clothesstore is not easy to expand and is difficult to reuse.

3. "Simple factory model"

Move the createclothes method to clothesfactory as a static factory method, like this:

Package factorypattern. simplefactorypattern; /*** @ author ayqy * defines the static factory method **/public class clothesfactory {/*** @ return returns undecorated clothes */public static clothes createclothes (string type) {If (type. equals ("coat") {return new clothes ("coat", "a nice coat", "linen");} else if (type. equals ("underwear") {return new clothes ("underwear", "comfortable underwear", "cotton") ;}elsereturn NULL ;}}

P.s. This time, clothes must be taken out as an independent class (internal classes cannot be accessed). In addition, the getclothes method in clothesstore must be changed accordingly .. Don't care about these details

After the simple factory model is applied, we did separate the part of the new object. The advantages of doing so are:

When clothes changes, we can directly modify the create method in clothesfactory, instead of searching for the create part in clothesstore's long code.

In addition, compared with the previous "general method", the Code has almost no changes, so it is easy to change the previous code to the code after the simple factory mode of application, so many developers like this method.

-------

The "simple factory model" is not a real factory model, and its advantages are extremely limited. But it doesn't matter. We also have a factory method model. This is a real factory model.

Iv. Factory method mode

Define the abstract "Factory method" for specific implementation. The new clothesstore will be like this:

Package factorypattern. factorymethodpattern;/*** @ author ayqy * use the factory method mode to define abstract factory methods for new products **/public abstract class clothesstore {string type; // define the clothing type clothes; // The clothing object public clothesstore (string type) {This. type = type;} // define the factory method. The extension class is used to implement the specific production details public abstract clothes createclothes (string type ); /*** @ return the prepared clothes */Public clothes getclothes () {clothes = createclothes (type); decorate (clothes); // return clothes for clothes decoration ;} private void decorate (clothes) {// Add decoration (pattern, pattern, etc.) to clothes system. out. println ("carefully decorated, clothes become more beautiful ");}}

We found that clothesstore became abstract, which encapsulates the clothes production process and implementation details, but did not implement the create process.

The next step is to expand the clothesstore class and implement the specific create details, as shown in the following figure:

Package factorypattern. factorymethodpattern;/*** @ author ayqy * extension clothesstore to implement specific creation details **/public class defaultclothesstore extends clothesstore {public defacloclothesstore (string type) {super (type );} /** Implementation Details */@ overridepublic clothes createclothes (string type) {If (type. equals ("coat") {return new clothes ("coat", "a nice coat", "linen");} else if (type. equals ("underwear") {return new clothes ("underwear", "comfortable underwear", "cotton") ;}elsereturn NULL ;}}

Well, now we have successfully applied the factory method model. Let's take a look at the features of this genuine factory model compared to the previous simple factory model.

1. It also realizes the separation of the specific process of the new object and the object behavior, but the difference is that we implement it by using inheritance (Extension), that is,"Decentralization"(Put the specific implementation at a lower class level)

2. Each specific store must implement its own create details, but it can also use the base-class store production process (decorate method, etc)

3. An Abstract Factory method easily implements the factory model (even the factory did not appear from start to end, but we have already implemented the "Factory", didn't we ?)

V. Abstract Factory Model

Abstract Factory mode is an extension of the previous method. We can only create one product on it, but many times we need to create a group of products, such as clothing raw materials, including fabrics, dyes, cables, buttons, etc. At this time, the abstract factory model needs to be used for implementation:

Package factorypattern. abstractfactorypattern;/*** @ author ayqy * define the raw material factory **/public abstract class resourcesfactory {public abstract cloth getcloth (); // obtain the public abstract color getcolor () of the cloth (); // get the dye public abstract button getbutton (); // get the button // other required factory methods}

The types in the abstract factory are all custom interfaces, for example:

Package factorypattern. abstractfactorypattern;/*** @ author ayqy * defines the cloth interface */public interface cloth {// attributes/behavior}

With the raw material factory, clothesstore should also make corresponding changes to adapt to this new structure:

Package factorypattern. abstractfactorypattern;/*** @ author ayqy * extends clothesstore to implement specific creation details **/public class defaultclothesstore extends clothesstore {public defacloclothesstore (string type, resourcesfactory res) {super (type, type, res);}/** Implementation Details */@ overridepublic clothes createclothes (string type) {If (type. equals ("coat") {// obtain the required material cloth = res. getcloth (); color = res. getcolor (); button = res. getbutton (); // make clothes return new clothes ("coat", color. tostring () + button. tostring (), Cloth. tostring ();} else if (type. equals ("underwear") {// obtain the required raw material cloth = res. getcloth (); color = res. getcolor (); button = res. getbutton (); // make clothes return new clothes ("underwear", color. tostring () + button. tostring (), Cloth. tostring ();} elsereturn NULL ;}}

When creating a store object, you need a specific resourcesfactory parameter (the raw material factory implements all the getxxx factory methods). The specific store is only responsible for the specific production process, all required materials can be obtained from resourcefactory. After the specific store is made of clothes, the store base class is responsible for the process processing (decorate method, etc.), and finally the finished clothes are returned by the specific store.

The entire structure is loose, low coupling, and easy to expand

-------

In addition, it is necessary to mention an OO design principle-"Dependency inversion principle"

By observing the class structure, we can find that:

High-level component store depends on clothes, and the low-level component resourcesfactory also depends on clothes (this is "Dependency inversion", that is, the low-level component is dependent on the High-level component in turn, and the high-level component is dependent on abstraction)

Such a design has the advantage of high scalability (abstraction means scalability ..)

V. Summary

In fact, the first part of the opening section is a summary. Here we should emphasize that everything has two sides. A good thing must have disadvantages, and the design model is no exception.

The abstract factory model looks really good, but it also has a fatal drawback: structural complexity caused by multi-level abstraction

Factory pattern)

Related Article

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.