Internet factory interview and examination center -- Design Mode

Blog address: Coding Lemon's blog
All articles will be updated on the blog at the first time!

Big factory interview series fifth bullet!

This chapter is special. It may summarize all the common design patterns, and then I will mark out some of the most frequently asked design patterns. There are many contents, but they are dry goods!

In order to directly view one of the design patterns, put the directory below:


Before learning design patterns, we need to understand the design principles!

1. Design principles

1.1 principle of single responsibility

A class has only one reason for its change. That is, a class should have only one responsibility. Each responsibility is an axis of change. If a class has more than one responsibility, these responsibilities are coupled together. This leads to fragile design. When one responsibility changes, it may affect other responsibilities. In addition, the coupling of multiple responsibilities will affect reusability. For example, to realize the separation of logic and interface.

1.2 Open Close Principle

The opening and closing principle means that it is open to extensions and closed to modifications. When the program needs to be expanded, you can't modify the original code to achieve a hot plug effect. So in a word, in order to make the program extensible, easy to maintain and upgrade. To achieve this effect, we need to use interfaces and abstract classes, which will be mentioned in the following specific design.

1.3 Liskov Substitution Principle

Commonly known as LSP principle (manual doghead doge). The Richter substitution principle says that wherever a base class can appear, subclasses must appear. LSP is the cornerstone of inheritance reuse. The base class can be reused only when the derived class can replace the base class and the function of the software unit is not affected, and the derived class can also add new behavior on the basis of the base class. The Richter substitution principle is right Supplement to the "open close" principle. The key step in realizing the "open close" principle is abstraction. The inheritance relationship between base class and subclass is the concrete implementation of abstraction, so the Richter substitution principle is the specification of the specific steps to realize abstraction.

1.4 Dependency Inversion Principle

The so-called dependency inversion principle is to rely on abstraction rather than concrete. In short, it requires programming the abstraction rather than the implementation, which reduces the coupling between the customer and the implementation module.

The key to realize the opening and closing principle is abstraction, and the concrete implementation is derived from abstraction. If the opening and closing principle is the goal of object-oriented design, then the dependency inversion principle is the main means of object-oriented design.

1.5 interface aggregation principle

This principle means that using multiple isolated interfaces is better than using a single interface. It also means to reduce the coupling between classes. From here, we can see that in fact, the design pattern is a software design idea, starting from the large-scale software architecture for the convenience of upgrading and maintenance. So it appears many times above: reduce dependence and reduce coupling.

1.6 Composite Reuse Principle

The principle of composite reuse refers to using some existing objects in a new object through association relationship (including composition relationship and aggregation relationship) to make them become a part of the new object; the new object reuses its existing functions by delegating and calling the methods of the existing object. In short, we should try to use combination / aggregation relationship and avoid inheritance.

1.7 Demeter Principle

