Seven design principles that design patterns follow

What are Design Patterns?

1. Definition of design pattern

The design pattern is a solution to various problems that recur in software design. It is not directly used to complete the code writing, but to describe how to solve the problem in various situations. . Design patterns can help us enhance code reusability, scalability, maintainability, flexibility, etc. The ultimate goal of using design patterns is to achieve high cohesion and low coupling of code.

2. Classification of Design Patterns

There are 23 design patterns , which can be roughly divided into three categories : creational, behavioral, and structural .

(1), creation mode:

The mode of object instantiation, the creational mode is used to decouple the instantiation process of objects.

  1. Singleton mode: A certain class intelligence has an instance, providing a global access point.
  2. Factory mode: A factory class decides which instance of the product class to create based on the parameters passed in.
  3. Abstract Factory Pattern: Creates families of related or dependent objects without explicitly specifying concrete classes.
  4. Builder mode: Encapsulates the creation process of a complex object and can be constructed step by step.
  5. Prototype pattern: Create new instances by copying existing ones.

(2), structural mode:

Group classes or objects together to form a larger structure.

  1. Decorator pattern: Dynamically add new functionality to an object.
  2. Proxy mode: Provide a proxy for other objects to control access to this object.
  3. Bridge Pattern: Separates the abstraction from its implementation so that they can both vary independently.
  4. Adapter pattern: Convert the method interface of a class into another interface that the client wants.
  5. Composite mode: Compose objects into a tree structure to represent a "part-whole" hierarchy.
  6. Appearance mode: Provide a unified method to access a group of interfaces in the subsystem.
  7. Flyweight mode: effectively support a large number of fine-grained objects through sharing technology.

(3), behavioral model

How classes and objects interact, with division of responsibilities and algorithms.

  1. Strategy pattern: Define a series of algorithms, encapsulate them, and make them interchangeable.
  2. Template pattern: Define an algorithm structure, while deferring some steps to subclass implementation.
  3. Command mode: Encapsulate the command request as an object, so that different requests can be used for parameterization.
  4. Iterator mode: A method of traversing and accessing each element in an aggregate object without exposing the internal structure of the object.
  5. Observer pattern: one-to-many dependencies between objects.
  6. Arbiter pattern: Use an intermediary object to encapsulate a series of object interactions.
  7. Memento pattern: Maintain the internal state of an object without breaking encapsulation.
  8. Interpreter mode: Given a language, define a representation of its grammar and define an interpreter.
  9. State Pattern: Allows an object to change its behavior when its internal state changes.
  10. Chain of Responsibility Mode: Decouple the sender and receiver of the request, so that multiple objects have the opportunity to process the request.
  11. Visitor pattern: Add new functionality to a set of object elements without changing the data structure.

Original link

3. Seven principles of design patterns

1. The Open Closed Principle (OCP)

Open-closed principle (Open-ClosedPrincinple, referred to as OCP):

​ A module, class, or function should be closed for modification and open for extension. Extend without modifying the source code.

  • ​ Modifying the original code may cause problems with the original normal functions.
  • ​ When the requirements change, it can be realized by extension, adding new methods or properties.

The principle of opening and closing is the most basic design principle and the core of object-oriented design. Following this principle can bring the huge benefits claimed by object-oriented technology, that is, maintainability, scalability, reusability, and good flexibility. The other design principles are the specific forms of the opening and closing principle. If it is explained in an object-oriented way, the opening and closing principle is the topmost abstract class, and the other five classes are its concrete realization.


2. Single Responsibility Principle (SRP)

Single Responsibility Principle (SRP):

As far as a class is concerned, there should be only one reason for it to change. Each class should implement a single principle , otherwise the class should be split.

If a class takes on too many responsibilities, it is equivalent to coupling these responsibilities together. A change in one responsibility may weaken or inhibit the ability of this class to complete other responsibilities. This coupling can lead to fragile designs. When changes occur, the design will suffer unexpected damage.

Much of what software design is really about is discovering responsibilities and separating those responsibilities from each other.

To put it simply, the function of a class should be single, not all-encompassing, just like a grocery store.


3. Dependency inversion (inversion) principle (DIP)

Dependence Inversion Principle (Dependence Inversion Principle, DIP for short):

It is the basis of the principle of opening and closing, and the specific content is for interface programming, which depends on abstraction rather than concreteness.

1. High-level modules should not depend on low-level modules, both should depend on abstraction.

2. Abstraction should not depend on details, details should depend on abstraction (ASD)

