Python Design Patterns: Introduction to 23 Design Patterns

Design pattern background

In the early days of software development, designers and programmers usually wrote code based on their own experience and intuition. But as the size and complexity of software increases, this way of writing becomes more and more difficult. Therefore, design patterns came into being.

Design patterns were originally formed to solve various problems in the early development process, including poor code maintainability, insufficient reusability, and poor readability. Design patterns provide a structured thinking process that enables developers to think more systematically about how to write high-quality code.

History of Design Patterns

The history of design patterns dates back to the late 1970s and early 1980s, when the concept of object-oriented programming became popular. During this period, computer scientists began trying to find a better way to deal with complex software design problems.

The first to propose design patterns were Kristen Nygaard and Ole-Johan Dahl, the founders of the Simula language. The Simula language was the first language to support object-oriented programming. In the early Simula language, design patterns already existed and were used to solve some complex software problems.

Until 1994, four computer scientists Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides co-published the book "Design Patterns: The Foundation of Reusable Object-Oriented Software", officially introducing the concept of design patterns into the field of software engineering middle.

Design pattern birth year and inventor

The concept of design patterns was first proposed by Kristen Nygaard and Ole-Johan Dahl, but the most widely circulated book is "Design Patterns: Fundamentals of Reusable Object-Oriented Software" by the "Gang of Four" (GoF) of Four authors. "This book. Published in 1994, the book was co-written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Due to the great influence of the book, these four authors are also known as the inventors of design patterns.

The history of design patterns

Since its birth in the 1990s, design patterns have gradually become an important concept in the field of software development. In software development, design patterns can help developers better organize code, improve code quality and reusability. At the same time, design patterns have become one of the core concepts of object-oriented design and programming.

In the development of design patterns, there are several important milestones. Foremost among these is the book Design Patterns: Fundamentals of Reusable Object-Oriented Software by GoF. The book systematically summarizes and sorts out 23 design patterns for the first time, and describes and classifies them. In addition, there are many other books and articles that discuss and expand design patterns, which promote the development and popularization of design patterns.

Design pattern is a classic problem-solving method in software development. It contains 23 design patterns, which can be divided into three categories: creational patterns, structural patterns, and behavioral patterns.

1. Creational mode

1.1 Singleton mode

The singleton pattern ensures that there is only one instance of a certain class in the program, and provides a global point of access to it. Usually used to control access to resources, such as thread pools, network connection pools, etc.

Implementation principle: the only instance is saved through static variables, and the constructor is set as private to prevent external instantiation.

Application scenarios: multithreading, database operations, logging, etc.

1.2 Factory mode

The factory pattern is a method of creating objects, using the factory method instead of the new operator to create the required objects. The corresponding objects can be dynamically created based on the parameter types passed to the factory.

Implementation principle: To create objects through abstract factories or concrete factories, the client only needs to know the factory interface.

Application scenarios: polymorphism, shielding object creation process, and improving code reuse rate.

1.3 Abstract factory pattern

The abstract factory pattern is a design pattern similar to the factory method pattern, and they are both used to create objects. The difference between the abstract factory pattern and the factory method pattern is that it can not only create an object, but a group of objects.

Implementation principle: use the abstract factory class to define a set of methods that the factory needs to support, and the specific factory implements these methods to create specific products.

Application scenarios: polymorphism, shielding object creation process, and improving code reuse rate.

1.4 Builder mode

The builder pattern separates the construction process of a complex object from its representation, so that the same construction process can create different representation objects. This pattern is often used to create objects with various properties.

Implementation principle: Define a Builder class and a series of Director classes to encapsulate part of the call sequence of the Builder class. The Client class is responsible for specifying the corresponding Director to implement a specific calling sequence.

Application scenario: Create some complex or configurable objects.

1.5 Prototype pattern

The prototype pattern copies a new instance from a given prototype instance. It is suitable for situations where there is a high cost when creating a new object, or when there are complex dependencies in the constructor.