Why is it called the least known principle, that is, an entity should interact with other entities as little as possible to make the system functional modules relatively independent. In other words, a software entity should interact with other entities as little as possible. In this way, when a module is modified, it will affect other modules as little as possible, and the expansion will be relatively easy. This is a limitation on the communication between software entities, which requires to limit the width and depth of communication between software entities. (in fact, it is somewhat similar to the current use of more microservices. Each microservice has as little interaction as possible and only knows each other's interfaces)

These seven design principles are the principles that software design patterns must follow as much as possible and are the basis of design patterns. In the actual development process, it is not necessary to require all codes to follow the design principles, but to comprehensively consider manpower, time, cost and quality, do not deliberately pursue perfection, and follow the design principles in appropriate scenarios. This reflects a balanced trade-off, which can help us design a more elegant code structure.

The emphasis of various principles is different. Next, we summarize the seven principles of software design pattern in one sentence, as shown in the table below.

Design principlesOne sentence inductionobjective
Opening and closing principleIt is open to extensions and closed to modificationsReduce new risks caused by maintenance
Dependency Inversion PrincipleThe high level should not rely on the low level, but should be interface oriented programmingIt is more conducive to the upgrading and expansion of code structure
Single responsibility principleA class only does one thing, and the implementation class should be singleEasy to understand and improve the readability of the code
Interface isolation principleAn interface only does one thing, and the interface should be simplified and singleFunctional decoupling, high aggregation and low coupling
Dimitt's lawDon't know what you shouldn't know. A class should keep the least understanding of other objects and reduce the degree of couplingOnly communicate with friends and don't talk to strangers to reduce code bloat
Richter substitution principleDo not destroy the inheritance system. The function of subclass overriding methods should be changed, and the meaning of parent class methods should not be affectedPrevent the spread of inheritance
Synthetic Reuse PrincipleTry to use combination or aggregation relationship to realize code reuse, and use inheritance lessReduce code coupling

In fact, the purpose of these principles is only one: reduce the coupling between objects and increase the reusability, scalability and maintainability of programs.

Now let's introduce various design modes!

2. Creation mode

The main focus of creative mode is "how to create objects?", Its main feature is "separating the creation and use of objects". This can reduce the coupling degree of the system. Users do not need to pay attention to the creation details of objects. The creation of objects is completed by relevant factories. Just like when we go to the mall to buy goods, we don't need to know how the goods are produced, because they are produced by special manufacturers.

The creation mode is divided into the following types.

  • Singleton mode: a class can only generate one instance. This class provides a global access point for external access to the instance. Its extension is the limited multiple instance mode.
  • Prototype mode: take an object as a prototype and clone multiple new instances similar to the prototype by copying it.
  • Factory method pattern: defines an interface for creating products, and subclasses determine what products to produce.
  • Abstract factory pattern: it provides an interface to create a product family, and each subclass can produce a series of related products.
  • Builder mode: decompose a complex object into several relatively simple parts, then create them according to different needs, and finally build the complex object.

2.1 singleton mode( ⭐⭐⭐⭐⭐)

In some systems, in order to save memory resources and ensure the consistency of data content, it is required to create only one instance of some classes, which is the so-called singleton pattern (such as dao layer and service layer in Spring).

Definition of Singleton mode: a mode in which a class has only one instance and the class can create the instance itself. Definition of Singleton mode: a mode in which a class has only one instance and the class can create the instance itself.

The singleton mode has three features:

  1. A singleton class has only one instance object;
  2. The singleton object must be created by the singleton class itself;
  3. The singleton class provides a global access point for accessing the singleton.

Advantages of singleton mode:

  • Singleton mode can ensure that there is only one instance in memory and reduce the memory overhead.
  • Multiple occupation of resources can be avoided.
  • Set global access points in singleton mode to optimize and share resource access.

Disadvantages of singleton mode:

  • The singleton mode generally has no interface and is difficult to expand. If you want to expand, there is no second way except to modify the original code, which violates the opening and closing principle.
  • In concurrent testing, singleton mode is not conducive to code debugging. During debugging, if the code in the singleton is not executed, a new object cannot be simulated.
  • The function code of singleton mode is usually written in a class. If the function design is unreasonable, it is easy to violate the principle of single responsibility.

The single case mode is divided into lazy single case and hungry single case. The difference is that lazy singletons are created only when the object is needed for the first time, while hungry singletons are created when the class is loaded.

The most classic thread safe singleton mode code based on double check:

public class Singleton {
    private static volatile Singleton INSTANCE;
 
    public static Singleton getInstance(){
        if(INSTANCE == null){
            synchronized (Singleton.class){
                if(INSTANCE == null){
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}

2.2 prototype mode( ⭐⭐⭐)

Prototype The (Prototype) pattern is defined as follows: take an instance that has been created as a Prototype, and create a new object that is the same or similar to the Prototype by copying the Prototype object. Here, the Prototype instance specifies the type of object to be created. It is very efficient to create objects in this way, and there is no need to know the details of object creation. For example, the security of Windows operating system Loading is usually time-consuming, and copying is much faster.

Advantages of prototype mode:

  • Java's built-in prototype pattern is based on the replication of memory binary stream, and its performance is better than that of directly new an object.
  • You can use deep cloning to save the state of an object, and use prototype mode to copy an object and save its state, which simplifies the process of creating an object for use when needed (for example, restoring to a certain state in History), and can assist in the implementation of undo.

Disadvantages of prototype mode:

  • You need to configure a clone method for each class
  • The clone method is located inside the class. When modifying an existing class, you need to modify the code, which violates the opening and closing principle.
  • When implementing deep cloning, you need to write more complex code, and when there are multiple nested references between objects, in order to implement deep cloning, the classes corresponding to each layer of objects must support deep cloning, which will be troublesome to implement. Therefore, deep cloning and shallow cloning need to be used properly.

The cloning of prototype pattern can be divided into shallow cloning and deep cloning.
Shallow cloning: create a new object. The properties of the new object are exactly the same as the original object. For non basic type properties, it still points to the memory address of the object pointed to by the original property.
Deep clone: when a new object is created, other objects referenced in the attribute will also be cloned and no longer point to the original object address.

//Concrete prototype class
class Realizetype implements Cloneable {
    Realizetype() {
        System.out.println("The specific prototype was created successfully!");
    }

    public Object clone() throws CloneNotSupportedException {
        System.out.println("Specific prototype copied successfully!");
        return (Realizetype) super.clone();
    }
}

//Prototype pattern test class
public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Realizetype obj1 = new Realizetype();
        Realizetype obj2 = (Realizetype) obj1.clone();
        System.out.println("obj1==obj2?" + (obj1 == obj2));
    }
}

2.3 simple factory mode( ⭐⭐⭐⭐⭐)

In real life, Primitive society is self-sufficient (without factories), small workshops in farming society (simple factories, folk wineries), industrial revolution assembly lines (factory methods, self production and self marketing), and modern industrial chain generation factories (Abstract factories, Foxconn). Our project code is also iterated step by step from simplicity to complexity, but it is becoming simpler and simpler for callers.

In daily development, where complex objects need to be generated, we can try to use factory pattern instead.

Note: the above complex object refers to the situation that too many constructor parameters of the class have an impact on the construction of the class. Because the construction of the class is too complex, if it is used directly in other business classes, the coupling between the two is too heavy, and subsequent business changes need to be changed in any source code referencing the class. It takes time just to find all dependencies, Let alone modify one by one.

Definition of factory pattern: define a factory interface for creating product objects, and postpone the actual creation of product objects to specific sub factory classes. This meets the requirement of "separation of creation and use" in the creation mode.

advantage:

  1. The factory class contains the necessary logical judgment to decide when to create an instance of which product. The client can avoid the responsibility of directly creating product objects and easily create corresponding products. The responsibilities of the factory and products are clearly distinguished.
  2. The client does not need to know the class name of the specific product created, but only needs to know the parameters.
  3. You can also import a configuration file to replace and add new specific product classes without modifying the client code.

Disadvantages:

  1. The factory class of simple factory mode is single, which is responsible for the creation of all products. The responsibility is too heavy. Once it is abnormal, the whole system will be affected. Moreover, the factory class code will be very bloated and violate the principle of high aggregation.
  2. Using the simple factory mode will increase the number of classes in the system (introduce new factory classes), and increase the complexity and understanding difficulty of the system
  3. It is difficult to expand the system. Once new products are added, the factory logic has to be modified. When there are many product types, the logic may be too complex
  4. The simple factory mode uses the static factory method, which makes the factory role unable to form an inheritance based hierarchical structure.

The main roles of the simple factory model are as follows:

  • Simple factory: it is the core of the simple factory pattern and is responsible for implementing the internal logic of creating all instances. The method of creating product class of factory class can be directly called by the outside world to create the required product object.
  • Abstract Product: it is the parent class of all objects created by a simple factory and is responsible for describing the common interface shared by all instances.
  • Concrete product: it is the creation target of simple factory mode.
public class Client {

    //Abstract product
    public interface Product {
        void show();
    }

    //Specific product: ProductA
    static class ConcreteProduct1 implements Product {
        public void show() {
            System.out.println("Specific product 1 display...");
        }
    }

    //Specific product: ProductB
    static class ConcreteProduct2 implements Product {
        public void show() {
            System.out.println("Specific product 2 display...");
        }
    }

    final class Const {
        static final int PRODUCT_A = 0;
        static final int PRODUCT_B = 1;
        static final int PRODUCT_C = 2;
    }

    static class SimpleFactory {
        public static Product makeProduct(int kind) {
            switch (kind) {
                case Const.PRODUCT_A:
                    return new ConcreteProduct1();
                case Const.PRODUCT_B:
                    return new ConcreteProduct2();
            }
            return null;
        }
    }
}

Conclusion: it is to abstract products and obtain different products through a unified factory.

2.4 factory method mode( ⭐⭐⭐⭐)

Factory method pattern "is a further abstraction of simple factory pattern. Its advantage is that the system can introduce new products without modifying the original code, that is, it meets the opening and closing principle.

advantage:

  • Users only need to know the name of the specific factory to get the desired product, without knowing the specific creation process of the product.
  • Flexibility is enhanced. For the creation of new products, you only need to write one more corresponding factory class.
  • Typical decoupling framework. The high-level module only needs to know the abstract class of the product, does not need to care about other implementation classes, and meets the Demeter rule, dependency inversion principle and Richter substitution principle.

Disadvantages:

  • The number of classes is easy to be too many, which increases the complexity
  • It increases the abstraction and understanding difficulty of the system
  • Abstract products can only produce one product, which can be solved by using abstract factory mode.

Application scenario:

  • The customer only knows the name of the factory that created the product, but does not know the specific product name. Such as TCL TV factory, Hisense TV factory, etc.
  • The task of creating objects is completed by one of multiple concrete sub factories, while the abstract factory only provides the interface to create products.
  • Customers don't care about the details of creating products, they only care about the brand of products

The main roles of the factory method pattern are as follows.

  • Abstract Factory: it provides an interface for creating products, through which the caller accesses the factory method newProduct() of a specific factory to create products.
  • Concrete factory: it mainly implements the abstract methods in the abstract factory and completes the creation of specific products.
  • Abstract Product: it defines the specification of the Product and describes the main characteristics and functions of the Product.
  • Concrete product: it implements the interface defined by the abstract product role, which is created by the specific factory and corresponds to the specific factory one by one.
public class AbstractFactoryTest {
    public static void main(String[] args) {
        try {
            Product a;
            AbstractFactory af;
            af = (AbstractFactory) ReadXML1.getObject();
            a = af.newProduct();
            a.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

//Abstract product: provides the interface of the product
interface Product {
    public void show();
}

//Concrete product 1: implement abstract methods in abstract products
class ConcreteProduct1 implements Product {
    public void show() {
        System.out.println("Specific product 1 display...");
    }
}

//Concrete product 2: implement abstract methods in abstract products
class ConcreteProduct2 implements Product {
    public void show() {
        System.out.println("Specific product 2 display...");
    }
}

//Abstract factory: provides the generation method of factory products
interface AbstractFactory {
    public Product newProduct();
}

//Specific factory 1: the generation method of factory products is realized
class ConcreteFactory1 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("Specific factory 1 generation-->Specific products 1...");
        return new ConcreteProduct1();
    }
}

//Specific factory 2: the generation method of factory products is realized
class ConcreteFactory2 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("Specific plant 2 generation-->Specific products 2...");
        return new ConcreteProduct2();
    }
}

Summary: it is to abstract products. Different factories produce different abstract products.

2.5 abstract factory mode

Abstract factory pattern definition: it is a pattern structure that provides an interface for an access class to create a group of related or interdependent objects, and the access class can obtain different levels of products of the same family without specifying the specific class of the product.

Abstract factory pattern is an upgraded version of factory method pattern. Factory method pattern only produces one level of products, while abstract factory pattern can produce multiple levels of products.

The following conditions are generally met when using the abstract factory pattern.

  • There are multiple product families in the system. Each specific factory creates products of the same family but belonging to different hierarchical structures.
  • The system can only consume one family of products at a time, that is, the products of the same family can be used together.

advantage.

  • The multi-level products associated in the product family can be managed together within the class, instead of introducing multiple new classes for management.
  • When a product family is required, the abstract factory can ensure that the client always uses only the product group of the same product.
  • Abstract factory enhances the scalability of the program. When adding a new product family, there is no need to modify the original code to meet the opening and closing principle.

Disadvantages:

  • When a new product needs to be added to the product family, all factory classes need to be modified. It increases the abstraction and understanding difficulty of the system.

The main roles of the abstract factory pattern are as follows.

  • Abstract Factory: it provides an interface for creating products. It contains multiple methods for creating products newProduct(), which can create multiple products of different levels.
  • Concrete Factory: it mainly implements multiple abstract methods in the abstract factory to complete the creation of specific products.
  • Abstract Product: it defines the Product specification and describes the main features and functions of the Product. The abstract factory pattern has multiple Abstract products.
  • Concrete product: it implements the interface defined by the abstract product role and is created by the concrete factory. It has a many-to-one relationship with the concrete factory.

Relevant codes are as follows:

Abstract factory: provides the generation method of products

interface AbstractFactory {
    public Product1 newProduct1();
    public Product2 newProduct2();
}

Specific factory: the product generation method is realized

class ConcreteFactory1 implements AbstractFactory {
    public Product1 newProduct1() {
        System.out.println("Specific factory 1 generation-->Specific products 11...");
        return new ConcreteProduct11();
    }
    public Product2 newProduct2() {
        System.out.println("Specific factory 1 generation-->Specific products 21...");
        return new ConcreteProduct21();
    }
}

Conclusion: Abstract Factory abstracts both products and factories.

Builder Definition of (Builder) pattern: it refers to separating the construction of a complex object from its representation, so that different representations can be created in the same construction process. Such a design pattern is called Builder pattern. It decomposes a complex object into multiple simple objects, and then builds it step by step. It will separate change from invariance, that is, the components of the product are invariable Yes, but each part can be flexibly selected.

advantage:

  • Good encapsulation, separation of construction and representation.
  • Good expansibility, each specific builder is independent of each other, which is conducive to the decoupling of the system.
  • The client does not need to know the details of the internal composition of the product. The builder can gradually refine the creation process without any impact on other modules, so as to control the detail risk.

Disadvantages:

  • The components of the product must be the same, which limits its scope of use.
  • If the internal changes of the product are complex and the internal changes of the product occur, the builder should also modify them synchronously, and the later maintenance cost is large.

The concerns of builder mode and factory mode are different: Builder mode pays attention to the assembly process of parts, while factory method mode pays more attention to the creation process of parts, but the two can be used together.

The main roles of the Builder pattern are as follows.

  • Product role: it is a complex object containing multiple components, and its components are created by specific builders.
  • Abstract Builder: it is an interface that contains abstract methods for creating various sub parts of a product, and usually contains a method getResult() that returns a complex product.
  • Concrete Builder: implement the builder interface and complete the specific creation method of various components of complex products.
  • Director: it calls the component construction and assembly methods in the builder object to complete the creation of complex objects. The director does not involve the information of specific products.

The code is as follows:

1. Product role: a complex object containing multiple components

class Product {
    private String partA;
    private String partB;
    private String partC;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    public void setPartC(String partC) {
        this.partC = partC;
    }

    public void show() {
        //Displays the characteristics of the product
    }
}

2. Abstract Builder: it includes the abstract method of creating each sub part of the product

abstract class Builder {
    //Create product object
    protected Product product = new Product();

    public abstract void buildPartA();

    public abstract void buildPartB();

    public abstract void buildPartC();

    //Return product object
    public Product getResult() {
        return product;
    }
}

3. Concrete Builder: the abstract builder interface is implemented

public class ConcreteBuilder extends Builder {
    public void buildPartA() {
        product.setPartA("build PartA");
    }

    public void buildPartB() {
        product.setPartB("build PartB");
    }

    public void buildPartC() {
        product.setPartC("build PartC");
    }
}

4. Commander: call the method in the builder to complete the creation of complex objects

class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    //Product construction and assembly method
    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}

5. Customers

public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product product = director.construct();
        product.show();
    }
}

