Home >Java >javaTutorial >Detailed introduction to 23 common Java design patterns
This article brings you relevant knowledge about java, which mainly introduces several common design patterns. A design pattern is a set of code design experiences that have been used repeatedly for the purpose of In order to reuse the code, make the code easier to understand by others, and ensure the reliability of the code, I hope it will be helpful to everyone.
## Recommended study: "java tutorial"
1. Overview of design patterns:In fact, there are two categories: concurrent mode and thread pool mode. Use a picture to describe it as a whole: ## 2. Six principles of design patterns:Creative patterns: 5 types in total: factory method pattern, abstract factory pattern, singleton pattern, builder pattern, prototype pattern
- Structural mode: 7 types in total: adapter mode, decorator mode, proxy mode, bridge mode, appearance mode, combination mode, flyweight mode
- Behavioral mode: 11 types in total: Strategy pattern, template method pattern, observer pattern, chain of responsibility pattern, visitor pattern, mediator pattern, iterator pattern, command pattern, state pattern, memo pattern, interpreter pattern
The Open Close Principle refers to being open to expansion and closed to modification. When extending the program, the original code cannot be modified. To achieve this effect, we need to use interfaces or abstract classes
(2) Dependence Inversion Principle ):The dependency inversion principle is the basis of the opening and closing principle, which refers to programming for interfaces and relying on abstraction rather than concrete
(3) Richter Liskov Substitution Principle:The Liskov Substitution Principle is the cornerstone of inheritance and reuse. Only when a subclass can replace the base class and the functions of the system are not affected, the base class can be reused, and subclasses can also add new behaviors to the base class. So the Liskov substitution principle means that wherever a base class can appear, a subclass must appear.
The Liskov substitution principle is a supplement to the "opening and closing principle". The key step to realize the "opening and closing principle" is abstraction, and the inheritance relationship between base classes and subclasses is the concrete implementation of abstraction, so The Liskov substitution principle is a specification of specific steps to achieve abstraction.
(4) Interface Segregation Principle:Using multiple isolated interfaces is better than using a single interface to reduce the coupling between interfaces and dependencies, convenient for upgrades and maintenance
(5) Demeter Principle:The Demeter Principle, also called the least known principle, refers to What is important is that a class should minimize interactions with other entities, making the system functional modules relatively independent and reducing coupling relationships. The original intention of this principle is to reduce the coupling of classes. Although communication with indirect classes can be avoided, communication must occur through an "intermediary". Excessive use of the Demeter principle will produce a large number of intermediaries and Passing classes leads to greater system complexity, so when using Dimit's Law, you have to repeatedly weigh the trade-offs to achieve both a clear structure and high cohesion and low coupling.
(6) Composite Reuse Principle:Try to use combination/aggregation instead of inheritance.
2. Java’s 23 design patterns:
Create a factory class and define an interface to create product classes that implement the same interface. First look at the relationship diagram: (2) Factory method pattern: The factory method pattern is an improvement on the simple factory pattern , the shortcoming of the simple factory is that it does not comply with the "opening and closing principle". Every time a new product category is added, the factory class needs to be modified, which is not conducive to the expansion and maintenance of the system. The factory method abstracts the factory and defines an interface for creating objects. Every time you add a new product, you only need to add the product and the corresponding specific implementation factory class. The specific factory class decides which product to be instantiated, and delays the creation and instantiation of the object to the subclass, so that the design of the factory complies with " "Opening and closing principle", there is no need to modify the original code when expanding. The UML relationship diagram is as follows: (3) Static factory method pattern: The static factory pattern combines the elements in the factory method pattern The method is made static, so there is no need to create an instance, just call it directly. Detailed article on factory method pattern: Creation type of Java design pattern: Detailed explanation of factory pattern (simple factory factory method abstract factory) The Abstract Factory Pattern is mainly used to create families of related objects. When a product family needs to be designed to work together, the abstract factory pattern can ensure that the client always only uses objects in the same product family; and by isolating the generation of specific classes, the client does not need to explicitly specify the specific generation. Class; all concrete factories implement the public interface defined in the abstract factory, so you only need to change the instance of the concrete factory to change the behavior of the entire software system to some extent. But the disadvantage of this model is that it is more troublesome to add new behaviors. If you need to add a new product family object, you need to change the interface and all its subclasses, which will inevitably cause a lot of trouble. The UML structure diagram is as follows: Details of abstract factory pattern: Creation type of Java design pattern: Detailed explanation of factory pattern (simple factory factory method abstraction Factory) The builder pattern decomposes the creation steps of complex products into different methods, making the creation process clearer and thus More precisely control the generation process of complex objects; by isolating the construction and use of complex objects, that is, separating the creation of the product from the product itself, so that the same construction process can create different objects; and each specific builder interacts with each other Independent, so it is easy to replace concrete builders or add new concrete builders. Users can get different product objects by using different concrete builders. The UML structure diagram is as follows: Builder pattern details: Java design pattern creation type: Builder pattern The singleton mode can ensure that there is only one instance of a certain class in the system. The class instantiates itself and provides the public access point of this instance to the entire system, except This public access point cannot access the instance through other means. The advantage of the singleton mode is: There are several ways to write the singleton pattern, there are three main types: lazy man-style singleton, hungry man-style singleton, and registration-style singleton. Details of singleton pattern: Creation type of Java design pattern: singleton pattern The prototype mode is also used for object creation. By using an object as a prototype and copying and cloning it, a new object similar to the source object is generated. The UML class diagram is as follows: In Java, the core of the prototype pattern is the prototype class Prototype. The Prototype class needs to meet the following two conditions: clone() in the Object class The default method is shallow copy. If you want to deep copy the object, you need to customize your own copy logic in the clone() method. Using the prototype mode to create objects not only simplifies the object creation steps, but also has much better performance than creating objects using the new method, because the clone() method of the Object class is a local method and directly operates the memory. In the binary stream, especially when copying large objects, the performance difference is very obvious; Details of prototype pattern: Creation type of Java design pattern: Prototype pattern above We have introduced 5 creative modes, and now we will start to introduce 7 structural modes: adapter mode, decoration mode, proxy mode, appearance mode, bridge mode, combination mode, and flyweight mode. The adapter mode of the object is the origin of various modes, as shown below: The adapter mode is mainly used to A class or interface is converted into the format desired by the client, so that originally incompatible classes can work together, decoupling the target class and the adapter class; at the same time, it also complies with the "opening and closing principle" and can be used without modifying the original code. On the basis of adding a new adapter class; encapsulating the specific implementation in the adapter class is transparent to the client class and improves the reusability of the adapter. However, the disadvantage is that the implementation process of replacing the adapter is relatively complicated. complex. Therefore, the adapter mode is more suitable for the following scenarios: The following is a very vivid example that illustrates what the adapter pattern is: There are three main implementations of the adapter pattern: class Adapter pattern, object adapter pattern, interface adapter pattern. The usage scenarios of the three are as follows: Details of the Adapter Pattern: Structural Type of Java Design Patterns: Adapter Pattern Decoration The decorator pattern can dynamically add some additional responsibilities to the object to expand the function, and select different decorators at runtime to achieve different behaviors; it is more flexible than using inheritance. By arranging and combining different decoration classes, you can create Many different behaviors, resulting in objects with more powerful functions; in line with the "opening and closing principle", the decorated class and the decorated class change independently. Users can add new decorative classes and decorated classes as needed, and then combine them when using , the original code does not need to be changed. The UML structure diagram of the decorator pattern is as follows: The design motivation of the proxy pattern is to access the real object through the proxy object. By establishing an object proxy class, the proxy object controls the reference of the original object. This enables operations on real objects. In the proxy mode, the proxy object mainly plays the role of an intermediary, used to coordinate and connect the caller (i.e. client) and the callee (i.e. target object), which reduces the coupling of the system to a certain extent and also Target object protected. But the disadvantage is that a proxy object is added between the caller and the callee, which may slow down the processing of requests. The UML structure diagram is as follows: Details of the agent pattern: Structural type of Java design pattern: Agent pattern The bridge mode separates and decouples the abstract part and the implementation part of the system so that they can change independently. In order to achieve the purpose of allowing the abstract part and the implementation part to change independently, the bridge mode uses a combination relationship instead of an inheritance relationship. The abstract part has an interface object of the implementation part, so that the functions of the specific implementation part can be called through this interface object. In other words, the bridge in the bridge mode is a one-way relationship, and only the abstract part can use the objects of the implementation part, but not the other way around. The bridge mode is in line with the "open and closing principle", which improves the systemic availability. In the two changes dimensions, one dimension does not need to be modified. Hide implementation details. However, since the aggregation relationship is established at the abstraction layer, developers are required to program for abstraction, which increases the difficulty of understanding and designing the system. The UML structure diagram of the bridge mode is as follows: The combination mode recursively combines leaf objects and container objects to form a tree structure to represent the "part-whole" hierarchical structure, allowing users to Single objects and composite objects are used consistently, and composite objects can be treated like leaf objects without distinction, allowing user programs to be decoupled from the internal structure of complex elements. The most critical thing about the combination pattern is that leaf objects and combination objects implement the same abstract construction class. It can represent both leaf objects and container objects. Customers only need to program for this abstract construction class. This is why the combined pattern treats leaf nodes and object nodes consistently. The UML structure diagram of the combination pattern is as follows: Details of the combination pattern: Structural type of Java design pattern: combination pattern The flyweight mode effectively supports fine-grained object reuse with small state changes through sharing technology. When there are multiple identical objects in the system, only one copy is shared. It is not necessary to instantiate an object each time, which greatly reduces the number of objects in the system, thereby saving resources. The core of the flyweight model is the flyweight factory class. The flyweight factory class maintains an object storage pool. When the client needs an object, it first obtains it from the flyweight pool. If there is an object in the flyweight pool, The instance is returned directly. If it does not exist in the flyweight pool, a new flyweight object instance is created and returned to the user, and the new object is saved in the flyweight pool. This has the meaning of a singleton. Factory classes usually use collection types to save objects, such as HashMap, Hashtable, Vector, etc. In Java, database connection pools, thread pools, etc. are all applications that use the Flyweight pattern. The UML structure diagram of the flyweight pattern is as follows: In Java, the String type uses the flyweight pattern. The String object is a final type. Once the object is created It cannot be changed. Java's string constants are stored in the string constant pool, and the JVM will ensure that there is only one copy of a string constant in the constant pool. And when it comes to shared pools, we can easily think of the JDBC connection pool in Java. Through the management of the connection pool, the sharing of database connections is realized, without the need to re-create the connection every time, saving the database The overhead of re-creation improves the performance of the system! Details of Flyweight Pattern: Structural Type of Java Design Pattern: Flyweight Pattern We have introduced 7 structural design patterns before, and next we will introduce 11 Behavioral design patterns: Strategy pattern, Template method pattern, Observer pattern, Iterative sub pattern, Chain of responsibility pattern, Command pattern, Memo pattern, State pattern, Visitor pattern, Mediator pattern, Interpreter pattern. Let’s take a picture first to see the relationship between these 11 patterns: The class will often change or may The changed part is extracted as an abstract strategy interface class, and then an instance of this object is included in the class, so that the class instance can freely call the behavior of the class that implements this interface at runtime. For example, defining a series of algorithms, encapsulating each algorithm, and making them interchangeable, so that the algorithm can change independently of the customers who use it, this is the strategy pattern. The UML structure diagram is as follows: The advantage of the strategy pattern is that it can dynamically change the behavior of the object; but the disadvantage is that many strategy classes will be generated, and the decision-making power of the strategy pattern rests with the user. The system only provides the implementation of different algorithms, so the client must know all the strategy classes and decide which strategy class to use; The strategy mode is suitable for the following scenarios: Details of Strategy Pattern: Behavioral Java Design Pattern: Strategy Pattern Template Method It is implemented based on inheritance. A template method is declared in the abstract parent class, and the execution steps of the algorithm (that is, the algorithm skeleton) are defined in the template method. In the template method pattern, the common parts of the subclass can be implemented in the parent class, while the characteristic parts are delayed to the subclass. You only need to declare the characteristic part as an abstract method in the parent class, so that the subclass Certain steps in the algorithm can be redefined without changing the algorithm structure, and different subclasses can implement these logics in different ways. The advantage of the template method pattern is that it conforms to the "opening and closing principle" and can also achieve code reuse, transfer unchanged behavior to the parent class, and remove duplicate code in the subclass. However, the disadvantage is that different implementations need to define a subclass, resulting in an increase in the number of classes, making the system larger and the design more abstract. The UML diagram of the template method pattern is as follows: Template method details: Behavioral type of Java design pattern: Template method pattern The responsibility chain can organize the request processors into a chain and pass the request along the chain. If a processor can handle the request, it will be processed, otherwise the request will be processed. Leave it to superiors. The client only needs to send the request to the responsibility chain and does not need to pay attention to the request processing details. The request sender and processor are decoupled through the responsibility chain. This is also the design motivation of the responsibility chain. The chain of responsibility model can simplify the interconnection between objects, because neither the client nor the processor has clear information about the other party, and the processor does not know the structure of the responsibility chain. The processor only needs to save a pointer to the subsequent References to candidates without needing to save references to all candidates. In addition, the chain of responsibility model increases the flexibility of the system. We can add or change processors at will, and even change the order of processors. However, it may result in a request not being processed anyway, because it May be placed at the end of the chain. So the responsibility chain model has the following advantages: However, the chain of responsibility model also has some shortcomings: The UML structure diagram of the chain of responsibility pattern is as follows: Details of the chain of responsibility pattern: Behavioral Java design pattern :Chain of responsibility model The Observer pattern is also called the publish-subscribe pattern, which defines a one-to-many dependency relationship between objects. When the state of the target object (observer) changes, all its dependencies (observers) will be notified. An observation target can correspond to multiple observers, and these observers are not related to each other, so observers can be added and deleted as needed, making the system easier to expand and comply with the opening and closing principle; and the observer mode allows the target object and the observation The observers are loosely coupled. Although each other does not know the details of the other, they can still interact. The target object only knows a specific observer list, but does not know any specific observer. It only knows that they all have a common interface. But the disadvantage of the observer pattern is that if there are many observers, it will take a certain amount of time to notify all observers. If there is a circular dependency between the observer and the observed, it may cause the system to crash. , and the observer mode does not have a corresponding mechanism for the observer to know how the observed object has changed, but only to know that the observation target has changed. The UML structure diagram of the observer pattern is as follows: Observer pattern details: Behavioral type of Java design pattern: Observer pattern Visitor mode is a method of separating object data structure and behavior (operations based on data structure). Through this separation, a dynamic visitor can be achieved The effect of adding new operations without making other modifications makes it simple to add new operations that act on these data structures without changing each data structure. It provides multiple access operation methods for different types of data structures. This is access The design motivation of the Pattern. In addition to making new access operations easier, it can also define the operations of the class hierarchy without modifying the existing class hierarchy, and concentrate the access behavior of related element objects into one access Or object, rather than scattered one by one element class. But the disadvantage of the visitor pattern is that it makes it difficult to add new element classes. Each addition of a new element class means adding a new abstract operation to the abstract visitor role, and each Adding corresponding specific operations to a specific visitor class violates the requirements of the "opening and closing principle"; Therefore, the visitor pattern is suitable for objects that rarely change in the structure, but often need to be defined on this object structure A system of new operations that makes it easy to add algorithmic operations; or you need to perform many different and unrelated operations on an object structure, and you need to avoid letting these operations pollute these objects, and you do not want to modify them when adding new operations. These types of scenarios. The UML structure diagram of the visitor pattern is as follows: From the UML structure diagram above we can see that the visitor pattern is mainly divided into two Hierarchy, one is the visitor hierarchy, which provides abstract visitors and concrete visitors, and is mainly used to declare some operations; the other is the element hierarchy, which provides abstract elements and concrete elements, and is mainly used to declare accept operations; and the object The structure ObjectStructure serves as a bridge between the two, storing different types of objects for different visitors to access. The same visitor can access different elements in different ways, so adding new visitors in the visitor mode does not require modifying the existing There is code that can be extended and powerful. Use dual -distribution technology in the visitors mode. The so -called double -point technology is when choosing a method, not only the runtime difference of the message receiver, but also the difference between the running time of the parameters. In the visitor mode, the client passes the specific status as a parameter to the specific visitor. The first dispatch is completed here, and then the specific visitor is used as a parameter in the "specific status" method, and its own this is also passed in as a parameter. , the second dispatch is completed here. Double dispatch means that the resulting execution depends on the type of request and the type of recipient. Details of Visitor Pattern: Behavioral Java Design Pattern: Visitor Pattern The intermediary mode encapsulates a series of object interactions through the intermediary object, turning the complex relationship between the objects between the objects into a simple structure with the core of the intermediary as the core. One-to-one association simplifies the relationship between objects and facilitates understanding; the relationship between each object is decoupled, and each object no longer interacts directly with its associated objects, but interacts with the associated objects through an intermediary object Communicate so that objects can be used relatively independently, improving the reusability of objects and the scalability of the system. In the mediator pattern, the mediator class is at the core. It encapsulates the relationship between all object classes in the system. In addition to simplifying the relationship between objects, it can also further control the interaction between objects. . The UML structure diagram of the mediator pattern is as follows: However, the intermediary object encapsulates the relationship between objects, causing the intermediary object to become larger and more complex. It also bears more responsibilities and is more difficult to maintain. It needs to know each object and the relationship between them. If something goes wrong with the interaction details between them, it will cause problems with the entire system. Details of the Mediator Pattern: Behavioral Java Design Patterns: Mediator Pattern Command Pattern The essence is to encapsulate requests into objects and separate the responsibilities of issuing commands and executing commands. The sender and receiver of the command are completely decoupled. The sender only needs to know how to send the command and does not need to care about how the command is implemented or even whether it is executed. No need to worry about success. The key to the command pattern is the introduction of an abstract command interface. The sender programs for the abstract command interface. Only specific commands that implement the abstract command interface can be associated with the receiver. The advantage of using the command mode is that it reduces the coupling of the system, and new commands can be easily added to the system, and it is also easy to design a combined command. But the disadvantage is that some systems will have too many specific command classes, because a specific command class needs to be designed for each command. The UML structure diagram of the command pattern is as follows: Command pattern details: Behavioral type of Java design pattern: Command pattern The state model allows an object to change its behavior when its internal state changes. The object looks as if its class has been modified, that is to say, The state is atomic to change its behavior, rather than behavior changing the state. When the behavior of an object depends on its attributes, we call these attributes state, and the object is called a state object. For a state object, its behavior depends on its state. For example, if you want to book a room, you can only book it when the room is free. You can only check into the room when you have booked the room or the room is free. For such an object, when its external events interact, its internal state will change, causing its behavior to change accordingly. The UML structure diagram of the state pattern is as follows: From the UML structure diagram above, we can see that the advantages of the state pattern are: (1) Encapsulates the conversion rules, allowing the state transition logic to be integrated with the state object, instead of a huge conditional statement block (2) Put all state-related behaviors into one class, New states can be easily added, and the behavior of the object can be changed by simply changing the object state. But the disadvantages of the state mode are: (1) The state type needs to be determined before enumerating the state (2) It will lead to an increase in the number of system classes and objects number. (3) The support for the "opening and closing principle" is not friendly. Adding a new state class requires modifying the source code responsible for state conversion, otherwise it will not be possible to switch to the new state; and modifying a certain state class The behavior also requires modifying the source code of the corresponding class. So the state pattern is suitable for: the code contains a large number of conditional statements related to the state of the object, and the behavior of the object depends on its state, and its related behavior can be changed according to changes in its state. Details of state pattern: Behavioral type of Java design pattern: state pattern The memo pattern provides a A state recovery mechanism that captures the internal state of an object at a certain moment without destroying the encapsulation and saves it outside the object to ensure that the object can be restored to a certain historical state; the memo mode encapsulates the saved details in In the memo, no other object can access it except the creator who created it, and it is implemented that even changing the saved details does not affect the client. However, the memo mode is multi-state and multi-backup, which will use more memory and consume resources. The UML structure diagram of the memo pattern is as follows: The core of the memo mode is the memento. What is stored in the memo is part or all of the status information of the originator. This status information cannot be accessed by other objects, which means that we cannot use it. Objects other than the memo are used to store this state information. If the internal state information is exposed, it violates the principle of encapsulation. Therefore, the memo cannot be accessed by other objects except the originator. Therefore, in order to realize the encapsulation of the memo mode, we need to control the access of the memo: (1) For the originator: all information in the memo can be accessed. (2) For the person in charge, caretaker: The data in the memo cannot be accessed, but he can save the memo and pass the memo to other objects. (3) Other objects: cannot be accessed and cannot be saved. It is only responsible for receiving the memo passed from the person in charge and restoring the status of the original device. Details of memo pattern: Behavioral Java design pattern: memo pattern Iterator pattern provides A way to access individual elements in a collection without exposing their internal representation. Give the responsibility of walking between elements to iterators instead of collection objects, thereby simplifying the implementation of collection containers and allowing the collection container to focus on what it should focus on, which is more in line with the single responsibility principle and avoids the need to The abstract interface layer is filled with various different traversal operations. The UML structure diagram of the iterator pattern is as follows: Iterator pattern details: Behavioral type of Java design pattern: Iterator pattern The interpreter mode is to define the grammar of the language and build an interpreter to interpret the sentences in the language. By building the interpreter, we can solve a frequently occurring problem. Examples of specific types of problems. The interpreter pattern describes how to construct a simple language interpreter. It is mainly used in compilers developed using object-oriented languages. It describes how to define a grammar for a simple language and how to use it in the language. represents a sentence, and how to interpret those sentences. In addition to using grammatical rules to define a language, the interpreter mode can also use abstract syntax trees to express more intuitively and better represent the composition of a language. Each abstract syntax tree corresponds to a Language examples. The abstract syntax tree describes how to form a complex sentence. By analyzing the abstract syntax tree, the terminal and non-terminal symbol classes in the language can be identified. In the interpreter mode, since each terminal expression and non-terminal expression has a specific instance corresponding to it, the system has better scalability. The UML of the interpreter pattern is as follows: Interpreter pattern details: Behavioral type of Java design pattern: Interpreter pattern Recommended study: "java learning tutorial"2. Creation type- Abstract Factory Pattern:
3. Creation-builder pattern:
4. Creation type - singleton mode:
5. Creation type-prototype pattern:
6. Structural-adapter mode:
7. Structural Type - Decorator Pattern:
Details of the decorator pattern: Structural type of Java design pattern: Decorator pattern
8. Structural-proxy pattern:
9. Structural type- Bridge mode:
Details of bridge mode: Structural type of Java design pattern: Bridge mode
10. Structural type-appearance mode: Appearance mode passes the client The client provides a unified interface for accessing a group of interfaces in the subsystem. Using appearance mode has the following advantages: (1) Easier to use: It makes the subsystem easier to use. The client no longer needs to understand the internal implementation of the subsystem, nor does it need to communicate with the internal implementation of many subsystems. To interact with modules, you only need to interact with the appearance class; (2) Loose coupling: Decouple the client from the subsystem, making it easier to expand and maintain modules within the subsystem. (3) Better division of access levels: Through reasonable use of Facade, access levels can be better divided. Some methods are external to the system, and some methods are used internally within the system. Concentrate the functions that need to be exposed to the outside into the facade, which is not only convenient for the client to use, but also hides the internal details well. But if the appearance pattern imposes too many restrictions on the subsystem classes, it will reduce the variability and flexibility. Therefore, the appearance pattern is suitable for providing a simple interface for complex subsystems to improve the usability of the system and scenarios The appearance pattern is introduced to decouple the subsystem from the client and improve the independence and portability of the subsystem. The UML structure diagram of the appearance pattern is as follows:
Appearance pattern details: Structural type of Java design pattern: Appearance pattern
11. Structural-combination mode:
12, Structural-flyweight mode:
13. Behavioral-Strategic Pattern:
14. Behavioral-Template Method:
15 , Behavioral-responsibility chain model:
16. Behavioral-Observer pattern:
17. Behavioral - Visitor mode:
18. Behavioral-Mediator Pattern:
19. Behavioral-Command Pattern:
20. Behavioral-state model:
21. Behavioral type-memo pattern:
22. Behavioral-Iterator pattern:
23. Behavioral-interpreter mode:
The above is the detailed content of Detailed introduction to 23 common Java design patterns. For more information, please follow other related articles on the PHP Chinese website!