04. Prototype Pattern Design Ideas
Catalog Introduction
- 01. Introduction to the Prototype Pattern
- 1.1 Origin of the prototype model
- 1.2 Prototype Model Definition
- 1.3 Prototype model scenarios
- 1.4 Reflections on the prototype model
- 02. Principles and Implementation of Prototype Patterns
- 2.1 List a scenario
- 2.2 Understanding Prototypes with Examples
- 2.3 Analysis of case evolution
- 2.4 Basic realization of the prototype model
- 03. Prototype Pattern Analysis
- 3.1 Prototype Pattern vs Factory Pattern
- 3.2 Prototype Mode vs Deep Copy
- 04. Explanation of the application of the prototype pattern
- 4.1 Using the clone method
- 4.2 Implementing the interface Cloneable
- 4.3 Deep and shallow cloning
- 05. Prototype Pattern Summary
- 5.1 Analysis of advantages and disadvantages
- 5.2 What are the disadvantages
- 5.3 Description of the application environment
- 06. Prototype Patterns Expanded Applications
- 6.1 Schema extensions
- 6.2 Summary of the prototype model
- 6.3 More content recommendations
01. Introduction to the Prototype Pattern
1.0 AI-generated blog summaries
This article describes in detail the design ideas of the prototype pattern, including its definition, application scenarios, implementation principles and advantages and disadvantages. Through the example of email cloning, it explains how the prototype pattern can improve performance and reduce code complexity by cloning existing objects to create new ones. The article also compares the difference between the prototype pattern and the factory pattern, and discusses the implementation of deep cloning and shallow cloning. Finally, it summarizes the value and limitations of the application of the prototype pattern in specific scenarios.
1.1 Origin of the prototype model
Let's look at an example - mail. As the mail object contains more content (such as sender, receiver, title, content, date, attachments, etc.), a system now need to provide a mail copy function, for the mail object has been created, you can copy the way to create a new mail object, if you need to change the content of a certain part of the original mail object without modifying the content of the original mail object, you only need to modify the copy of the mail object can be obtained.
If you rewrite this code every time you copy it, you can imagine how complex it is, so this time you need to encapsulate a base class to encapsulate all of these assignment processes, which shows that the prototype pattern utilizes nothing more than object-oriented programming encapsulation, inheritance features.
1.2 Prototype Model Definition
The prototype pattern is used to create more objects of the same type by giving a prototype object that specifies the type of the object being created, and then using its own implementation of the cloning interface to duplicate the prototype object.
Creating new objects in this way eliminates the need for new instantiation. This is because the clone method of the Object class is a native method that operates directly on the binary stream in memory, so it has better performance than new instantiation.
The prototype pattern basically works by passing a prototype object to the object that is to be created, and the object that is to be created realizes the creation process by requesting the prototype object to copy the prototype itself.
1.3 Prototype model scenarios
The prototype model is particularly useful in the following situations:
- When the object creation process is complex or time-consuming, performance can be improved by copying existing objects.
- The prototype pattern can be used when there is a need to create multiple similar objects, but you don't want to be coupled with their concrete classes.
Scenarios of application of the prototype pattern, and its two implementations: deep copy and shallow copy. Although the principle and code implementation of the prototype pattern is very simple.
1.4 Reflections on the prototype model
Provides a flexible way to create objects by copying existing objects to create new objects, thus avoiding the expensive process of object creation. The core idea of the pattern is to create new objects by copying existing objects, rather than by instantiating classes.
02. Principles and Implementation of Prototype Patterns
2.1 List a scenario
apprehendEmail example codeFor example, due to the presentation, we encapsulate three fields in the email: the title, the content and the attachment, where the attachment is a class containing the name, the type and the file size.
First use the default clone method (shallow cloning), that is, the attachment in the copied email is the same object as the attachment in the original email; then realize deep cloning, that is, the attachment in the copied email is not the same object as the attachment in the original email.
2.2 Understanding Prototypes with Examples
1. Base class - to facilitate the subclass call clone does not need to catch exceptions
public class Prototype implements Cloneable {
public Prototype cloneMe() {
Prototype prototype = null;
try {
prototype = (Prototype) ();
} catch (CloneNotSupportedException exception) {
}
return prototype;
}
}
2. Annex subcategories
public class Attachment extends Prototype {
// Attachment name
private String name;
// Attachment Document Type
private String type;
// Attachment size
private long length;
public Attachment(String name, String type, long length) {
super();
= name;
= type;
= length;
}
public void download() {
("Downloaded the attachment:" + name);
}
public String display() {
return "Attachment [name=" + name + ", type=" + type + ", length=" + length + "]";
}
@Override
public boolean equals(Object obj) {
Attachment a = (Attachment) obj;
if((name) && (type) && == length) {
return true;
}
return false;
}
}
3. Mail subclass
public class Email extends Prototype {
// caption
private String title;
// element
private String content;
// attachment (email)
private Attachment attachment;
public Email(String title, String content, Attachment attachment) {
super();
= title;
= content;
= attachment;
}
public String display() {
return "Email [title=" + title + ", content=" + content + ", attachment=" + ();
}
public Attachment getAttachment() {
return attachment;
}
@Override
public boolean equals(Object obj) {
Email e = (Email) obj;
if((title) && (content) && (attachment)) {
return true;
}
return false;
}
}
4. Client Class
private void test() {
Email email = new Email("Email Title", "Email Content, hahaha..." , new Attachment("Attachment Header", "Document", 45987));
(());
Email copyEmail = (Email) ();
("Email copy status: " + (email ! = copyEmail && (copyEmail) ? "Success" : "Failure") ); ("Email copy status: " + (email ! = copyEmail && (copyEmail) ?
Attachment attachment = ();
Attachment copyAttachment = ();
if((copyAttachment)) {
("Mail attachment content is consistent");
}
if(attachment == copyAttachment) {
("The email attachment was not copied"); }
} else {
("The email attachment was copied"); }
}
}
The final run results are shown below:
Email [title=Email title, content=Email content, hahaha... , attachment=Attachment [name=Attachment title, type=Document, length=45987]
Email Copy Status: Success
Email Attachment Content Consistent
Email attachment not copied
You can see, due to rewrite the subclass of the equals method, so when the content of each field is equal, the content of the class is considered the same, but after copying, the address is different, the last judgment is used to determine the mail class call cloneMe method, among the attachment object is also copied, if the address is the same, so there is no copying, this time is a shallow cloning.
2.3 Analysis of case evolution
So how to do deep cloning? It is very simple, just need to rewrite the cloneMe method of the mail object, first call the clone method of the parent class to get its own copy of the object, and then its own attachment object also call the cloneMe method, the object will be obtained and then assigned to the copy of the mail object.
public class EmailNew extends Prototype {
// caption
private String title;
// element
private String content;
// attachment (email)
private Attachment attachment;
public EmailNew(String title, String content, Attachment attachment) {
super();
= title;
= content;
= attachment;
}
public String display() {
return "EmailNew [title=" + title + ", content=" + content + ", attachment=" + ();
}
public Attachment getAttachment() {
return attachment;
}
@Override
public boolean equals(Object obj) {
EmailNew e = (EmailNew) obj;
if((title) && (content) && (attachment)) {
return true;
}
return false;
}
@Override
public EmailNew cloneMe() {
EmailNew e = (EmailNew) ();
= (Attachment) ();
return e;
}
}
The final run results are shown below:
EmailNew [title=Email title, content=Email content, hahaha.... , attachment=Attachment [name=Attachment title, type=Document, length=45987]
Email Copy Status: Success
Email attachment content is consistent
Email attachment copied
2.4 Basic realization of the prototype model
The prototype model contains the following roles:
- Prototype: abstract prototype class. Declares an interface that clones itself.
- ConcretePrototype: concrete prototype class. Implement the clone() method of the prototype class to realize the operation of cloning itself. It is an object that can be copied, and there can be more than one.
- Client: client class.
To implement a prototype class, three conditions are required:
- Implementing the Cloneable Interface: The Cloneable interface is similar to the serialization interface in that it simply tells the VM that it is safe to use the clone method on classes that implement this interface. In the JVM, only classes that implement the Cloneable interface can be copied, otherwise a CloneNotSupportedException is thrown.
- Overriding the clone method of the Object class: In Java, the parent class of all classes is the Object class, which has a clone method that returns a copy of the object.
- Calling () in the overridden clone method: By default, classes don't have the ability to copy objects and need to call () to do so.
Now implement a prototype pattern with a simple example:
//realizationCloneable Prototype Abstract Classes for InterfacesPrototype
class Prototype implements Cloneable {
//rewriteclonemethodologies
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)();
}catch(CloneNotSupportedException e){
();
}
return prototype;
}
}
//realization原型类
class ConcretePrototype extends Prototype{
public void show(){
("原型模式realization类");
}
}
public class Client {
public static void main(String[] args){
ConcretePrototype cp = new ConcretePrototype();
for(int i=0; i< 10; i++){
ConcretePrototype clonecp = (ConcretePrototype)();
();
}
}
}
03. Prototype Pattern Analysis
3.1 Prototype Pattern vs Factory Pattern
Purpose and usage scenario differences:
- The main purpose of the prototype pattern is to create new objects by copying existing objects, not by instantiating classes. It is suitable for situations where you need to create multiple similar objects, but do not want to be coupled with a concrete class.
- factory models main purpose is to encapsulate the object creation process and unify the creation of objects through a factory class. It is suitable for situations where different types of objects need to be created based on different conditions or parameters.
Difference in creation method:
- The prototype pattern creates a new object by copying an existing object, either as a shallow clone (copying only basic type attributes) or as a deep clone (copying all attributes, including reference type attributes).
- The factory pattern creates objects through a factory class, which is invoked based on different conditions or parameters in differentfactory methodto create different types of objects.
Flexibility to differentiate:
- The prototype pattern dynamically determines the type of an object at runtime, allowing you to clone different types of objects as needed.
- The factory pattern determines the type of an object at compile time and requires different factory methods to be defined in the factory class to create different types of objects.
The focus is different:
- The prototype pattern is concerned with the process of copying and cloning objects, creating new objects by copying existing objects.
- The factory pattern focuses on the object creation process, encapsulating the object creation logic through the factory class.
3.2 Prototype Mode vs Deep Copy
Prototype Pattern (Prototype Pattern) and Deep Copy (Deep Copy) are two concepts that have some differences in terms of object copying and cloning.
Purpose and usage scenarios:
- The main purpose of the prototype pattern is to create new objects by copying existing objects, not by instantiating classes. It is suitable for situations where you need to create multiple similar objects, but do not want to be coupled with a concrete class.
- The main purpose of deep copy is to create a new object and copy all the properties of the original object into the new object, including those of reference types. It is used in situations where completely separate copies of an object are needed, rather than shared references.
Reproduction method:
- The prototype pattern creates a new object by copying an existing object, either as a shallow clone (copying only basic type attributes) or as a deep clone (copying all attributes, including reference type attributes).
- Deep copy is a type of copying that recursively copies all properties of an object, including reference type properties, ensuring that the new object is completely independent of the original.
Differences in realization:
- The prototype pattern allows copying and cloning of objects by implementing the Cloneable interface and overriding the clone() method.
- deep copyThis can be done through a custom copy method or by using serialization and deserialization.
04. Explanation of the application of the prototype pattern
4.1 Using the clone method
An abstract prototype class is defined in the prototype pattern structure that all Java classes inherit from, and the Object class provides a clone() method that makes a copy of a Java object.
Therefore, in Java, you can directly use the clone () method provided by Object to achieve object cloning, the prototype pattern in the Java language is very simple to implement.
4.2 Implementing the interface Cloneable
Java classes that are capable of cloning must implement an identifying interface, Cloneable, indicating that the Java class supports copying.
If a class does not implement this interface but calls the clone() method, the Java compiler will throw a CloneNotSupportedException.
Therefore, in Java, the Object class and the Cloneable interface together act as an abstract prototype class that does not need to be defined again, however, since calling the clone method requires catching exceptions, it is more cumbersome to do the processing each time it is called, so you can abstract a base class that catches them, and then they do not need to be caught again in the concrete subclasses (only when the subclasses don't need to deal with the exceptions) Then you don't need to catch it again in the concrete subclass (only when the subclass doesn't need to handle exceptions).
4.3 Deep and shallow cloning
Typically, a class contains a number of member objects. When cloning an object using the prototype pattern, the prototype pattern can be categorized into two forms depending on whether or not its member objects are also cloned: deep cloning and shallow cloning.
- Shallow cloning: creates a new object with exactly the same attributes as the original object, and for non-basic type attributes, still points to the memory address of the object to which the original attribute points.
- Deep cloning: a new object is created and other objects referenced in the property are cloned and no longer point to the original object address.
The clone method in Java is a shallow clone by default.
Regarding data deep cloning and shallow cloning, there is an article on my side dedicated to detailing its cases and principles. You can read it:Comparison of various copy data
05. Prototype Pattern Summary
5.1 Analysis of advantages and disadvantages
vantage
- When creating new object instances is more complex, the use of prototype patterns can simplify the object creation process, through an existing instance can improve the efficiency of the creation of new instances.
- Product classes can be dynamically added or subtracted.
- The prototype pattern provides a simplified creation structure.
- The state of an object can be saved using deep cloning.
5.2 What are the disadvantages
drawbacks
- Each class needs to be equipped with a clone method, and this clone method needs to take into account the functionality of the class, which is not difficult for brand new classes, but not necessarily easy for existing classes, which have to be modified, violating the "principle of openness and closure".
- More complex code is required to implement deep cloning. There is some complexity to modify the implementation of the clone method.
5.3 Description of the application environment
The prototype pattern can be used in the following cases:
- Creating new objects is more costly, and new objects can be obtained by copying existing objects through the prototype pattern, or, in the case of similar objects, by slightly modifying their properties.
- If the system wants to save the state of an object, and the state of the object changes very little, or the object itself does not take up much memory, you can also use the prototype pattern together with the memo pattern to apply it. On the contrary, if the state of the object changes a lot, or the object occupies a lot of memory, it would be better to use the state pattern than the prototype pattern.
- There is a need to avoid using hierarchical factory classes to create hierarchical objects, and with classes that have only one or very few combined states for instance objects, it may be more convenient to get a new instance by copying the prototype object than to create a new instance using the constructor.
06. Prototype Patterns Expanded Applications
6.1 Schema extensions
6.2 Summary of the prototype model
1. What is the prototype pattern?
If the cost of creating an object is relatively large, and the difference between different objects of the same class is small (most of the fields are the same), in this case, we can use the existing object (prototype) to make a copy (or called copy) of the way to create a new object, in order to achieve the purpose of saving the creation time. This way of creating objects based on prototypes is called the Prototype Design Pattern, or Prototype Pattern for short.
2. Two ways to implement the prototype pattern
There are two implementations of the prototype pattern, deep copy and shallow copy. Shallow copy only copies the basic data type data in the object and the memory address of the referenced object, it does not recursively copy the referenced object, and the referenced object of the referenced object ...... whereas deep copy gets a copy of the object that is completely independent. So, deep copy is more time consuming and memory space consuming than shallow copy.
If the object to be copied is immutable, it is fine for shallow copy to share the immutable object, but for mutable objects, the object obtained by shallow copy and the original object will share part of the data, and there is a risk that the data may be modified, and it becomes much more complicated.
6.3 More content recommendations
module (in software) | descriptive | note |
---|---|---|
GitHub | Multiple YC series of open source projects , including Android component libraries , and a number of cases | GitHub |
Blog Roundup | Bringing together Java, Android, C/C++, network protocols, algorithms, programming summaries and more! | YCBlogs |
design pattern | Six Design Principles, 23 Design Patterns, Design Pattern Cases, Object-Oriented Thinking | design pattern |
Java Advanced | Data Design and Principles, Object Oriented Core Ideas, IO, Exceptions, Threading and Concurrency, JVM | Java Advanced |
network protocol | Practical examples of networking, network principles and layering, Https, network requests, troubleshooting | network protocol |
computer theory | Computer Architecture, Frames, Memory, CPU Design, Memory Design, Instruction Programming Principles, Exception Handling Mechanisms, IO Operations and Principles | computer foundation |
Learning C Programming | A systematic and comprehensive tutorial for learning three to four comprehensive cases at the introductory level of the C language. | C programming |
C++ programming | Systematic and comprehensive instructional tutorials for the introductory level of the C++ language, concurrent programming, and core principles. | C++ programming |
algorithmic practice | Columns, arrays, chain tables, stacks, queues, trees, hashes, recursion, lookups, sorting, etc. | Leetcode |
Android | Basic primer, open source library interpretation, performance optimization, Framework, program design | Android |
23 Design Patterns
23 Design Patterns & Description & Core Role | including through |
---|---|
creation-based model Provides use cases for creating objects. Ability to separate the creation of objects from the use of objects in a software module |
Factory Pattern Abstract Factory Pattern (Abstract Factory Pattern) Singleton Pattern Builder Pattern Prototype Pattern |
structural model Focus on combinations of classes and objects. Describe howCombining classes or objects to form larger structures |
Adapter Pattern (Adapter Pattern) Bridge Pattern Filter Pattern (Filter, Criteria Pattern) Composite Pattern Decorator Pattern Facade Pattern Flyweight Pattern Proxy Pattern |
behavioral model Special attention is paid to communication between objects. The main solution is "interaction between classes or objects". |
Chain of Responsibility Pattern (Chain of Responsibility Pattern) Command Pattern Interpreter Pattern (Interpreter Pattern) Iterator Pattern Mediator Pattern (Mediator Pattern) Memorandum Pattern (Memento Pattern) Observer Pattern (OOP) State Pattern Null Object Pattern (NOP) Strategy Pattern Template Pattern Visitor Pattern |