3. Structural mode

Structural patterns describe how classes or objects can be arranged into larger structures. It is divided into class structured pattern and object structured pattern. The former uses inheritance mechanism to organize interfaces and classes, and the latter uses composition or aggregation to combine objects.

Because the coupling degree of composite relationship or aggregation relationship is lower than that of inheritance relationship and meets the "composite Reuse Principle", the object structured pattern has more flexibility than the class structured pattern.

The structural mode is divided into the following 7 types:

  1. Proxy mode: provides a proxy for an object to control access to the object. That is, the client indirectly accesses the object through the proxy, so as to restrict, enhance or modify some characteristics of the object.

  2. Adapter mode: convert the interface of a class into another interface desired by the customer, so that those classes that cannot work together due to interface incompatibility can work together.

  3. Bridge mode: it separates abstraction from implementation so that they can change independently. It is implemented by using composition relationship instead of inheritance relationship, so as to reduce the coupling between the two variable dimensions of abstraction and implementation.

  4. Decorator mode: dynamically add some responsibilities to objects, that is, add their additional functions.

  5. Facade pattern: provide a consistent interface for multiple complex subsystems to make these subsystems more accessible.

  6. Flyweight mode: use sharing technology to effectively support the reuse of a large number of fine-grained objects.

  7. Composite mode: combines objects into a tree hierarchy, enabling users to have consistent access to individual objects and composite objects.

Among the above seven structural modes, except that the adapter mode is divided into class structural mode and object structural mode, all the others belong to object structural mode. In addition, the first four kinds may be asked in the interview.

3.1 agent mode( ⭐⭐⭐⭐)

Definition of proxy mode: for some reasons, it is necessary to provide a proxy for an object to control access to the object. At this time, the access object is not suitable or cannot directly reference the target object. The proxy object acts as the intermediary between the access object and the target object (for example, AOP in Spring uses the proxy mode).

advantage:

  • Proxy mode plays an intermediary role between the client and the target object and protects the target object;
  • The proxy object can extend the function of the target object;
  • Proxy mode can separate the client from the target object, reduce the coupling of the system to a certain extent, and increase the scalability of the program

Disadvantages:

  • The agent pattern will increase the number of classes in the system design
  • Adding a proxy object between the client and the target object will slow down the request processing speed;
  • It increases the complexity of the system;

The main roles of the agent model are as follows.

  • Abstract Subject class: business methods implemented by declaring real subjects and proxy objects through interfaces or abstract classes.
  • Real Subject class: it implements the specific business in the abstract subject. It is the real object represented by the proxy object and the object to be referenced finally.
  • Proxy class: it provides the same interface as the real topic. It contains references to the real topic. It can access, control or extend the functions of the real topic.

In the code, the general agent will be understood as code enhancement. In fact, it is to add some code logic before and after the original code logic without the caller's perception.

According to the creation period of the agent, the agent mode is divided into static agent and dynamic agent.
Static: the programmer creates a proxy class or a specific tool to automatically generate the source code and then compile it. The proxy class is generated before the program runs The class file already exists.
Dynamic: it is created dynamically by using reflection mechanism when the program is running

package proxy;

public class ProxyTest {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.Request();
    }
}

//Abstract theme
interface Subject {
    void Request();
}

//Real theme
class RealSubject implements Subject {
    public void Request() {
        System.out.println("How to access real topics...");
    }
}

//agent
class Proxy implements Subject {
    private RealSubject realSubject;

    public void Request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.Request();
        postRequest();
    }

    public void preRequest() {
        System.out.println("Preprocessing before accessing a real topic.");
    }

    public void postRequest() {
        System.out.println("Subsequent processing after accessing the real topic.");
    }
}

3.2 Adapter mode( ⭐⭐⭐)

Adapter mode The definition of (adapter) is as follows: convert the interface of a class into another interface desired by the customer, so that those classes that cannot work together due to incompatible interfaces can work together. The adapter mode is divided into class structure mode and object structure mode. The former has higher coupling between classes than the latter, and requires the programmer to understand the relevant groups in the existing component library Because of the internal structure of the component, the application is relatively less.

advantage:

  • The client can call the target interface transparently through the adapter.
  • Reusing the existing classes, programmers do not need to modify the original code and reuse the existing adapter classes.
  • The target class and adapter class are decoupled to solve the problem of inconsistent interface between target class and adapter class.
  • In many business scenarios, it conforms to the opening and closing principle.

Disadvantages:

  • The adapter writing process needs to be comprehensively considered in combination with the business scenario, which may increase the complexity of the system.
  • Increase the difficulty of code reading and reduce the readability of code. Excessive use of adapters will make the system code messy.

The Adapter pattern contains the following main roles.

  • Target interface: the interface expected by the current system business. It can be an abstract class or interface.
  • Adapter class: it is the component interface in the existing component library accessed and adapted.
  • Adapter class: it is a converter that converts the adapter interface into a target interface by inheriting or referencing the adapter object, so that customers can access the adapter in the format of the target interface.

Relevant codes are as follows:

The code of class adapter pattern is as follows:

package adapter;
//Target interface
interface Target
{
    public void request();
}
//Adapter interface
class Adaptee
{
    public void specificRequest()
    {       
        System.out.println("The business code in the adapter is called!");
    }
}
//Class adapter class
class ClassAdapter extends Adaptee implements Target
{
    public void request()
    {
        specificRequest();
    }
}
//Client code
public class ClassAdapterTest
{
    public static void main(String[] args)
    {
        System.out.println("Class adapter mode test:");
        Target target = new ClassAdapter();
        target.request();
    }
}

The code of the object adapter pattern is as follows:

package adapter;
//Object adapter class
class ObjectAdapter implements Target
{
    private Adaptee adaptee;
    public ObjectAdapter(Adaptee adaptee)
    {
        this.adaptee=adaptee;
    }
    public void request()
    {
        adaptee.specificRequest();
    }
}
//Client code
public class ObjectAdapterTest
{
    public static void main(String[] args)
    {
        System.out.println("Object adapter mode test:");
        Adaptee adaptee = new Adaptee();
        Target target = new ObjectAdapter(adaptee);
        target.request();
    }
}

3.3 Bridge mode

The definition of Bridge pattern is as follows: it separates abstraction from implementation so that they can change independently. It is implemented by using composition relationship instead of inheritance relationship, so as to reduce the coupling between the two variable dimensions of abstraction and implementation.

Through the above explanation, we can well feel that the bridge mode follows the Richter substitution principle and dependency inversion principle, and finally realizes the opening and closing principle, which is closed for modification and open for expansion. The advantages and disadvantages of the bridging mode are summarized as follows.

advantage:

  • Separation of abstraction and implementation, strong scalability
  • Comply with the opening and closing principle
  • Comply with the principle of synthetic reuse
  • Its implementation details are transparent to customers

Disadvantages:

  • Because the aggregation relationship is based on the abstraction layer, developers are required to design and program for abstraction, and can correctly identify two independent changing dimensions in the system, which increases the difficulty of system understanding and design.

The Bridge mode contains the following main roles.

  • Abstraction role: defines an abstract class and contains a reference to the implementation object.
  • Refined Abstraction role: it is a subclass of the abstract role, implements the business methods in the parent class, and calls the business methods in the abstract role through the composition relationship.
  • Implementer role: defines the interface of the implementer role, which can be called by the extended abstract role.
  • Concrete implementer role: give the concrete implementation of the implementation role interface.
package bridge;

public class BridgeTest {
    public static void main(String[] args) {
        Implementor imple = new ConcreteImplementorA();
        Abstraction abs = new RefinedAbstraction(imple);
        abs.Operation();
    }
}

//Realize role
interface Implementor {
    public void OperationImpl();
}

//Concrete implementation role
class ConcreteImplementorA implements Implementor {
    public void OperationImpl() {
        System.out.println("Concrete realization(Concrete Implementor)Role is accessed");
    }
}

//Abstract role
abstract class Abstraction {
    protected Implementor imple;

    protected Abstraction(Implementor imple) {
        this.imple = imple;
    }

    public abstract void Operation();
}

//Extended abstract role
class RefinedAbstraction extends Abstraction {
    protected RefinedAbstraction(Implementor imple) {
        super(imple);
    }

