2.1 Modal Motivation

In some systems, there is the problem of creating a large number of identical or similar objects. If we use traditional constructors to create objects, it will be complicated and time-consuming, and it is very efficient to use prototype mode to generate objects, just like the Monkey King pulling out the monkey hair and blowing it into a lot of Sun Wukong.

Figure 1

Again one of the most simple example to illustrate the prototype pattern: remember when in elementary school, the teacher needs to be done to the blackboard to write the extracurricular exercises, and we all want to put these questions below copy to your notebook, ready to home, hand in the second day, namely each question, whole class 50 people, everyone has to copy it again. According to the current theory of time, that’s 50 people’s time wasted. However, at that time, the conditions are limited, and the teacher is forced to do it. Now, the teacher makes an electronic copy of the problem set, prints out a copy, and then takes the original print and makes 50 copies.

The teacher printed out the “prototype”, and the 50 copies were used as “copies”. The prototype model is as simple as this: take what you have and copy it.

Okay, now, let’s move on to the theory.

2.2 Definition and characteristics of the mode

Design Patterns: The Foundation of Reusable Object-oriented Software says that you specify what kind of objects to create with prototype instances, and create new objects by copying those prototypes.

The Prototype pattern is defined as follows: Use an already created instance as a Prototype and create a new object that is identical or similar to the Prototype by copying the Prototype object. Here, the prototype instance specifies the kind of object to be created. Creating objects this way is very efficient, and you don’t need to know the details of object creation at all. For example, Windows installation is usually time consuming, and replication is much faster. There are many examples of copying in life, and I will not list them here.

The prototype pattern is simply a way to copy yourself. This pattern is easy to understand. The unique aspect of this pattern is not the relationship between classes, but the semantic understanding, just the implementation of an interface.

2.3 Structure and implementation of the mode

2.3.1 Pattern structure

The archetypal pattern contains the following primary roles.

Queue Abstract Stereotype class: Specifies the interface that a concrete stereotype object must implement. Virtual prototype classes: Implement a Clone () method for an abstract prototype class, which is an object that can be copied. A class is accessed using the Clone () method in a concrete prototype class to copy a new object.

Its structure is shown in Figure 2.

Figure 2. Structure diagram of the prototype pattern

Cloning requires a Prototype, and Prototype in the above class diagram is the Prototype. Prototype defines the Clone interface, which is implemented by derived classes. The focus of the Prototype mode is the implementation of the Clone interface. ConcretePrototype1 and ConcretePrototype2 inherit from the Prototype class and implement the Clone interface to Clone itself. Meanwhile, the default copy constructor needs to be overridden in the ConcretePrototype1 and ConcretePrototype2 classes for the Clone function to call, which is done internally by calling the overridden copy constructor. Later in the coding process, if a class needs to implement Clone functionality, it simply inherits the Prototype class and overrides its default copy constructor. For example, the clone interface is provided in C# and Java equal. When a class needs to implement the stereotype pattern, it only needs to implement this interface. No matter what object-oriented language you use, the idea is the same. What we are studying here is the mind.

2.3.2 Implementation of the pattern

/**Includes*********************************************************************/
#include <iostream>

/**namespace********************************************************************/
using namespace std;

/ / interface
class Prototype
{
public:
    Prototype() {}virtual ~Prototype() {}virtual Prototype *Clone(a)=0;
};

/ / implementation
class ConcretePrototype_1 : public Prototype
{
public :
    ConcretePrototype_1() :m_counter(1) {}// Copy the constructor
    ConcretePrototype_1( int counter)
    {
        this->m_counter = counter;
    }

    // Copy itself
    virtual Prototype * Clone(a)
    {
        // Call the copy constructor
        return new ConcretePrototype_1(*this );
    }
    void Show(a)
    {
        cout << this->m_counter << endl;
    }

    virtual ~ConcretePrototype_1() {}private :
    int m_counter;
};

