Cloning of six objects of creative pattern -- prototype pattern

Introduction and implementation of prototype Manager

Prototype manager is a factory that stores multiple prototype objects in a collection for clients to use. It is specifically responsible for cloning objects. A collection is defined to store prototype objects. If a clone of a prototype object is needed, it can be obtained by copying the corresponding prototype object in the collection. Program the Abstract prototype class in the prototype manager for extension. Its structure is shown in the figure:

 

The above figure shows the prototype mode with prototype manager

Next, the design and implementation of the prototype manager are introduced by simulating a simple document manager: Sunny software company needs to create, submit and approve many documents in its daily office, such as feasibility analysis report, project proposal, software requirements specification, project progress report, etc. in order to improve work efficiency, templates are created for all kinds of documents in the OA system, Users can quickly create new official documents through these templates. These official document templates need to be managed uniformly. The system generates different new official documents according to different user requests.

We use the prototype mode with prototype manager to realize the design of document manager. Its structure is shown in the figure:

 

 

Structure diagram of document manager

The following are some core codes to realize this function. Considering the readability of the code, we have simplified all classes:

//Abstract document interface can also be defined as an abstract class to provide clone()Method, which declares the business method as an abstract method
interface OfficialDocument extends Cloneable{
    public OfficialDocument clone();
    public void display();
}
//Feasibility analysis report(Feasibility Analysis Report)class
class FAR implements OfficialDocument {
        public OfficialDocument clone() {
            OfficialDocument far = null;
            try {
                far = (OfficialDocument) super.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println("Copy is not supported!");
            }
            return far;
        }

        public void display() {
            System.out.println("<Feasibility analysis report");
        }
  }
//Software requirements specification(Software Requirements Specification)class
class SRS implements OfficialDocument {
        public OfficialDocument clone() {
            OfficialDocument srs = null;
            try {
                srs = (OfficialDocument) super.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println("Copy is not supported!");
            }
            return srs;
        }

        public void display() {
            System.out.println("<Software requirements specification");
        }
}
//Prototype Manager (implemented with hungry Han style singleton) 
class PrototypeManager {
        //Define a Hashtable,Used to store prototype objects
        private Hashtable ht = new Hashtable();
        private static PrototypeManager pm = new PrototypeManager();

        //by Hashtable Add document object
        private PrototypeManager() {
            ht.put("far", new FAR());
            ht.put("srs", new SRS());
        }

        //Add a new document object
        public void addOfficialDocument(String key, OfficialDocument doc) {
            ht.put(key, doc);
        }

        //Obtain new document objects through shallow cloning
        public OfficialDocument getOfficialDocument(String key) {
            return ((OfficialDocument) ht.get(key)).clone();
        }

        public static PrototypeManager getPrototypeManager() {

            return pm;
        }
 }            

The client code is as follows:

class Client {
     public static void main(String args[]) {
            //Get prototype manager object
            PrototypeManager pm = PrototypeManager.getPrototypeMa

            OfficialDocument doc1, doc2, doc3, doc4;

            doc1 = pm.getOfficialDocument("far");
            doc1.display();
            doc2 = pm.getOfficialDocument("far");
            doc2.display();
            System.out.println(doc1 == doc2);

            doc3 = pm.getOfficialDocument("srs");
            doc3.display();
            doc4 = pm.getOfficialDocument("srs");
            doc4.display();
            System.out.println(doc3 == doc4);
        }
}

Compile and run the program, and the output results are as follows:

<Feasibility analysis report
<Feasibility analysis report
false
<Software requirements specification
<Software requirements specification
false

 

A collection object of Hashtable type is defined in the PrototypeManager. The prototype object is stored by "Key value pair". The client can obtain the clone object of the corresponding prototype object through the Key (such as "far" or "srs"). The PrototypeManager class provides a factory like getOfficialDocument() method to return a cloned object. In this example code, we design PrototypeManager as a singleton class and use hungry man singleton implementation to ensure that there is and only one PrototypeManager object in the system, which is conducive to saving system resources and better controlling the prototype manager object.

 

Prototype model summary

As a way to quickly create a large number of identical or similar objects, prototype mode is widely used in software development. The copy (Ctrl + C) and paste (Ctrl + V) operations provided by many software are typical applications of prototype mode. The use effect and application of this mode are briefly summarized below.

The main advantages of the prototype model are as follows:

(1) When creating a new object instance is complex, using the prototype pattern can simplify the object creation process, and the creation efficiency of a new instance can be improved by copying an existing instance.

(2) The extensibility is good. Because the Abstract prototype class is provided in the prototype mode, the Abstract prototype class can be programmed on the client, and the specific prototype class can be written in the configuration file. Adding or reducing product classes has no impact on the original system.

(3) The prototype pattern provides a simplified creation structure. The factory method pattern often needs a factory hierarchy that is the same as the product class hierarchy, but the prototype pattern does not need this. The replication of products in the prototype pattern is realized through the cloning method encapsulated in the prototype class, and there is no need for a special factory class to create products.

(4) You can use deep cloning to save the state of the object, and use prototype mode to copy the object and save its state for use when needed (such as restoring to a historical state), which can assist in the implementation of undo operation.

 

The main disadvantages of the prototype model are as follows:

(1) Each class needs to be equipped with a cloning method, and the cloning method is located inside a class. When transforming an existing class, the source code needs to be modified, which violates the "opening and closing principle".

(2) When implementing deep cloning, you need to write more complex code, and when there are multiple nested references between objects, in order to implement deep cloning, the classes corresponding to each layer of objects must support deep cloning, which may be troublesome.

 

For applicable scenarios, the prototype mode can be considered in the following cases:

(1) The cost of creating new objects is high (for example, initialization takes a long time and takes too much CPU resources or network resources). New objects can be obtained by copying existing objects in the prototype mode. If they are similar objects, their member variables can be slightly modified.

(2) If the system wants to save the state of the object, and the state change of the object is very small, or the object itself occupies less memory, it can be realized by using prototype mode and memo mode.

(3) It is necessary to avoid using hierarchical factory classes to create hierarchical objects, and the instance object of the class has only one or few combined states. It may be more convenient to get a new instance by copying the prototype object than using the constructor.

 

Tags: Design Pattern

Posted by drfate on Thu, 12 May 2022 10:52:12 +0300