    public void Operation() {
        System.out.println("Extended abstraction(Refined Abstraction)Role is accessed");
        imple.OperationImpl();
    }
}

3.4 decorator mode( ⭐⭐⭐⭐)

Definition of Decorator Pattern: it refers to the pattern that dynamically adds some responsibilities (i.e. adds its additional functions) to the object without changing the existing object structure. It belongs to object structure pattern.

advantage:

  • Decorator is a powerful supplement to inheritance. It is more flexible than inheritance. It dynamically extends the function of an object without changing the original object, plug and play
  • Different effects can be achieved by using different decorative classes and the arrangement and combination of these decorative classes
  • The decorator mode fully complies with the opening and closing principle

Disadvantages:

  • Decorator pattern will add many subclasses, and overuse will increase the complexity of the program.

Decorator mode mainly includes the following roles.

  • Abstract Component role: define an abstract interface to standardize objects ready to receive additional responsibilities.
  • Concrete component role: implement abstract components and add some responsibilities to them by decorating roles.
  • Abstract Decorator role: inherits abstract components and contains instances of specific components. You can extend the functions of specific components through its subclasses.
  • Concrete decorator role: implement relevant methods of abstract decoration and add additional responsibilities to specific component objects.
package decorator;

public class DecoratorPattern {
    public static void main(String[] args) {
        Component p = new ConcreteComponent();
        p.operation();
        System.out.println("---------------------------------");
        Component d = new ConcreteDecorator(p);
        d.operation();
    }
}

//Abstract component role
interface Component {
    public void operation();
}

//Specific component role
class ConcreteComponent implements Component {
    public ConcreteComponent() {
        System.out.println("Create concrete component roles");
    }

    public void operation() {
        System.out.println("Calling methods for specific component roles operation()");
    }
}

//Abstract decorative role
class Decorator implements Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        component.operation();
    }
}

//Specific decorative role
class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        addedFunction();
    }

    public void addedFunction() {
        System.out.println("Add additional functions to specific component roles addedFunction()");
    }
}

3.5 appearance mode (Facade mode)

appearance (Facade) mode, also known as Facade mode, is a mode that makes these subsystems more accessible by providing a consistent interface for multiple complex subsystems. This mode has a unified interface to the outside, and external applications do not care about the specific details of internal subsystems, which will greatly reduce the complexity of applications and improve the maintainability of programs .

In our daily coding work, we all use appearance patterns intentionally or unintentionally. As long as the high-level module needs to schedule multiple subsystems (more than two class objects), we will consciously create a new class to encapsulate these subsystems and provide simplified interfaces, so that the high-level module can easily call the functions of these subsystems indirectly. In particular, at this stage, various third-party SDK s and open-source class libraries are likely to use the appearance mode.

advantage:

  • It reduces the coupling between the subsystem and the client, so that the change of the subsystem will not affect the client class calling it.
  • It shields the subsystem components from customers, reduces the number of objects handled by customers, and makes the subsystem easier to use.
  • It reduces the compilation dependency in large software systems and simplifies the migration process of the system between different platforms, because compiling a subsystem will not affect other subsystems or appearance objects.

Disadvantages:

  • It can not well restrict customers from using subsystem classes, which is easy to bring unknown risks.
  • Adding a new subsystem may require modifying the appearance class or the source code of the client, which violates the "opening and closing principle".

The Facade mode contains the following main roles.

  • Facade role: provide a common interface for multiple subsystems.
  • Sub System role: realize some functions of the system, and customers can access it through appearance role.
  • Client role: access the functions of each subsystem through one appearance role.
package facade;

public class FacadePattern {
    public static void main(String[] args) {
        Facade f = new Facade();
        f.method();
    }
}

//Appearance role
class Facade {
    private SubSystem01 obj1 = new SubSystem01();
    private SubSystem02 obj2 = new SubSystem02();
    private SubSystem03 obj3 = new SubSystem03();

    public void method() {
        obj1.method1();
        obj2.method2();
        obj3.method3();
    }
}

//Subsystem roles
class SubSystem01 {
    public void method1() {
        System.out.println("Of subsystem 01 method1()Called!");
    }
}

//Subsystem roles
class SubSystem02 {
    public void method2() {
        System.out.println("Of subsystem 02 method2()Called!");
    }
}

//Subsystem roles
class SubSystem03 {
    public void method3() {
        System.out.println("Of subsystem 03 method3()Called!");
    }
}

3.6 yuan sharing mode

Definition of Flyweight pattern: it uses sharing technology to effectively support the reuse of a large number of fine-grained objects. It greatly reduces the number of objects to be created and avoids the overhead of a large number of similar classes by sharing existing objects, so as to improve the utilization rate of system resources.

advantage:

  • Only one copy of the same object is saved, which reduces the number of objects in the system, thus reducing the pressure on memory caused by fine-grained objects in the system.

Disadvantages:

  • In order for objects to be shared, some states that cannot be shared need to be externalized, which will increase the complexity of the program.
  • Reading the external state of the shared mode will make the running time slightly longer.

The main roles of Xiangyuan mode are as follows.

  • Abstract shared element role (Flyweight): it is the base class of all specific shared element classes. It is the public interface to be implemented by the specific shared element specification. The external state of non shared elements is passed in the form of parameters through methods.
  • Concrete Flyweight role: implement the interface specified in the abstract flyweight role.
  • Unsharable flyweight role: it is an external state that cannot be shared. It is injected into the relevant methods of specific shared elements in the form of parameters.
  • Flyweight Factory role: it is responsible for creating and managing a membership role. When a client object requests a membership object, the membership factory checks whether there is a qualified membership object in the system. If so, it will provide it to the client; if not, it will create a new membership object.
public class FlyweightPattern {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight f01 = factory.getFlyweight("a");
        Flyweight f02 = factory.getFlyweight("a");
        Flyweight f03 = factory.getFlyweight("a");
        Flyweight f11 = factory.getFlyweight("b");
        Flyweight f12 = factory.getFlyweight("b");
        f01.operation(new UnsharedConcreteFlyweight("First call a. "));
        f02.operation(new UnsharedConcreteFlyweight("Second call a. "));
        f03.operation(new UnsharedConcreteFlyweight("3rd call a. "));
        f11.operation(new UnsharedConcreteFlyweight("First call b. "));
        f12.operation(new UnsharedConcreteFlyweight("Second call b. "));
    }
}

//Non meta role
class UnsharedConcreteFlyweight {
    private String info;