Implementation principle: define an abstract parent class and implement the Clone method to copy the object, and the subclass overrides the Clone method and returns the subclass object.

Application scenario: Generate complex objects and avoid constructor initialization overhead.

2. Structural patterns

2.1 Adapter mode

The adapter pattern converts the interface of one class into another interface expected by clients. Adapters allow otherwise incompatible classes to work together.

Implementation principle: Use an adapter class to convert the interface of a class into the interface that the customer wants.

Application scenarios: use existing classes without modifying their interfaces, and solve problems between incompatible interfaces.

2.2 Decorator pattern

The decorator pattern dynamically attaches responsibilities to objects and extends the functionality of objects by wrapping the real object with a decorator object.

Implementation principle: Use an abstract class to define the object that needs to be decorated, use the decoration class to inherit the abstract class and rewrite the methods in it, and add the required operations before and after calling the method.

Application scenarios: dynamically expand objects, enhance object functions, and avoid overcomplicated inheritance relationships.

2.3 Combination mode

The Composite mode composes objects into a tree structure to represent a "whole-part" hierarchy, allowing users to use a single object and a composite object in a consistent manner.

Implementation principle: Use abstract classes to define objects and their behavior, and use concrete classes to implement various types of objects.

Application scenarios: tree structure, recursive structure, fixed hierarchy.

2.4 Appearance mode

Facade mode provides a unified interface for accessing a group of interfaces in a subsystem. It defines a high-level interface that makes the subsystem easier to use.

Implementation principle: Use a facade class to encapsulate complex operations of other classes.

Application scenarios: decoupling the system and simplifying the system call process.

2.5 Proxy mode

The proxy pattern adds additional behavior without changing the original code. The proxy object and the proxy object have a common interface, the proxy object knows how to access the actual object, and can control the access of the actual object.

Implementation principle: Use a proxy class to wrap the class that needs to be proxied, and expose the same interface for the client to use.

Application scenarios: protecting target objects, providing additional access control, lazy initialization, caching data, etc.

3. Behavioral patterns

3.1 Observer pattern

The Observer pattern defines a one-to-many dependency relationship between objects, so that whenever an object's state changes, its related dependent objects will be notified and automatically updated.

Implementation principle: use the observer interface to define observers and corresponding notification methods, and specific observers need to implement this interface. The observed object needs to maintain a list of observers and notify the observers when the state changes.

Application scenarios: message passing, status update, event processing, etc.

3.2 Strategy Pattern

The Strategy pattern is a way of defining a family of algorithms that conceptually all do the same job, just implemented differently.

Implementation principle: Use an abstract class or interface to define an algorithm, and use concrete classes to implement different algorithms.

Application scenario: It needs to be used when the algorithm needs to be dynamically selected at runtime.

3.3 Template method pattern

The Template Method pattern defines the skeleton of an algorithm in an operation, deferring some steps to implementation in subclasses. It is an inheritance based design pattern.

Implementation principle: use abstract classes or interfaces to define the skeleton of the algorithm, and use concrete classes to implement specific steps.

Application scenarios: fixed algorithm framework, code reuse.

3.4 Iterator pattern

The Iterator pattern provides a way to access individual elements in a container object without exposing the object's internal representation.

Implementation principle: Use an iterator class to encapsulate the container object to achieve different iteration methods.

Application scenario: used when traversing or searching container objects.

3.5 Command Mode

The command pattern encapsulates the request as an object, allowing you to parameterize the client with different requests. At the same time, requests can be queued, request logs can be recorded, and undo operations can be supported.

Implementation principle: Use a command interface to define command operations, and use specific classes to implement specific command operations.

Application scenarios: need to record request logs, support undo operations, support the execution of multiple commands, etc.

The above is the introduction and implementation principles of 23 design patterns. Different scenarios require different design patterns to solve problems. Developers need to choose the appropriate design pattern according to the specific situation and use it flexibly in actual development. Later, Python will be used to introduce each design pattern in detail.

Guess you like

Origin blog.csdn.net/weixin_40025666/article/details/131221448