This is the 23rd day of my participation in the August More Text Challenge.More challenges in August

📖 preface

Mastering Python Design Patterns divides design patterns into three types:

  • Creation pattern
  • Structural mode
  • Behavioral pattern

The creation pattern is described as follows:

The prototype pattern comes in handy when we have an object and want to create a full copy of that object. When we know that some part of an object will be changed but want to keep the original object unchanged, we usually need a copy of the object. In such cases, it does not make sense to recreate the original object (see section [Mitotic Division]).

Another example is when we want to copy a complex object, using the prototype pattern is convenient. For copying complex objects, we can treat the object as if it were fetched from the database and refer to some other object that is also fetched from the database. It takes a lot of work to create an object by repeatedly querying the data multiple times. It is much more convenient to use the prototype pattern in this scenario.


🚀 Prototype pattern

Prototype Pattern: copy existing objects to achieve functional reuse and optimization

1. Introduction

Prototype patterns are used to create repetitive objects while maintaining performance. This type of design pattern is the creation pattern, which provides the best way to create objects.

This pattern implements a prototype interface that creates a clone of the current object. This pattern is used when the cost of creating objects directly is high. For example, an object needs to be created after an expensive database operation. We can cache the object, return a clone of it on the next request, and update the database as needed to reduce database calls.

Intent: Specify the type of object to create with prototype instances, and create new objects by copying these prototypes.

Main solution: create and delete prototypes at run time.

When to use:

  • When a system should be created, constructed, and represented independently of its product.
  • When the class to be instantiated is specified at run time, for example, by dynamic loading.
  • To avoid creating a factory class hierarchy parallel to the product class hierarchy.
  • When an instance of a class can have only one of several different combinations of states. It may be more convenient to create a proportionate number of prototypes and clone them than to manually instantiate the class each time in the appropriate state.

2. Application scenarios

  • Resource optimization scenario.
  • Class initialization requires the digestion of many resources, including data, hardware resources, and so on.
  • Scenarios for performance and security requirements.
  • throughnewIf generating an object requires very tedious data preparation or access rights, you can use the prototype pattern.
  • A scenario where an object has multiple modifiers.
  • When an object needs to be made available to other objects, and each caller may need to modify its value, consider using the prototype pattern to copy multiple objects for use by the caller.
  • In a real project, the prototype pattern rarely appears alone, but usually in conjunction with the factory method pattern, where a Clone method creates an object that is then provided to the caller by the factory method.

Personal Understanding:

When we already have an object with properties and methods, we have two options if we want to acquire another object of the same type: To create a new object, or copy a copy of the existing object, and in many cases we do not need to completely rebuild an object, just need to modify its properties and methods on the basis of the existing object (retain the original object) to get a new object.

🐱🏍 leave a thought!

I saw the following article explaining the implementation steps, because bloggers are new to thisPythonA little not too clever tooth son, hope big guy can help understand

The Prototype design pattern helps us create clones of objects. In its simplest form, a clone() function takes an object as an input parameter and returns a copy of the input object. Copy is classified into deep copy and shallow copy, and is implemented using python’s built-in copy module. The deepcopy copy.deepcopy() function, which recursively copies and creates new objects; The shallow-copy copy () function points to the same object with a reference. The advantage of deep copy is that objects do not affect each other, but it consumes resources and takes time to create. If the object is not modified, shallow copy can be used to save resources and creation time.

In Python, you can use the copy.copy() function for shallow copying. The following, taken from the Official Python documentation, illustrates the difference between shallow copies (copy.copy()) and deep copies (copy.deepcopy()) :

When a new composite object is constructed, references to the object found in the original object are inserted into the new object (as much as possible).

After a new composite object is constructed, a copy of the object found in the original object is inserted recursively into the new object. Shallow copy, we focus on improving application performance and optimizing memory usage, introducing data sharing between objects, but need to modify data carefully because all changes are visible to all copies. Shallow copies are not covered much in this chapter, but you may want to try them out.