    UnsharedConcreteFlyweight(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

//Abstract meta role
interface Flyweight {
    public void operation(UnsharedConcreteFlyweight state);
}

//Specific meta role
class ConcreteFlyweight implements Flyweight {
    private String key;

    ConcreteFlyweight(String key) {
        this.key = key;
        System.out.println("Specific share yuan" + key + "Created!");
    }

    public void operation(UnsharedConcreteFlyweight outState) {
        System.out.print("Specific share yuan" + key + "Called,");
        System.out.println("Non shared meta information is:" + outState.getInfo());
    }
}

//Enjoy yuan factory role
class FlyweightFactory {
    private HashMap<String, Flyweight> flyweights = new HashMap<String, Flyweight>();

    public Flyweight getFlyweight(String key) {
        Flyweight flyweight = (Flyweight) flyweights.get(key);
        if (flyweight != null) {
            System.out.println("Specific share yuan" + key + "It already exists and was successfully obtained!");
        } else {
            flyweight = new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
        }
        return flyweight;
    }
}

3.7 combination mode

Definition of Composite Pattern: sometimes called part whole pattern, it is a pattern that combines objects into a tree hierarchy, which is used to represent the "whole part" relationship, so that users have consistent access to single objects and composite objects. It belongs to structural design pattern.

The combination mode is generally used to describe the relationship between the whole and the part. It organizes the objects into a tree structure. The top-level node is called the root node. The root node can contain branch nodes and leaf nodes, and the branch node and leaf nodes can be contained below the branch node.

advantage:

  • The combination mode enables the client code to deal with single objects and combined objects consistently without caring whether they are dealing with single objects or combined objects, which simplifies the client code;
  • It is easier to add new objects to the assembly, and the client will not change the source code because of the addition of new objects, meeting the "opening and closing principle";

Disadvantages:

  • The design is complex, and the client needs to spend more time to clarify the hierarchical relationship between classes;
  • It is not easy to limit the components in the container;
  • It is not easy to add new functions of components by inheritance;
public class CompositePattern {
    public static void main(String[] args) {
        Component c0 = new Composite();
        Component c1 = new Composite();
        Component leaf1 = new Leaf("1");
        Component leaf2 = new Leaf("2");
        Component leaf3 = new Leaf("3");
        c0.add(leaf1);
        c0.add(c1);
        c1.add(leaf2);
        c1.add(leaf3);
        c0.operation();
    }
}

//Abstract component
interface Component {
    public void add(Component c);

    public void remove(Component c);

    public Component getChild(int i);

    public void operation();
}

//Leaf component
class Leaf implements Component {
    private String name;

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

    public void add(Component c) {
    }

    public void remove(Component c) {
    }

    public Component getChild(int i) {
        return null;
    }

    public void operation() {
        System.out.println("leaf" + name + ": Be visited!");
    }
}

//Branch member
class Composite implements Component {
    private ArrayList<Component> children = new ArrayList<Component>();

    public void add(Component c) {
        children.add(c);
    }

    public void remove(Component c) {
        children.remove(c);
    }

    public Component getChild(int i) {
        return children.get(i);
    }

    public void operation() {
        for (Object obj : children) {
            ((Component) obj).operation();
        }
    }
}

4. Behavioral model

Behavioral pattern is used to describe the complex process control of a program at run time, that is, how multiple classes or objects cooperate with each other to complete tasks that can not be completed by a single object. It involves the allocation of responsibilities between algorithms and objects.

Behavioral patterns are divided into class behavior patterns and object behavior patterns. The former uses inheritance mechanism to allocate behavior between classes, and the latter uses combination or aggregation to allocate behavior between objects. Because the coupling degree of composite relationship or aggregation relationship is lower than that of inheritance relationship and meets the "composite Reuse Principle", the object behavior pattern has more flexibility than the class behavior pattern.

Behavioral pattern is the largest category of GoF design patterns, which includes the following 11 patterns.

  1. Template Method mode: define the algorithm skeleton in an operation and delay some steps of the algorithm to the subclass, so that the subclass can redefine some specific steps of the algorithm without changing the structure of the algorithm.
  2. Strategy pattern: it defines a series of algorithms and encapsulates each algorithm so that they can be replaced with each other, and the change of the algorithm will not affect the customers using the algorithm.
  3. Command mode: encapsulates a request as an object, separating the responsibility of issuing the request from the responsibility of executing the request.
  4. Chain of Responsibility mode: transfer the request from one object in the chain to the next until the request is responded. In this way, the coupling between objects is removed.
  5. State mode: allows an object to change its behavior when its internal state changes.
  6. Observer mode: there is a one to many relationship between multiple objects. When an object changes, it notifies other objects of the change, thereby affecting the behavior of other objects.
  7. Mediator mode: define a mediation object to simplify the interaction between the original objects, reduce the coupling between the objects in the system, and make it unnecessary for the original objects to understand each other.
  8. Iterator pattern: provides a way to sequentially access a series of data in an aggregate object without exposing the internal representation of the aggregate object.
  9. Visitor mode: provide multiple access methods for each element in a collection without changing the collection elements, that is, each element has multiple visitor objects to access.
  10. Memo mode: on the premise of not destroying encapsulation, obtain and save the internal state of an object for later recovery.
  11. Interpreter mode: it provides how to define the grammar of the language and the interpretation method of language sentences, that is, the interpreter.

4.1 template method mode

The definition of Template Method pattern is as follows: define the algorithm skeleton in an operation, and delay some steps of the algorithm to subclasses, so that subclasses can redefine some specific steps of the algorithm without changing the structure of the algorithm. It is a kind of behavioral pattern.

advantage:

  • It encapsulates the invariant part and extends the variable part. It encapsulates the algorithm that is considered to be the invariant part into the parent class, and inherits the variable part algorithm from the subclass, which is convenient for the subclass to continue to expand.
  • It extracts part of the common code from the parent class to facilitate code reuse.
  • Some methods are implemented by subclasses, so subclasses can add corresponding functions through extension, which conforms to the opening and closing principle.

Disadvantages:

  • It is necessary to define a subclass for each different implementation, which will increase the number of classes, make the system larger and the design more abstract, and indirectly increase the complexity of the system implementation.
  • Abstract methods in the parent class are implemented by subclasses, and the execution results of subclasses will affect the results of the parent class, which leads to a reverse control structure, which improves the difficulty of code reading.
  • Due to the shortcomings of the inheritance relationship itself, if a new abstract method is added to the parent class, all subclasses must be changed again.

The template method pattern contains the following main roles.

  • Abstract Class / Abstract Class
    Abstract template class, which is responsible for giving the outline and skeleton of an algorithm. It consists of a template method and several basic methods. These methods are defined as follows.
  1. Template method: defines the skeleton of the algorithm and calls its basic methods in a certain order.
  2. Basic method: it is a step in the whole algorithm, including the following types.
  3. Abstract method: declared in an abstract class and implemented by a concrete subclass.
  4. Concrete method: it has been implemented in an abstract class and can be inherited or overridden in a concrete subclass.
  5. Hook method: it has been implemented in abstract classes, including logical methods for judgment and empty methods that need to be overridden by subclasses.
  • Concrete Class
    The concrete implementation class implements the abstract methods and hook methods defined in the abstract class, which are a constituent step of a top-level logic.
public class TemplateMethodPattern {
    public static void main(String[] args) {
        AbstractClass tm = new ConcreteClass();
        tm.TemplateMethod();
    }
}

//abstract class
abstract class AbstractClass {
    //Template method
    public void TemplateMethod() {
        SpecificMethod();
        abstractMethod1();
        abstractMethod2();
    }

    //Specific method
    public void SpecificMethod() {
        System.out.println("Concrete methods in abstract classes are called...");
    }

    //Abstract method 1
    public abstract void abstractMethod1();

    //Abstract method 2
    public abstract void abstractMethod2();
}

//Specific subclass
class ConcreteClass extends AbstractClass {
    public void abstractMethod1() {
        System.out.println("The implementation of abstract method 1 is called...");
    }

    public void abstractMethod2() {
        System.out.println("The implementation of abstract method 2 is called...");
    }
}

4.2 strategic mode

Strategy (Strategy) pattern definition: this pattern defines a series of algorithms and encapsulates each algorithm so that they can be replaced with each other, and the change of the algorithm will not affect the customers using the algorithm. The policy pattern belongs to the object behavior pattern, which separates the responsibility of using the algorithm from the implementation of the algorithm by encapsulating the algorithm, and delegates it to different objects These algorithms are managed.

advantage:

  • Multiple conditional statements are difficult to maintain, and the use of policy mode can avoid the use of multiple conditional statements, such as if... else statements and switch... case statements.
  • Policy pattern provides a series of reusable algorithm families. Proper use of inheritance can transfer the public code of the algorithm family to the parent class, so as to avoid repeated code.
  • The policy pattern can provide different implementations of the same behavior, and customers can choose different policies according to different time or space requirements.
  • The strategy mode provides perfect support for the opening and closing principle, and can flexibly add new algorithms without modifying the original code.
  • The policy pattern puts the use of the algorithm into the environment class, and the implementation of the algorithm is moved to the specific policy class, which realizes the separation of the two.

Disadvantages:

  • The client must understand the differences between all policy algorithms in order to select the appropriate algorithm class in time.
  • The policy mode creates many policy classes, which increases the difficulty of maintenance.

The main roles of the policy model are as follows.

  • Abstract Strategy class: defines a public interface. Different algorithms implement this interface in different ways. Environmental roles use this interface to call different algorithms, which are generally implemented by interfaces or abstract classes.
  • Concrete Strategy class: implements the interface of abstract policy definition and provides specific algorithm implementation.
  • Context class: holds a reference to a policy class, which is finally called to the client.
public class StrategyPattern {
    public static void main(String[] args) {
        Context c = new Context();
        Strategy s = new ConcreteStrategyA();
        c.setStrategy(s);
        c.strategyMethod();
        System.out.println("-----------------");
        s = new ConcreteStrategyB();
        c.setStrategy(s);
        c.strategyMethod();
    }
}

//Abstract policy class
interface Strategy {
    public void strategyMethod();    //Strategy method
}

//Specific strategy class A
class ConcreteStrategyA implements Strategy {
    public void strategyMethod() {
        System.out.println("Specific strategies A The policy method of is accessed!");
    }
}

//Specific strategy class B
class ConcreteStrategyB implements Strategy {
    public void strategyMethod() {
        System.out.println("Specific strategies B The policy method of is accessed!");
    }
}

//Environment class
class Context {
    private Strategy strategy;

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void strategyMethod() {
        strategy.strategyMethod();
    }
}

4.3 command mode

The definition of Command mode is as follows: encapsulate a request into an object to separate the responsibility of sending the request from the responsibility of executing the request. In this way, the two communicate through the Command object, which is convenient for storing, transmitting, calling, adding and managing the Command object.

advantage:

  • The coupling degree of the system is reduced by introducing middleware (abstract interface).
  • It has good expansibility and is very convenient to add or delete commands. Using the command mode, adding and deleting commands will not affect other classes, and meet the "opening and closing principle".
  • Macro commands can be implemented. Command mode can be combined with combined mode to assemble multiple commands into a combined command, that is, macro command.
  • It is convenient to realize Undo and Redo operations. The command mode can be combined with the memo mode described later to realize the revocation and recovery of commands.
  • You can add additional functions to existing commands. For example, logging, combined with decorator mode, will be more flexible.

Disadvantages:

  • A large number of specific command classes may be generated. Because each specific operation needs to design a specific command class, which will increase the complexity of the system.
  • The result of the command mode is actually the execution result of the receiver, but in order to architecture, decouple the request and implementation in the form of commands, The introduction of additional type structure (the interface between the requestor and the abstract command) increases the difficulty of understanding. However, this is also a common problem of design patterns. Abstraction will inevitably increase the number of classes. Code separation must be more difficult to understand than code aggregation.

The command mode contains the following main roles.

  • Abstract Command class (Command) role: it declares the interface for executing commands and has the abstract method execute() for executing commands.
  • Concrete Command role: it is the concrete implementation class of the abstract command class. It has the receiver object and completes the operation to be executed by calling the receiver's function.
  • Implementer / Receiver role: performs operations related to command functions and is the real implementer of specific command object business.
  • Caller / requester role: it is the sender of a request. It usually has many command objects and executes related requests by accessing the command object. It does not directly access the receiver.
package command;

public class CommandPattern {
    public static void main(String[] args) {
        Command cmd = new ConcreteCommand();
        Invoker ir = new Invoker(cmd);
        System.out.println("Customer access caller's call()method...");
        ir.call();
    }
}

//caller 
class Invoker {
    private Command command;

    public Invoker(Command command) {
        this.command = command;
    }

    public void setCommand(Command command) {
        this.command = command;
    }

    public void call() {
        System.out.println("The caller executes the command command...");
        command.execute();
    }
}

//Abstract command
interface Command {
    public abstract void execute();
}

//order of the day
class ConcreteCommand implements Command {
    private Receiver receiver;

    ConcreteCommand() {
        receiver = new Receiver();
    }

    public void execute() {
        receiver.action();
    }
}

//recipient
class Receiver {
    public void action() {
        System.out.println("Recipient's action()Method called...");
    }
}

4.4 responsibility chain mode( ⭐⭐⭐⭐)

Definition of Chain of Responsibility mode: in order to avoid coupling the request sender with multiple request handlers, all request handlers are connected into a chain by remembering the reference of the next object through the previous object; when a request occurs, the request can be passed along the chain until an object processes it.

Note: responsibility chain mode is also called responsibility chain mode.

In the responsibility chain mode, the customer only needs to send the request to the responsibility chain, and does not need to care about the processing details of the request and the transmission process of the request. The request will be transmitted automatically. Therefore, the responsibility chain decouples the sender of the request from the handler of the request.

advantage:

  • Reduces the coupling between objects. This mode makes an object do not need to know which object handles its request and the structure of the chain, and the sender and receiver do not need to have each other's clear information.
  • It enhances the scalability of the system. New request processing classes can be added as needed to meet the opening and closing principle.
  • Increased flexibility in assigning responsibilities to objects. When the workflow changes, you can dynamically change the members in the chain or transfer their order, or dynamically add or delete responsibilities.
  • The chain of responsibility simplifies the connection between objects. Each object only needs to maintain a reference to its successor without maintaining the references of all other processors, which avoids the use of many if or if ·· else statements.
  • Responsibility sharing. Each class only needs to deal with its own work that should be handled, and the work that should not be handled should be transferred to the next object for completion. The scope of responsibility of each class should be defined and in line with the principle of single responsibility of the class.

Disadvantages:

  • There is no guarantee that every request will be processed. Since a request has no specific receiver, it cannot be guaranteed that it will be processed. The request may not be processed until it reaches the end of the chain.
  • For a long responsibility chain, the processing of requests may involve multiple processing objects, and the system performance will be affected to some extent.
  • The rationality of the establishment of responsibility chain depends on the client, which increases the complexity of the client, and may lead to system errors due to the wrong setting of responsibility chain, such as circular call.

The responsibility chain model mainly includes the following roles.

  • Abstract Handler role: define an interface for processing requests, including abstract processing methods and a subsequent connection.
  • Concrete Handler role: implement the processing method of the abstract handler to judge whether the request can be processed. If the request can be processed, process it. Otherwise, transfer the request to its successor.
  • Client role: create a processing chain and submit a request to the specific handler object of the chain head. It does not care about the processing details and the transmission process of the request.

The essence of responsibility chain mode is to decouple request and processing, so that requests can be transmitted and processed in the processing chain; Understanding the responsibility chain model should understand its model, not its specific implementation. The unique feature of the responsibility chain model is that it combines its node processors into a chain structure, and allows the node to decide whether to process or forward the request, which is equivalent to making the request flow.

package chainOfResponsibility;

public class ChainOfResponsibilityPattern {
    public static void main(String[] args) {
        //Assembly responsibility chain
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        handler1.setNext(handler2);
        //Submit request
        handler1.handleRequest("two");
    }
}

//Abstract handler role
abstract class Handler {
    private Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    public Handler getNext() {
        return next;
    }

    //Method of processing request
    public abstract void handleRequest(String request);
}

//Specific processor role 1
class ConcreteHandler1 extends Handler {
    public void handleRequest(String request) {
        if (request.equals("one")) {
            System.out.println("Specific handler 1 is responsible for processing the request!");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(request);
            } else {
                System.out.println("No one is processing the request!");
            }
        }
    }
}

//Specific processor role 2
class ConcreteHandler2 extends Handler {
    public void handleRequest(String request) {
        if (request.equals("two")) {
            System.out.println("Specific handler 2 is responsible for processing the request!");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(request);
            } else {
                System.out.println("No one is processing the request!");
            }
        }
    }
}