/ / implementation
class ConcretePrototype_2 : public Prototype
{
public :
    ConcretePrototype_2() :m_counter(2) {}// Copy the constructor
    ConcretePrototype_2(int counter)
    {
        m_counter = counter;
    }

    // Copy itself
    virtual Prototype * Clone(a)
    {
        // Call the copy constructor
        return new ConcretePrototype_2 (*this );
    }

    void Show(a)
    {
        cout << this->m_counter << endl;
    }

    virtual ~ConcretePrototype_2() {}private :
    int m_counter;
};

/** * @brief main function * @param argc argv * @retval None */
int main(int argc, char *argv[])
{
    ConcretePrototype_1 * p1 = new ConcretePrototype_1(a); ConcretePrototype_2 * p2 = (ConcretePrototype_2 *)(p1->Clone());

	p1->Show(a); p2->Show(a);delete p1;
	delete p2;

    return 0;
}
Copy the code

The result is as follows:

The code above implements the simplest prototype pattern, but has already shown the basic implementation principles of the prototype pattern. In other cases, when Clone is called and the object state needs to be changed, an Initialize operation may be added to the ConcretePrototype class to Initialize the cloned object. The copy constructor is called inside Clone, and deep and shallow copies are involved. Therefore, in the process of actual operation, these problems need to be carefully considered.

2.4 Application Scenarios of Mode

The prototype pattern, like the Builder pattern and the factory method pattern, is a kind of creation pattern. In simple terms, we use the prototype pattern to create objects. However, using the prototype pattern is best in the following scenarios:

  • It is easier to clone a new object from an object of that type when the object type is determined at run time rather than at the beginning.
  • Sometimes we need a copy of an object in a certain state, and prototyping is the best choice. For example: an object, after a period of processing, its internal state changes; At this point, we need a copy of this state, if directly new a new object, but its state is not correct, in this case, we can use the prototype mode, copy the original object, the object is exactly the same as the previous object;
  • When we deal with some relatively simple objects, and the differences between objects are very small, maybe just a few different properties, then we can use the prototype mode to complete, save the trouble of creating objects;
  • Sometimes, when you’re creating an object with a lot of parameters in the constructor and you don’t fully know what each parameter means, you can use the prototype pattern to create a new object and forget about the creation process.

Therefore, in the above case, in the design, appropriate consideration of the prototype mode, reduce the corresponding workload, reduce the complexity of the program, improve efficiency.

2.5 Schema extensions

The stereotype pattern is extensible to a stereotype pattern with a stereotype manager, which adds a stereotype manager PrototypeManager class to the stereotype pattern. This class holds multiple replicated stereotypes using a HashMap from which the Client class can retrieve the replicated stereotypes via the manager’s GET (String ID) method. Its structure is shown in Figure 3.

Figure 3 structure diagram of a stereotype pattern with stereotype manager

2.6 summarize

The factory method pattern, the Abstract factory pattern, the Builder pattern, and the prototype pattern are all creative patterns. Factory method mode is suitable for production is more complex, a factory produces a single product when; Abstract factory model is suitable for a factory to produce multiple interdependent products; The Builder mode focuses on the process of creating complex objects step by step, assembling products, and controlling the creation of each simple object during the creation process. The archetypal pattern is more about copying yourself from yourself, creating objects that look exactly like you.

As one of the most special creation patterns in the prototype pattern, the specific creation process is provided by the object itself, so that we can easily and quickly build new objects in many scenarios. However, the biggest disadvantage of the stereotype pattern is that all subclasses that inherit the stereotype have to implement the Clone operation, which is very difficult. For example, it is difficult to add a Clone operation when the class in question already exists. Cloning can also be difficult when internal objects include objects that do not support copying or have circular references. In order to say, every design mode has its advantages and disadvantages, in the design, we need to weigh the factors of all aspects, to maximize the strengths and avoid the weaknesses.