The first sentence can be understood as follows: For example, the user login and registration module, the specific implementation process is that the front end submits the form to the back end, and the back end reads and writes the database according to the data in the form. In the process of using java to access the database, we will use JDBC, first write a function (bottom function) that encapsulates the database access, and then call this function with specific business logic (high-level function), this is called high-level module dependency Low-level modules . This method will make it impossible to reuse the high-level modules, because the high-level modules are bound to the bottom modules. If the motherboard in the computer adopts this principle, if the motherboard is damaged, the CPU, memory, graphics card, etc. will all have to be replaced. This design is unreasonable. Conversely, if any one of the memory stick, CPU, or graphics card is broken, it will not cause the other parts to be unusable. Therefore, it is necessary to make both the high-level modules and the low-level modules depend on abstraction . If there is a problem, it can be replaced directly, or it can be checked and changed on this basis.

The second sentence can be understood as follows: For example, I have a motherboard with five von Neumann components. Suppose one day the memory module breaks and needs to be replaced. Here, the memory module is replaced instead of the entire motherboard. There is an interface for the memory module on the motherboard, and the manufacturer must produce the memory module according to this interface, rather than a certain brand creating its own interface. In this case, when replacing the memory module, the entire motherboard needs to be replaced. Therefore, the internal design of the memory stick here (storage particles, circuit design, etc.) is all internally packaged (details), and this needs to rely on the golden finger interface (abstract) of the memory stick design, so the principle of dependency inversion: abstraction ( memory interface) should not depend on details (internal packaging of the memory module), and details (internal packaging of the memory module) should depend on abstraction (interface of the memory module).

The radio is a typical example of overcoupling. When a radio breaks down, people who don't understand it can't fix it, because any problem depends on other components, and each component depends on each other, making it difficult to maintain.

Dependency inversion is a hallmark of object-oriented design, and all dependencies in the program are terminated by abstract classes or interfaces.


4. Liskov Substitution Principle (LSP)

Liskov Substitution Principle (LSP):

The Liskov substitution principle is the cornerstone of inheritance and reuse. If a software entity uses a parent class, it must be used in its subclasses, and it cannot detect the difference between the parent class object and the subclass object, that is to say , replacing the parent class with its subclass, the behavior of the program remains unchanged. Subtypes must be able to replace their supertypes .

The subclass can replace any place where the parent class can appear. For example, you can represent your father to work at your grandma's house.

It is a bit of the principle of opening and closing. Subclasses can extend the functions of the parent class, but cannot change the original functions of the parent class.


5. Interface Separation Principle (ISL)

Interface Segregation (Separation) Principle (Interface Segregation Principle, referred to as ISL):

A class's dependence on another class should be based on the smallest interface .

  • A class should not depend on interfaces it does not need. Each interface does not have methods that subclasses cannot use but must implement, otherwise the interface must be split.
  • The granularity of the interface should be as small as possible. If an interface has too many methods, it can be split into multiple interfaces.

Using multiple specialized interfaces is better than using a single general interface. The principle of interface isolation is to constrain interfaces and reduce the dependence of classes on interfaces.


6. Principle of Demeter (LOD)

Law of Demeter (Law of Demeter, referred to as LoD): also known as the principle of least knowledge

Two classes should not interact directly if they don't have to communicate directly with each other. If one of the classes needs to call a method of another class, the call can be forwarded by a third party. A class should try not to have a relationship with other classes

  • The less a class knows about other classes, the less coupling.
  • When one class is modified, other classes are less affected and errors are less likely to occur.

In terms of class structure design, each class should minimize the access rights of its members. The principle of least knowledge emphasizes the coupling between classes. The weaker the coupling between classes, the more conducive it is to reuse. If a class in weak coupling is modified, it will not affect related classes.


7. Compositional Reuse Principle (CARP)

Composite/Aggregate Reuse Principle (CARP):
try to use synthesis/aggregation instead of inheritance.
When the author of the parent class and the child class are the same person (class), inheritance is used casually. Composition is preferred when parent and subclass authors are not the same person. Composition is preferred when only to reuse methods of a certain class, because inheritance will bring some unwanted methods.


Summary of the seven principles:

Open Closed Principle (OCP): Open for extension, closed for modification

Single Responsibility Principle (SRP): A class has a single responsibility

Dependency Induced (DIP): Programming to Interfaces

Interface Separation (ISL): The design interface should be concise and simple

Principle of Demeter (LOD): Reduce coupling between classes

Composition Reuse Principle (CARP): Use composition/aggregation instead of inheritance.

The problem to be solved by the design pattern is:
find out the possible changes in the application, separate them, and don't mix them with the code that does not need to be changed; program for the interface
, not for the implementation; Strive for loosely coupled design.

Guess you like

Origin blog.csdn.net/qq_42242452/article/details/124635739