4.5 status mode

Definition of State mode: for stateful objects, complex "judgment logic" is extracted into different State objects, allowing State objects to change their behavior when their internal State changes.

advantage:

  • The structure is clear, and the state mode localizes the behaviors related to a specific state into one state, and separates the behaviors in different states to meet the "single responsibility principle".
  • Display the state transition to reduce the interdependence between objects. Introducing different states into independent objects will make the state transition more explicit and reduce the interdependence between objects.
  • The responsibilities of the status class are clear, which is conducive to the expansion of the program. It is easy to add new states and transitions by defining new subclasses.

Disadvantages:

  • The use of state mode will inevitably increase the number of classes and objects in the system.
  • The structure and implementation of state mode are complex. Improper use will lead to confusion of program structure and code.
  • The state mode does not support the opening and closing principle very well. For the state mode that can switch states, adding a new state class requires modifying the source code responsible for state transformation, otherwise it cannot switch to the new state, and modifying the behavior of a state class also requires modifying the source code of the corresponding class.

The status mode contains the following main roles.

  • Context role: also known as context, it defines the interface required by the client, internally maintains a current state, and is responsible for switching specific states.
  • Abstract State role: define an interface to encapsulate the behavior corresponding to a specific State in an environment object. There can be one or more behaviors.
  • Concrete State role: implement the behavior corresponding to the abstract state, and switch the state if necessary.
public class StatePatternClient {
    public static void main(String[] args) {
        Context context = new Context();    //Create environment      
        context.Handle();    //Processing requests
        context.Handle();
        context.Handle();
        context.Handle();
    }
}

//Environment class
class Context {
    private State state;

    //Defines the initial state of the environment class
    public Context() {
        this.state = new ConcreteStateA();
    }

    //Set new status
    public void setState(State state) {
        this.state = state;
    }

    //Read status
    public State getState() {
        return (state);
    }

    //Processing requests
    public void Handle() {
        state.Handle(this);
    }
}

//Abstract state class
abstract class State {
    public abstract void Handle(Context context);
}

//Specific status class A
class ConcreteStateA extends State {
    public void Handle(Context context) {
        System.out.println("Current status is A.");
        context.setState(new ConcreteStateB());
    }
}

//Specific status class B
class ConcreteStateB extends State {
    public void Handle(Context context) {
        System.out.println("Current status is B.");
        context.setState(new ConcreteStateA());
    }
}

4.6 observer mode( ⭐⭐⭐⭐)

The definition of Observer mode: it refers to the one to many dependency between multiple objects. When the state of an object changes, all objects that depend on it are notified and automatically updated. This mode is sometimes called publish subscribe mode and model view mode. It is an object behavior mode.

advantage:

  • It reduces the coupling relationship between the target and the observer, which is an abstract coupling relationship. Comply with the principle of dependency inversion.
  • A trigger mechanism is established between the target and the observer.

Disadvantages:

  • The dependency between the target and the observer is not completely removed, and circular references may occur.
  • When there are many observers, the announcement takes a lot of time, which affects the efficiency of the program.

The main roles of the observer model are as follows.

  • Abstract Subject role: also known as abstract target class, it provides an aggregation class for saving observer objects, methods for adding and deleting observer objects, and abstract methods for notifying all observers.
  • Concrete Subject role: also known as concrete target class, it implements the notification method in the abstract target. When the internal state of the Concrete Subject changes, it notifies all registered observer objects.
  • Abstract Observer role: it is an abstract class or interface, which contains an abstract method to update itself. It is called when receiving the change notification of a specific topic.
  • Concrete Observer role: implement the abstract method defined in the abstract observer to update its status when notified of the change of the target.
package net.biancheng.c.observer;

import java.util.*;

public class ObserverPattern {
    public static void main(String[] args) {
        Subject subject = new ConcreteSubject();
        Observer obs1 = new ConcreteObserver1();
        Observer obs2 = new ConcreteObserver2();
        subject.add(obs1);
        subject.add(obs2);
        subject.notifyObserver();
    }
}

//Abstract goal
abstract class Subject {
    protected List<Observer> observers = new ArrayList<Observer>();

    //Add observer method
    public void add(Observer observer) {
        observers.add(observer);
    }

    //Delete observer method
    public void remove(Observer observer) {
        observers.remove(observer);
    }

    public abstract void notifyObserver(); //Method of notifying the observer
}

//Specific objectives
class ConcreteSubject extends Subject {
    public void notifyObserver() {
        System.out.println("The specific objectives have changed...");
        System.out.println("--------------");

        for (Object obs : observers) {
            ((Observer) obs).response();
        }

    }
}

//Abstract observer
interface Observer {
    void response(); //reaction
}

//Specific observer 1
class ConcreteObserver1 implements Observer {
    public void response() {
        System.out.println("Specific observer 1 responds!");
    }
}

//Specific observer 1
class ConcreteObserver2 implements Observer {
    public void response() {
        System.out.println("Specific observer 2 responds!");
    }
}

