Design Pattern-Detailed Explanation of Prototype Pattern

Preface

  • Introduction to design patterns
  • Design patterns are solutions to common problems in software development. They are reusable design ideas and solutions summarized through practice and experience. Design patterns help developers write high-quality code more efficiently by providing common structures, principles, and guidance.
    Design patterns are divided into three main categories:
  1. Creational pattern: focuses on the creation process of objects, including how to instantiate objects, hiding the details of object creation, and copying and cloning objects.
  2. Structural patterns: Focus on the way objects and classes are combined to achieve the goal of a larger structure, such as the relationships between classes.
  3. Behavioral patterns: focus on how classes and objects interact and communicate to achieve better collaboration and control.
  • Introduction to Prototype Pattern
    Prototype pattern is a type of creational pattern that focuses on copying and cloning objects. In some cases, creating new objects through traditional instantiation can be prohibitively expensive or complex. At this time, the prototype pattern provides an alternative method to create new objects by cloning existing objects, thus avoiding the expensive initialization process.

The prototype pattern can save resources and time and improve the efficiency of object creation by using the cloning method to generate new objects. It is suitable for scenarios where a large number of similar objects need to be created. It also has good scalability and can implement customized cloning logic by inheriting and overriding the cloning method as needed.

To summarize, the prototype pattern is a design pattern that creates new objects by cloning existing objects. It provides a flexible and efficient way to create objects, which can significantly improve code reusability and maintainability in certain scenarios.
Insert image description here

Theoretical basis

1. Prototype pattern definition

Prototype pattern is a creational design pattern that allows new objects to be created by cloning existing objects without relying on the traditional instantiation process. This pattern creates a new independent object by copying the properties and state of an existing object, and its specific properties can be modified as needed.

In prototype pattern, we define an abstract prototype class which contains an abstract method for cloning an object. The concrete prototype class inherits from the abstract prototype class and implements the clone method to return a cloned copy of itself. Client code uses an instance of the concrete prototype class and calls its clone method to create a new object.

The key idea of ​​the prototype pattern is to create new objects from existing objects rather than starting a new instantiation process from scratch. By cloning existing objects, you can avoid repeated initialization work and resource consumption, and improve the efficiency of object creation. At the same time, the prototype mode also makes the creation of objects more flexible and can be modified and customized as needed.

2. Prototype role

  • abstract prototype class
  • concrete prototype class
  • client

3. Working process of prototype mode

4. Advantages and Disadvantages of Prototype Pattern

Practical application

1. Applicable scenarios of prototype mode

  • The object initialization process takes more time
  • Class initialization consumes a lot of resources
  • Creating objects through new is more complicated
  • Need to avoid using subclasses of classes for initial configuration

2. Prototype pattern implementation steps

  • Create abstract prototype class
  • Create concrete prototype class
  • Create client class

3. The difference between prototype pattern and singleton pattern

Variations of Prototype Pattern

1. Prototype pattern with prototype manager

  • Prototype pattern with prototype manager:
    Prototype pattern with prototype manager is an extension of prototype pattern. It introduces a prototype manager (Prototype Manager) to centrally manage prototype objects. The prototype manager acts as a registry for storing and retrieving various prototype objects.

This variant of the prototype pattern makes it easier to create and manage multiple prototype objects of different types. The client can obtain the required prototype object through the prototype manager without explicitly calling the clone method. The prototype manager can internally maintain a collection of prototype objects, copying and returning them as needed.

  • Prototype pattern code implementation with prototype manager:
import java.util.HashMap;
import java.util.Map;

// 原型接口
interface Prototype {
    
    
    Prototype clone();
}

// 具体原型类 A
class ConcretePrototypeA implements Prototype {
    
    
    private String name;

    public ConcretePrototypeA(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeA(this.name);
    }
}

// 具体原型类 B
class ConcretePrototypeB implements Prototype {
    
    
    private int number;

    public ConcretePrototypeB(int number) {
    
    
        this.number = number;
    }

    public int getNumber() {
    
    
        return number;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeB(this.number);
    }
}

// 原型管理器
class PrototypeManager {
    
    
    private Map<String, Prototype> prototypes;

    public PrototypeManager() {
    
    
        prototypes = new HashMap<>();
    }

    public void registerPrototype(String key, Prototype prototype) {
    
    
        prototypes.put(key, prototype);
    }

    public Prototype getPrototype(String key) {
    
    
        Prototype prototype = prototypes.get(key);
        if (prototype != null) {
    
    
            return prototype.clone();
        }
        return null;
    }
}

// 客户端
public class Main {
    
    
    public static void main(String[] args) {
    
    
        PrototypeManager manager = new PrototypeManager();
        manager.registerPrototype("A", new ConcretePrototypeA("Prototype A"));
        manager.registerPrototype("B", new ConcretePrototypeB(10));

        Prototype prototypeA = manager.getPrototype("A");
        if (prototypeA != null) {
    
    
            System.out.println("Clone A: " + ((ConcretePrototypeA) prototypeA).getName());
        }

        Prototype prototypeB = manager.getPrototype("B");
        if (prototypeB != null) {
    
    
            System.out.println("Clone B: " + ((ConcretePrototypeB) prototypeB).getNumber());
        }
    }
}

