Design Pattern (5) prototype Pattern

Source: Internet
Author: User
Tags shallow copy

Overview

In software systems, product classes sometimes change dynamically and have a certain hierarchical structure. In this case, if the factory model is used, the factory method classes parallel to the product class hierarchy will also change with this change, which is obviously not suitable. So how can we encapsulate this dynamic change? So that the client programs dependent on these variable objects do not change with the product class?

Intention

Use a prototype instance to specify the type of the object to be created, and copy the prototype to create a new object.

 

Examples in life

In prototype mode, a prototype instance is used to specify the type of the object to be created. The prototype of a new product is usually created before all products. Such prototype is passive and does not participate in copying itself. The split of a cell produces two identical cells. This is an example of assuming an active role to copy its own prototype. This demonstrates the prototype. One Cell Division produces two cells of the same genotype. In other words, the cell clones itself.

 

Color prototype

Using system; using system. collections. generic; using system. LINQ; using system. text; namespace prototypepatterndemo {interface icolorprototype {icolorprototype clone ();} class conctetecolorprototype: icolorprototype {private int _ Red, _ Green, _ blue; // constructor, assign public conctetecolorprototype (INT red, int green, int blue) {This. _ Red = red; this. _ Green = green; this. _ Blue = blue;} public override Icolorprototype clone () {// implement the shallow copy // The memberwiseclone method creates a superficial copy by creating a new object and then copying the non-static fields of the current object to the new object. // If the field is of the value type, perform a one-bit copy of the field. If the field is of reference type, the referenced object is copied, but the referenced object is not copied. // Therefore, the original object and its counterparts reference the same object. Return (icolorprototype) This. memberwiseclone ();} public void display (string _ colorname) {console. writeline ("{0}'s RGB values are: {1}, {2}, {3}", _ colorname, _ Red, _ Green, _ blue) ;}}// public class idinfo // {// public int idnumber; // public idinfo (INT idnumber) // {// This. idnumber = idnumber; //} // public class person // {// public int age; // public string name; // public idinfo; // public person shallowcopy () // {// return (person) This. memberwiseclone (); //} // public person deepcopy () // {// Person Other = (person) This. memberwiseclone (); // Other. idinfo = new idinfo (this. idinfo. idnumber); // return other ;//}//}
Color tool main program

Using system; using system. collections. generic; using system. LINQ; using system. text; namespace prototypepatterndemo {class program {// prototype Mode Static void main (string [] ARGs) {colormanager = new colormanager (); // initialize the color colormanager ["red"] = new conctetecolorprototype (255, 0, 0); colormanager ["green"] = new conctetecolorprototype (0,255, 0 ); colormanager ["blue"] = new conctetecolorprototype (0, 0,255); colormanager ["Angry"] = new conctetecolorprototype (255, 54, 0 ); colormanager ["peace"] = new conctetecolorprototype (128,211,128); colormanager ["Flame"] = new conctetecolorprototype (211, 34, 20 ); // use the color string colorname = "red"; conctetecolorprototype C1 = (conctetecolorprototype) colormanager [colorname]. clone (); c1.display (colorname); colorname = "peace"; conctetecolorprototype C2 = (conctetecolorprototype) colormanager [colorname]. clone (); c2.display (colorname); colorname = "Flame"; conctetecolorprototype C3 = (conctetecolorprototype) colormanager [colorname]. clone (); c3.display (colorname); console. readline ();}}}

 

As you can see, the customer program can incorporate a specific product category into the system by registering the prototype instance, and dynamically create and delete the prototype at runtime. Note that in the above example, we use superficial replication. If you want to perform deep replication, You need to implement it through serialization. After the above analysis, let's think about the following questions:

1. Why prototype mode?

The essence of introducing the prototype mode is to use an existing prototype object to quickly generate the same instance as the prototype object. You have an instance A: A = new A (); now you want to generate an instance B like car1, according to the prototype mode, it should be like this: A B =. clone (); instead of creating a new a object. Through the above sentence, we can get an instance that is the same as a. Specifically, it should be that their data members are the same. The prototype mode returns an object A without using the new operation.

2. What are the benefits of introducing the prototype mode?

We can see that after the prototype mode is introduced, we no longer need a factory method class parallel to the specific product level structure, which reduces the class structure and allows the customer program to create and delete the prototype at runtime.

3. What object-oriented design principles does prototype meet?

Dependency inversion principle: in the preceding example, the colormanager only depends on the colorprototype, while the conctetecolorprototype depends on the colorprototype ), therefore, prototype satisfies the Dependency inversion principle.

 

 

 

Deep copy through serialization

Deep copy can be achieved through serialization. Abstract classes and specific classes must be labeled as serializable. The complete program added with deep copy in the above example is as follows:

Using system;

Using system. collections;

Using system. IO;

Using system. runtime. serialization;

Using system. runtime. serialization. formatters. Binary;

 

[Serializable]

Abstract class colorprototype

{

Public abstract colorprototype clone (bool deep );

}

 

[Serializable]

Class conctetecolorprototype: colorprototype

{

 

Private int _ Red, _ Green, _ blue;

 

 

Public conctetecolorprototype (INT red, int green, int blue)

{

This. _ Red = red;

This. _ Green = green;

This. _ Blue = blue;

}

Public override colorprototype clone (bool deep)

{

If (deep)

Return createdeepcopy ();

Else

Return (colorprototype) This. memberwiseclone ();

}

 

// Implement deep copy

Public colorprototype createdeepcopy ()

{

Colorprototype;

 

Memorystream = new memorystream ();

Binaryformatter formatter = new binaryformatter ();

 

Formatter. serialize (memorystream, this );

Memorystream. Position = 0;

 

Colorprototype = (colorprototype) formatter. deserialize (memorystream );

Return colorprototype;

}

 

Public conctetecolorprototype create (INT red, int green, int blue)

{

Return new conctetecolorprototype (red, green, blue );

}

 

Public void display (string _ colorname)

{

Console. writeline ("{0}'s RGB values are: {1}, {2}, {3 }",

_ Colorname, _ Red, _ Green, _ blue );

}

}

 

Class colormanager

{

Hashtable colors = new hashtable ();

Public colorprototype this [string name]

{

Get

{

Return (colorprototype) colors [name];

}

Set

{

Colors. Add (name, value );

}

}

}

 

 

Class app

{

Public static void main (string [] ARGs)

{

Colormanager = new colormanager ();

 

// Initialize the color

Colormanager ["red"] = new conctetecolorprototype (255, 0, 0 );

Colormanager ["green"] = new conctetecolorprototype (0,255, 0 );

Colormanager ["blue"] = new conctetecolorprototype (0, 0,255 );

Colormanager ["Angry"] = new conctetecolorprototype (255, 54, 0 );

Colormanager [& quot; Peace & quot;] = new conctetecolorprototype (128,211,128 );

Colormanager ["Flame"] = new conctetecolorprototype (211, 34, 20 );

 

// Use color

String colorname = "red ";

Conctetecolorprototype C1 = (conctetecolorprototype) colormanager [colorname]. Clone (false );

C1.display (colorname );

 

Colorname = "peace ";

Conctetecolorprototype C2 = (conctetecolorprototype) colormanager [colorname]. Clone (true );

C2.display (colorname );

 

Colorname = "Flame ";

Conctetecolorprototype C3 = (conctetecolorprototype) colormanager [colorname]. Clone (true );

C3.display (colorname );

 

Console. Readline ();

}

}

 

Implementation points

1. The prototype manager can be dynamically created and destroyed when the number of original types in a system is not fixed.

2. Implement the clone operation. In. net, you can use the memberwiseclone () method of the object class to realize the superficial copy of the object or achieve the deep copy through serialization.

3. The prototype mode is also used to isolate the coupling between the users of class objects and specific types (variable classes). It also requires that these "variable classes" have stable interfaces.

Effect

1. It hides a specific product class from the customer, thus reducing the number of names that the customer knows.

2. prototype mode allows the customer to integrate a specific product class into the system by registering the prototype instance only. The customer can create and delete the prototype at runtime.

3. The subclass structure is reduced. The prototype mode clones a prototype instead of requesting the factory method to create one. Therefore, it does not need a creater class level parallel to a specific product class.

4. The portotype mode provides the ability to dynamically load new functions for an application. Because prototype is highly independent, it is easy to dynamically load new features without affecting the old system.

5. The product class does not need to have any pre-determined level structure, because the prototype mode applies to any level structure.

6. The main disadvantage of prototype mode is that each class must have a clone method. In addition, this cloning method requires a comprehensive consideration of the functions of the class, which is not very difficult for the brand-new class, but it is not always easy to transform the existing class.

Applicability

The prototype mode should be used in the following cases:

1. When a system should be independent of its product creation, composition, and representation;

2. When the class to be instantiated is specified at the runtime, for example, through dynamic loading;

3. To avoid creating a factory class level parallel to the product class level;

4. When an instance of a class can only have one of several combinations of different States. Creating prototype and cloning them may be more convenient than manually instantiating this type with the appropriate state each time.

Summary

The prototype mode is the same as the factory mode. It also hides the object creation work for the customer. However, unlike constructing a new object by instantiating a class, the prototype creates a new object by copying an existing object to isolate the coupling relationship between the user of the class object and the specific type (variable type.

 

| -- Icolorprototype clone (); returns a light copy or a deep copy object.
| -- Conctetecolorprototype: icolorprototype

 

 

 

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.