4.7 intermediary model

Definition of mediator pattern: define a mediation object to encapsulate the interaction between a series of objects, so that the coupling between the original objects is loose, and the interaction between them can be changed independently. Mediator pattern is also called mediation pattern, which is a typical application of Demeter's law.

advantage:

  • Each class performs its own duties, which conforms to Dimitri's law.
  • It reduces the coupling between objects and makes objects easy to be reused independently.
  • The one-to-many association between objects is transformed into one-to-one association, which improves the flexibility of the system and makes the system easy to maintain and expand.

Disadvantages:

  • The mediator pattern turns the direct interdependence of multiple objects into the dependency between the mediator and multiple colleague classes. When there are more colleagues, intermediaries will become more bloated, complex and difficult to maintain.

The mediator pattern contains the following main roles.

  • Abstract Mediator role: it is the interface of the Mediator and provides abstract methods for registering and forwarding colleague object information.
  • Concrete Mediator role: implement the mediator interface, define a List to manage colleague objects and coordinate the interaction between various colleague roles. Therefore, it depends on colleague roles.
  • Abstract Colleague class role: define the interface of Colleague class, save the mediator object, provide abstract methods for Colleague object interaction, and realize the public functions of all interacting Colleague classes.
  • Concrete Colleague role: it is the implementer of the abstract colleague class. When it is necessary to interact with other colleague objects, the mediator object is responsible for the subsequent interaction.
package net.biancheng.c.mediator;

import java.util.*;

public class MediatorPattern {
    public static void main(String[] args) {
        Mediator md = new ConcreteMediator();
        Colleague c1, c2;
        c1 = new ConcreteColleague1();
        c2 = new ConcreteColleague2();
        md.register(c1);
        md.register(c2);
        c1.send();
        System.out.println("-------------");
        c2.send();
    }
}

//Abstract mediator
abstract class Mediator {
    public abstract void register(Colleague colleague);

    public abstract void relay(Colleague cl); //forward
}

//Specific intermediary
class ConcreteMediator extends Mediator {
    private List<Colleague> colleagues = new ArrayList<Colleague>();

    public void register(Colleague colleague) {
        if (!colleagues.contains(colleague)) {
            colleagues.add(colleague);
            colleague.setMedium(this);
        }
    }

    public void relay(Colleague cl) {
        for (Colleague ob : colleagues) {
            if (!ob.equals(cl)) {
                ((Colleague) ob).receive();
            }
        }
    }
}

//Abstract colleague class
abstract class Colleague {
    protected Mediator mediator;

    public void setMedium(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void receive();

    public abstract void send();
}

//Specific colleagues
class ConcreteColleague1 extends Colleague {
    public void receive() {
        System.out.println("Specific colleague class 1 received the request.");
    }

    public void send() {
        System.out.println("Specific colleague class 1 sends a request.");
        mediator.relay(this); //Ask the intermediary to forward
    }
}

//Specific colleagues
class ConcreteColleague2 extends Colleague {
    public void receive() {
        System.out.println("Specific colleague class 2 received the request.");
    }

    public void send() {
        System.out.println("Specific colleague class 2 sends a request.");
        mediator.relay(this); //Ask the intermediary to forward
    }
}

4.8 iterator mode

Definition of Iterator pattern: provide an object to access a series of data in an aggregate object sequentially without exposing the internal representation of the aggregate object.

advantage:

  • Access the contents of an aggregate object without exposing its internal representation.
  • The traversal task is left to the iterator, which simplifies the aggregation class.
  • It supports traversing an aggregate in different ways, and you can even customize the subclass of the iterator to support new traversal.
  • Adding new aggregate classes and iterator classes is very convenient without modifying the original code.
  • It has good encapsulation and provides a unified interface for traversing different aggregation structures.

Disadvantages:

  • The number of classes is increased, which increases the complexity of the system to a certain extent.

In daily development, we hardly write iterators ourselves. Unless you need to customize an iterator corresponding to your own data structure, the API provided by the open source framework is fully sufficient.

The iterator pattern mainly includes the following roles.

  • Abstract Aggregate role: defines interfaces for storing, adding, deleting Aggregate objects, and creating iterator objects.
  • Concrete aggregate role: implement the abstract aggregate class and return an instance of a concrete iterator.
  • Abstract Iterator role: defines the interface for accessing and traversing aggregation elements, usually including hasNext(), first(), next(), etc.
  • Concrete iterator role: implement the methods defined in the abstract iterator interface, complete the traversal of aggregate objects, and record the current location of traversal.
package net.biancheng.c.iterator;

import java.util.*;

public class IteratorPattern {
    public static void main(String[] args) {
        Aggregate ag = new ConcreteAggregate();
        ag.add("Sun Yat-sen University");
        ag.add("South China Institute of Technology");
        ag.add("shaoguan university ");
        System.out.print("The aggregated contents include:");
        Iterator it = ag.getIterator();
        while (it.hasNext()) {
            Object ob = it.next();
            System.out.print(ob.toString() + "\t");
        }
        Object ob = it.first();
        System.out.println("\nFirst: " + ob.toString());
    }
}

//Abstract aggregation
interface Aggregate {
    public void add(Object obj);

    public void remove(Object obj);

    public Iterator getIterator();
}

//Specific aggregation
class ConcreteAggregate implements Aggregate {
    private List<Object> list = new ArrayList<Object>();

    public void add(Object obj) {
        list.add(obj);
    }

    public void remove(Object obj) {
        list.remove(obj);
    }

    public Iterator getIterator() {
        return (new ConcreteIterator(list));
    }
}

//Abstract iterator
interface Iterator {
    Object first();

    Object next();

    boolean hasNext();
}

//Concrete iterator
class ConcreteIterator implements Iterator {
    private List<Object> list = null;
    private int index = -1;

    public ConcreteIterator(List<Object> list) {
        this.list = list;
    }

    public boolean hasNext() {
        if (index < list.size() - 1) {
            return true;
        } else {
            return false;
        }
    }

    public Object first() {
        index = 0;
        Object obj = list.get(index);
        ;
        return obj;
    }

    public Object next() {
        Object obj = null;
        if (this.hasNext()) {
            obj = list.get(++index);
        }
        return obj;
    }
}

4.9 Visitor mode

visitor Definition of (Visitor) pattern: it separates the operations that act on each element in a data structure and encapsulates them into independent classes, so that it can add new operations that act on these elements without changing the data structure, and provide multiple access methods for each element in the data structure. It separates the data operations from the data structure, which is in the behavior pattern The most complex model.

advantage:

  • Good scalability. It can add new functions to the elements in the object structure without modifying the elements in the object structure.
  • Good reusability. Visitors can define the general functions of the whole object structure, so as to improve the reuse degree of the system.
  • Good flexibility. Visitor mode decouples the data structure from the operations acting on the structure, so that the operation set can evolve relatively freely without affecting the data structure of the system.
  • Comply with the principle of single responsibility. Visitor mode encapsulates the relevant behaviors to form a visitor, so that the function of each visitor is relatively single.

Disadvantages:

  • Adding new element classes is difficult. In the visitor mode, every time a new element class is added, the corresponding specific operation must be added to each specific visitor class, which violates the "opening and closing principle".
  • Destroy the package. In the visitor pattern, specific elements publish details to visitors, which destroys the encapsulation of objects.
  • Violation of the dependency inversion principle. The visitor pattern relies on concrete classes instead of abstract classes.

The visitor pattern contains the following main roles.

  • Abstract Visitor role: define an interface for accessing concrete elements. Each concrete element class corresponds to an access operation visit(). The parameter type in the operation identifies the accessed concrete elements.
  • Concrete visitor role: it implements each access operation declared in the abstract visitor role and determines what visitors should do when accessing an element.
  • Abstract Element role: declare an interface containing the accept operation accept(), and the accepted visitor object is used as the parameter of the accept() method.
  • Concrete element role: implement the accept() operation provided by the abstract element role, and its method body is usually visitor Visit (this). In addition, the specific elements may also contain relevant operations of their own business logic.
  • Object Structure role: it is a container containing element roles and provides methods for visitor objects to traverse all elements in the container. It is usually implemented by aggregate classes such as List, Set and Map.
import java.util.*;

public class VisitorPattern {
    public static void main(String[] args) {
        ObjectStructure os = new ObjectStructure();
        os.add(new ConcreteElementA());
        os.add(new ConcreteElementB());
        Visitor visitor = new ConcreteVisitorA();
        os.accept(visitor);
        System.out.println("------------------------");
        visitor = new ConcreteVisitorB();
        os.accept(visitor);
    }
}

//Abstract Visitor 
interface Visitor {
    void visit(ConcreteElementA element);

    void visit(ConcreteElementB element);
}

//Specific visitor class A
class ConcreteVisitorA implements Visitor {
    public void visit(ConcreteElementA element) {
        System.out.println("Specific visitors A visit-->" + element.operationA());
    }

    public void visit(ConcreteElementB element) {
        System.out.println("Specific visitors A visit-->" + element.operationB());
    }
}

//Specific visitor class B
class ConcreteVisitorB implements Visitor {
    public void visit(ConcreteElementA element) {
        System.out.println("Specific visitors B visit-->" + element.operationA());
    }