2. Implementation of prototype pattern of lazy singleton pattern

  • The prototype pattern of the lazy singleton pattern:
    The lazy singleton pattern is a common way to implement the singleton pattern, which delays the instantiation of the singleton object until it is created for the first time. Combining the lazy singleton pattern with the prototype pattern can achieve a pattern of lazy loading and reuse of instances.

In this variant of the prototype pattern, the singleton object acts as the prototype object and when the client first requests for an instance, a copy of the object is obtained through cloning and returned as a singleton object. After that, each request will return this existing copy, avoiding repeated creation and initialization processes.

This implementation method combines lazy loading and object reuse, and can dynamically create new objects and cache them when needed, improving system performance and resource utilization.

  • Prototype pattern code implementation of lazy singleton pattern:
// 单例类
class Singleton {
    
    
    private static Singleton instance;

    // 私有构造函数
    private Singleton() {
    
    
        System.out.println("Singleton instance created.");
    }

    // 获取单例对象
    public static Singleton getInstance() {
    
    
        if (instance == null) {
    
    
            synchronized (Singleton.class) {
    
    
                if (instance == null) {
    
    
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    // 克隆方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
    
    
        throw new CloneNotSupportedException("Cannot clone a singleton object.");
    }
}

// 客户端
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        System.out.println("Singleton 1: " + singleton1);
        System.out.println("Singleton 2: " + singleton2);

        // 尝试克隆单例对象
        try {
    
    
            Singleton clone = (Singleton) singleton1.clone();
            System.out.println("Clone: " + clone);
        } catch (CloneNotSupportedException e) {
    
    
            System.out.println(e.getMessage());
        }
    }
}

3. Fine-grained prototype mode

  • Fine-grained prototype pattern:
    The fine-grained prototype pattern refers to splitting a complex object into multiple parts and creating corresponding prototype objects for each part. In this way, when you need to use a certain part, you only need to clone the prototype object of that part, instead of cloning the entire complex object.

Fine-grained prototyping patterns can improve system flexibility and efficiency. It allows the client to select the required parts for cloning without cloning the entire object. At the same time, when a certain part changes, only the corresponding prototype object needs to be modified instead of recreating the entire object.

This pattern is suitable for complex objects that are composed of multiple components or modules. Through fine-grained prototype objects, components of complex objects can be constructed and modified more flexibly, reducing code duplication and coupling.

  • Fine-grained prototype pattern code
// 原型接口
interface Prototype {
    
    
    Prototype clone();
}

// 具体原型类 A
class ConcretePrototypeA implements Prototype {
    
    
    private String name;

    public ConcretePrototypeA(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeA(this.name);
    }
}

// 具体原型类 B
class ConcretePrototypeB implements Prototype {
    
    
    private int number;

    public ConcretePrototypeB(int number) {
    
    
        this.number = number;
    }

    public int getNumber() {
    
    
        return number;
    }

    @Override
    public Prototype clone() {
    
    
        return new ConcretePrototypeB(this.number);
    }
}

// 客户端
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Prototype prototypeA = new ConcretePrototypeA("Prototype A");
        Prototype cloneA = prototypeA.clone();
        if (cloneA instanceof ConcretePrototypeA) {
    
    
            System.out.println("Clone A: " + ((ConcretePrototypeA) cloneA).getName());
        }

        Prototype prototypeB = new ConcretePrototypeB(10);
        Prototype cloneB = prototypeB.clone();
        if (cloneB instanceof ConcretePrototypeB) {
    
    
            System.out.println("Clone B: " + ((ConcretePrototypeB) cloneB).getNumber());
        }
    }
}

Summarize

  • Summary of using prototype mode
  • The Importance of Prototype Pattern for Software Development
// 抽象原型类
abstract class Prototype implements Cloneable {
    
    
    public abstract Prototype clone();
}

// 具体原型类
class ConcretePrototype extends Prototype {
    
    
    @Override
    public Prototype clone() {
    
    
        try {
    
    
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
    
    
            e.printStackTrace();
            return null;
        }
    }
}

// 客户端
public class Client {
    
    
    public static void main(String[] args) {
    
    
        ConcretePrototype prototype = new ConcretePrototype();
        ConcretePrototype clone = (ConcretePrototype) prototype.clone();
        // 进行操作
    }
}

The above code shows a simple implementation of the prototype pattern, in which the abstract prototype class defines an abstract method clone, which is implemented in the concrete prototype class, and the object is cloned by calling the super.clone() method. In the client, you can create a prototype object and clone it to get a new object for operation.

The prototype mode is suitable for scenarios where a large number of similar objects need to be created, and efficiency can be improved by cloning existing objects. It simplifies the object creation process and reduces repeated initialization operations. At the same time, the prototype mode also has good scalability, and custom cloning logic can be implemented by inheriting and overriding the clone method.

In general, the prototype pattern is a simple and practical design pattern that has wide application value in software development. By rationally using the prototype pattern, the reusability, maintainability and flexibility of the code can be improved, thereby improving the efficiency and quality of software development.

Guess you like

Origin blog.csdn.net/pengjun_ge/article/details/132591678
Recommended