Deep copy, where we want to be able to make changes to one copy without affecting other objects. This feature is useful in cases like the cake recipe example we saw earlier. There is no data sharing, so you need to be concerned about the resource consumption that comes with object cloning.


👏 in popular terms:

When we publish A book, The Big Talk Design Pattern 1.0, and 10 years later we feel that the book is outdated and need to rewrite the big Talk Design Pattern 2.0, are we completely rewriting the book? Or is it a revision based on the original Big Talk Design Mode 1.0? The latter, of course, because it saves a lot of typesetting, adding pre-existing knowledge, and so on that has already been done.

Example source code in the book:

import copy from collections import OrderedDict class Book: def __init__(self, name, authors, price, **rest): Examples of rest are: "Self.name = name self.authors = authors self.price = price self.__dict__. Update (rest) # add additional attributes def __str__(self): mylist = [] ordered = OrderedDict(sorted(self.__dict__.items())) for i in ordered.keys(): mylist.append('{}: {}'.format(i, ordered[i])) if i == 'price': mylist.append('$') mylist.append('\n') return ''.join(mylist) class Prototype: def __init__(self): Self. Objects = dict() # def register(self, identifier, obj): Self. Objects [identifier] = obj def unregister(self, identifier): [identifier] def clone(self, identifier, **attr): Find = self.objects.get(identifier) if not found: raise ValueError('Incorrect object identifier: {}'.format(identifier)) obj = copy.deepCopy (found) obj.__dict__. Update (attr) # return obj def main():  b1 = Book('The C Programming Language', ('Brian W. Kernighan', 'Dennis M.Ritchie'), price=118, publisher='Prentice Hall', length=228, publication_date='1978-02-22', tags=('C', 'programming', 'algorithms', 'data structures')) prototype = Prototype() cid = 'k&r-first' prototype.register(cid, b1) b2 = prototype.clone(cid, Name ='The C Programming Language(ANSI)', price=48.99, length=274, publication_date='1988-04-01', edition=2) for i in (b1, b2): print(i) print("ID b1 : {} ! = ID b2 : {}".format(id(b1), id(b2))) if __name__ == '__main__': main()Copy the code

The output result is:

authors: ('Brian W. Kernighan', 'Dennis M.Ritchie')
length: 228
name: The C Programming Language
price: 118$
publication_date: 1978-02-22
publisher: Prentice Hall
tags: ('C', 'programming', 'algorithms', 'data structures')

authors: ('Brian W. Kernighan', 'Dennis M.Ritchie')
edition: 2
length: 274
name: The C Programming Language(ANSI)
price: 48.99$

publication_date: 1988-04-01
publisher: Prentice Hall
tags: ('C', 'programming', 'algorithms', 'data structures')

ID b1 : 2378797084512 != ID b2 : 2378796684008
Copy the code

In Python, we’re going to do the same thing. It’s not that complicated. We don’t have to use this method.

def main(): b1 = Book('The C Programming Language', ('Brian W. Kernighan', 'Dennis M.Ritchie'), price=118, publisher='Prentice Hall', length=228, publication_date='1978-02-22', tags=('C', 'programming', 'algorithms', Deepcopy (b1) b2.name = 'The C Programming Language(ANSI)' b2.price B2. edition = 2 for I in (b1, b2): print(I) print("ID b1: {}! = ID b2 : {}".format(id(b1), id(b2)))Copy the code

🎉 summary:

The same content, through different ways, can get the same effect.

As mentioned in Python Design Patterns, the general meaning is as follows:

Design patterns are not tied to a specific programming language. A good design pattern should be implemented in most programming languages (if not all, depending on the language characteristics). Most importantly, design patterns are a double-edged sword that can lead to disaster and endless trouble if used in the wrong circumstances. However, if design patterns are used in the right place at the right time, they can be your salvation.

  • For more references, see here:The Blog of Chan Wing Kai

  • Like the small partner of the blogger can add a concern, a thumbs-up oh, continue to update hey hey!