    public void visit(ConcreteElementB element) {
        System.out.println("Specific visitors B visit-->" + element.operationB());
    }
}

//Abstract element class
interface Element {
    void accept(Visitor visitor);
}

//Specific element class A
class ConcreteElementA implements Element {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public String operationA() {
        return "Specific elements A Operation of.";
    }
}

//Specific element class B
class ConcreteElementB implements Element {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public String operationB() {
        return "Specific elements B Operation of.";
    }
}

//Object structure role
class ObjectStructure {
    private List<Element> list = new ArrayList<Element>();

    public void accept(Visitor visitor) {
        Iterator<Element> i = list.iterator();
        while (i.hasNext()) {
            ((Element) i.next()).accept(visitor);
        }
    }

    public void add(Element element) {
        list.add(element);
    }

    public void remove(Element element) {
        list.remove(element);
    }
}

4.10 memo mode

Definition of memo mode: capture the internal state of an object without destroying the encapsulation, and save the state outside the object, so that the object can be restored to the original saved state when necessary. This mode is also called snapshot mode.

advantage:

  • Provides a mechanism to restore state. When users need it, they can easily restore the data to a historical state.
  • The encapsulation of internal state is realized. Except for the initiator who created it, no other object can access this state information.
  • Simplified the human. The initiator does not need to manage and save each backup of its internal status. All status information is saved in the memo and managed by the manager, which is in line with the principle of single responsibility.

Disadvantages:

  • Large resource consumption. If the internal state information to be saved is too much or too frequent, it will occupy a large memory resource.

The main roles of the memo model are as follows.

  • Initiator role: it records the internal status information at the current time, provides the function of creating memos and recovering memo data, and realizes other business functions. It can access all the information in memos.
  • Memo role: responsible for storing the internal status of the initiator and providing these internal status to the initiator when necessary.
  • Caretaker role: manages memos and provides the function of saving and obtaining memos, but it cannot access and modify the contents of memos.
package net.biancheng.c.memento;

public class MementoPattern {
    public static void main(String[] args) {
        Originator or = new Originator();
        Caretaker cr = new Caretaker();
        or.setState("S0");
        System.out.println("Initial state:" + or.getState());
        cr.setMemento(or.createMemento()); //Save status
        or.setState("S1");
        System.out.println("New status:" + or.getState());
        or.restoreMemento(cr.getMemento()); //Restore state
        System.out.println("Restore state:" + or.getState());
    }
}

//memorandum
class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}

//Initiator
class Originator {
    private String state;

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public Memento createMemento() {
        return new Memento(state);
    }

    public void restoreMemento(Memento m) {
        this.setState(m.getState());
    }
}

//controller
class Caretaker {
    private Memento memento;

    public void setMemento(Memento m) {
        memento = m;
    }

    public Memento getMemento() {
        return memento;
    }
}

4.11 interpreter mode

Definition of Interpreter pattern: define a language for the analysis object, define the grammatical representation of the language, and then design a parser to interpret the sentences in the language. That is, analyze the instances in the application by compiling the language. This pattern implements the interface for grammatical expression processing, which interprets a specific context.

The concepts of grammar and sentence mentioned here are the same as those described in the compilation principle. "Grammar" refers to the grammatical rules of the language, and "sentence" is an element in the language set. For example, there are many sentences in Chinese, "I am Chinese" is one of them. A grammar tree can be used to intuitively describe the sentences in the language.

advantage:

  • Good scalability. Because classes are used to represent the grammar rules of the language in the interpreter mode, the grammar can be changed or extended through mechanisms such as inheritance.
  • Easy to implement. Each expression node class in the syntax tree is similar, so it is easier to implement its grammar.

Disadvantages:

  • Low execution efficiency. Interpreter mode usually uses a large number of loops and recursive calls. When the sentences to be interpreted are complex, its running speed is very slow, and the debugging process of the code is also troublesome.
  • Will cause class expansion. Each rule in the Interpreter pattern needs to define at least one class. When there are many grammar rules, the number of classes will increase sharply, making it difficult for the system to manage and maintain.
  • There are few applicable scenarios. In software development, there are very few application examples that need to define language grammar, so this model is rarely used.

The Interpreter pattern contains the following main roles.

  • Abstract Expression role: defines the interface of the interpreter and specifies the interpretation operation of the interpreter, mainly including the interpretation method interpret().
  • Terminal Expression role: it is a subclass of abstract expression, which is used to implement operations related to terminals in grammar. Each terminal in grammar has a specific Terminal Expression corresponding to it.
  • Non terminal expression role: it is also a subclass of abstract expression, which is used to realize the operations related to non terminal in grammar. Each rule in grammar corresponds to a non terminal expression.
  • Context role: it usually contains the data or public functions required by each interpreter. It is generally used to transfer the data shared by all interpreters. Subsequent interpreters can obtain these values from here.
  • Client (Client): the main task is to translate the sentences or expressions that need analysis into the abstract syntax tree described by the interpreter object, then invoke the interpreter's interpretation method, and of course, can indirectly access the interpreter's interpretation method through the role of the environment.
package net.biancheng.c.interpreter;

//Abstract expression class
interface AbstractExpression {
    public void interpret(String info);    //Interpretation method
}

//Terminator expression class
class TerminalExpression implements AbstractExpression {
    public void interpret(String info) {
        //Processing of terminator expressions
    }
}

//Non terminator expression class
class NonterminalExpression implements AbstractExpression {
    private AbstractExpression exp1;
    private AbstractExpression exp2;

    public void interpret(String info) {
        //Processing of non terminator expressions
    }
}

//Environment class
class Context {
    private AbstractExpression exp;

    public Context() {
        //Data initialization
    }

    public void operation(String info) {
        //Call the interpretation method of the related expression class
    }
}

5. Summary

A table is used to summarize 23 design modes:

classificationDesign patternsketchOne sentence inductionobjectiveLife case
Creative design pattern (simply used to create objects)Factory PatternCreate different instances under different conditionsProduct standardization and more efficient productionPackage creation detailsPhysical factory
Singleton PatternEnsure that a class has only one instance and provides a global access pointThere is only one me in the worldGuarantee uniquenessCEO
Prototype PatternCreate new objects by copying prototypesPull out a monkey hair and blow out tens of thousandsCreate objects efficientlyclone
Builder PatternUsed to create complex composite objectsHigh configuration, medium configuration and low configuration. Choose whichever you wantOpen personality configuration stepsOptional
Structural design pattern (focusing on the combination of classes and objects)Proxy PatternProvides a proxy for other objects to control access to this objectI have no resources and no time. I have to find someone else to helpEnhanced responsibilitieswoman matchmaker
Facade PatternProvide a unified interface to access the subsystemOpen a door to the worldUnified access portalReception
Decorator PatternAdd new features to objectsHis uncle and his second uncle are all his unclesFlexible expansion and homologygrilled savory crepe
Flyweight PatternUse object pools to reduce the creation of duplicate objectsOptimize resource allocation and reduce repeated wasteShared resource poolNational Social Security Network
Composite PatternRecursively combine the whole with the part (tree structure), so that the client can process it in a wayPeople together are called gangs, and hearts together are called teamsUnify the whole and the individualOrganization structure tree
Adapter PatternMerge two incompatible classes togetherUniversal chargerCompatible conversionPower adapter
Bridge PatternSeparate two parts that can change independentlyConvention over configurationInheritance is not allowedBridge
Behavioral design patterns (focus on communication between objects)Template PatternDefine a set of process templates and implement the operations in the templates as neededAll processes are standardized. Please override if fine tuning is requiredLogical reusePut the elephant in the fridge
Strategy PatternEncapsulate different algorithms, which can replace each otherAll roads lead to Rome. You decide which oneGive the choice to the userSelect payment method
Chain of Responsibility PatternAll intercepted classes implement a unified interface, and each receiver contains a reference to the next receiver. Connect these objects into a chain and pass requests along the chain until an object processes it.Every man sweeps the snow in front of his door, and never mind the frost on their tilesDecoupling processing logicKick the ball
Iterator PatternProvides a method for sequentially accessing elements in an aggregate objectSit on the assembly line for a day and sweep each packageUnify access to collectionsCheck in one by one
Command PatternEncapsulate the request into a command and record it, which can be revoked and redoneStrategizing, winning thousands of miles awayDecoupling request and processingRemote control
State PatternMake different behaviors according to different statesState drives behavior, and behavior determines stateBinding state and behaviorOrder status tracking
Memo patternSave the state of the object and restore it if necessaryA slip of foot is not eternal hatred. When you want to start again, start againBackup and regret mechanismdrafts
Mediator PatternThe communication association between objects is encapsulated into a mediation class and processed separately, so as to make it loosely coupledI'll give you the contact information. I don't care how to handle itUnified management of network resourcesWechat Moments
Interpreter PatternGiven a language, define its grammatical representation and define an interpreter that uses the identifier to interpret sentences in the languageI want to say "dialect", and all interpretation rights belong to meImplement specific syntax parsingMorse code
Observer PatternNotify the observer of a one to many relationship when the state changesLet me know when you arriveDecouple the observer from the observedalarm clock
Visitor PatternStabilize the data structure and define new operation behaviorThe peak is formed on the side of the ridge, and the distance is differentDecoupling data structures and data operationsKPI assessment
Delegate PatternIt allows object composition to realize the same code reuse as inheritance, and is responsible for task invocation and allocationThis requirement is very simple. I don't care how to realize itOnly responsible for the resultsPower of attorney

Keywords: Java Design Pattern Interview

Added by phast1 on Thu, 16 Dec 2021 08:38:42 +0200