Detailed explanation of 23 design patterns in java development (recommended)

Design patterns

-- the basis of Reusable Object-Oriented Software

Design pattern (design pattern) is a set of code design experience that is repeatedly used, known by most people, classified and catalogued. The purpose of using design patterns is to reuse code, make code easier to be understood by others and ensure code reliability. There is no doubt that design patterns win more for themselves, others and the system. Design patterns make code preparation truly engineering and design Pattern is the cornerstone of software engineering, just like a brick of a building. The rational use of design patterns in the project can perfectly solve many problems. Each pattern has corresponding principles to correspond to it. Each pattern describes a recurring problem around us and the core solution of the problem, which is also the reason why it can be widely used. This chapter is the design pattern of the beauty of Java [evolution from rookie to expert]. We will study this chapter in the way of combining theory and practice. We hope that the majority of program lovers can learn the design pattern well and be an excellent software engineer!

1、 Classification of design patterns

Generally speaking, design patterns are divided into three categories:

There are five kinds of creation patterns: factory method pattern, abstract factory pattern, singleton pattern, builder pattern and prototype pattern.

There are seven structural modes: adapter mode, decorator mode, agent mode, appearance mode, bridge mode, combination mode and sharing mode.

There are eleven behavioral modes: strategy mode, template method mode, observer mode, iteration sub mode, responsibility chain mode, command mode, memo mode, status mode, visitor mode, mediator mode and interpreter mode.

In fact, there are two types: merge mode and thread pool mode. Describe it as a whole with a picture:

2、 Six principles of design pattern

1. 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.

2. Liskov Substitution Principle

Liskov Substitution Principle (LSP) is one of the basic principles of object-oriented design. Richter's substitution principle says that where any base class can appear, subclasses must appear. LSP is the cornerstone of inheritance reuse. Only when the derived class can replace the base class and the function of the software unit is not affected, the base class can be truly reused, and the derived class can also add new behavior on the basis of the base class. Richter's substitution principle is a 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 From Baidu Encyclopedia

3. Dependency Inversion Principle

This is the basis of the opening and closing principle. The specific content: true interface programming depends on abstraction rather than concrete.

4. Interface Segregation 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.

5. 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.

6. Composite Reuse Principle

The principle is to try to use composition / aggregation instead of inheritance.

3、 Design patterns in Java

Starting from this, we introduce the concepts and application scenarios of 23 design patterns in Java in detail, and analyze them in combination with their characteristics and the principles of design patterns.

1. Factory method

There are three factory method modes:

11. The common factory pattern is to create a factory class and create instances of some classes that implement the same interface. First look at the diagram below:

Examples are as follows: (let's give an example of sending email and SMS)

First, create a common interface between the two:

Secondly, create an implementation class:

Finally, plant construction:

Let's test:

Output: This is SMS sender!

22. Multiple factory method mode is an improvement on the ordinary factory method mode. In the ordinary factory method mode, if the string passed is wrong, the object cannot be created correctly, while multiple factory method mode provides multiple factory methods to create objects respectively. Diagram:

Modify the above code and change the sendfactory class as follows:

The test classes are as follows:

Output: This is mailsender!

33. Static factory method mode: set the methods in the above factory method modes as static. You can call them directly without creating an instance

Output: This is mailsender!

Generally speaking, the factory pattern is suitable: when a large number of products need to be created and have common interfaces, they can be created through the factory method pattern. In the above three modes, the first one cannot create objects correctly if the incoming string is incorrect. Compared with the second one, the third one does not need to instance the factory class. Therefore, in most cases, we will choose the third one - static factory method mode.

2. Abstract factory pattern

A problem with the factory method pattern is that the creation of classes depends on factory classes, that is, if you want to expand the program, you must modify the factory class, which violates the closure principle. Therefore, from the design point of view, there are certain problems. How to solve them? The abstract factory pattern is used to create multiple factory classes. In this way, once new functions need to be added, new factory classes can be added directly without modifying the previous code. Because the abstract factory is not easy to understand, let's look at the diagram first, and then compare it with the code, which is easier to understand.

Take an example:

Two implementation classes:

Two factory classes:

When providing an interface:

Test class:

In fact, the advantage of this mode is that if you want to add a function: sending timely information, you only need to make an implementation class to implement the sender interface and a factory class to implement the provider interface. It's OK without changing the ready-made code. In this way, the expansibility is better!

3. Singleton mode

Singleton is a common design pattern. In Java applications, singleton can ensure that there is only one instance of the object in a JVM. This pattern has several advantages:

1. Some classes are created frequently, which is a great overhead for some large objects.

2. The new operator is omitted, which reduces the use frequency of system memory and reduces the pressure of GC.

3. Some classes, such as the core trading engine of the exchange, control the trading process. If more than one class can be created, the system will be completely chaotic. (for example, if multiple commanders command at the same time in an army, it will be in a mess). Therefore, only using the single case mode can ensure that the core transaction server can independently control the whole process.

First, we write a simple singleton class:

This class can meet the basic requirements. However, if we put such a class without thread safety protection into a multithreaded environment, there will be problems. How to solve them? We will first think of adding the synchronized keyword to the getInstance method, as follows:

However, the synchronized keyword locks the object. This usage will degrade the performance, because the object must be locked every time getinstance() is called. In fact, it is only necessary to lock the object when it is created for the first time, and then it is not necessary. Therefore, this place needs to be improved. Let's change to the following:

It seems that the problem mentioned earlier has been solved by adding the synchronized keyword internally, that is, locking is not required when calling. Locking is required only when instance is null and an object is created. The performance has been improved to a certain extent. However, in this case, there may still be problems. Look at the following situation: the creation of objects and assignment operations in Java instructions are carried out separately, that is, instance = new singleton(); The statement is executed in two steps. However, the JVM does not guarantee the sequence of these two operations, that is, it is possible that the JVM will allocate space for the new singleton instance, assign it directly to the instance member, and then initialize the singleton instance. In this way, errors may occur. Let's take threads a and B as examples:

a> Threads a and B enter the first if judgment at the same time

b> A first enters the synchronized block. Since instance is null, it executes instance = new singleton();

c> Due to the internal optimization mechanism of the JVM, the JVM first draws some blank memory allocated to the singleton instance and assigns it to the instance member (note that the JVM does not start initializing this instance at this time), and then a leaves the synchronized block.

d> B enters the synchronized block. Since instance is not null at this time, it immediately leaves the synchronized block and returns the result to the program calling the method.

e> At this time, thread B intends to use the singleton instance, but finds that it has not been initialized, so an error occurs.

Therefore, the program may still have errors. In fact, the running process of the program is very complex. From this point, we can see that it is more difficult and challenging to write programs, especially in a multithreaded environment. We further optimized the program:

In fact, the singleton mode uses internal classes to maintain the implementation of singletons. The internal mechanism of the JVM can ensure that when a class is loaded, the loading process of this class is mutually exclusive. In this way, when we call getInstance for the first time, the JVM can help us ensure that instance is created only once and that the memory assigned to instance is initialized, so we don't have to worry about the above problems. At the same time, the method will only use the mutual exclusion mechanism at the first call, which solves the low performance problem. In this way, we temporarily summarize a perfect singleton mode:

In fact, it is not necessarily perfect. If an exception is thrown in the constructor, the instance will never be created and errors will occur. Therefore, there is no perfect thing. We can only choose the implementation method most suitable for our application scenario according to the actual situation. It is also implemented in this way: because we only need to synchronize when creating classes, it is also possible to separate creation from getinstance() and add the synchronized keyword for creation separately:

Considering the performance, the whole program only needs to create an instance once, so the performance will not be affected.

Supplement: the "shadow instance" method is used to update the attributes of a single instance object synchronously

Through the learning of singleton mode, we know that:

1. The singleton pattern is simple to understand, but it is still difficult to implement.

2. The synchronized keyword locks objects. When you use it, you must use it in the right place (pay attention to the objects and processes that need locks. Sometimes not the whole object and the whole process need locks).

At the end, the author suddenly thought of another problem, that is, it is feasible to use the static method of class to realize the effect of singleton mode. What is the difference between the two?

First, static classes cannot implement interfaces. (it's OK from the perspective of class, but that will destroy the static. Because static modified methods are not allowed in the interface, even if they are implemented, they are non-static)

Secondly, a singleton can be initialized late. Static classes are usually initialized when they are loaded for the first time. The reason for delayed loading is that some classes are large, so delayed loading helps to improve performance.

Thirdly, the singleton class can be inherited and its methods can be overridden. However, the internal methods of static classes are static and cannot be overridden.

Finally, the singleton class is flexible. After all, it is only an ordinary Java class in implementation. As long as you meet the basic needs of singleton, you can implement some other functions as you like, but static classes can't. From the above generalizations, we can basically see the difference between the two. On the other hand, the singleton pattern we finally implemented above is internally implemented with a static class. Therefore, the two are very related, but we consider different levels of the problem. The combination of the two ideas can create a perfect solution, just as HashMap uses array + linked list to achieve. In fact, many things in life are like this. Only using different methods to deal with problems always has advantages and disadvantages. The most perfect method is to combine the advantages of various methods to solve problems best!

4. Builder mode (builder)

The factory class mode provides the mode of creating a single class, while the builder mode centralizes various products for management and is used to create composite objects. The so-called composite object means that a class has different properties. In fact, the builder mode is obtained by combining the previous abstract factory mode with the final test. Let's look at the code:

As before, there is a sender interface and two implementation classes mailsender and smssender. Finally, the builder class is as follows:

Test class:

From this point of view, the builder pattern integrates many functions into a class, which can create more complex things. Therefore, the difference from the engineering mode is that the factory mode focuses on creating a single product, while the builder mode focuses on creating conforming objects and multiple parts. Therefore, whether to choose factory mode or builder mode depends on the actual situation.

5. Prototype

Although the prototype mode is a creation mode, it has nothing to do with the engineering mode. From the name, we can see that the idea of this mode is to take an object as a prototype, copy and clone it, and produce a new object similar to the original object. This summary will be explained by copying objects. In Java, the copy object is implemented through clone (). First create a prototype class:

Very simply, a prototype class only needs to implement the clonable interface and override the clone method. Here, the clone method can be changed to any name. Because the clonable interface is an empty interface, you can define the method name of the implementation class arbitrarily, such as clonea or cloneb, because the focus here is super Clone(), super Clone () calls the clone () method of object, but in the object class, clone () is native. How to implement it? I will explain the call of local methods in Java in another article. Here, I will combine shallow copy and deep copy of objects. First, I need to understand the concepts of deep and shallow copy of objects:

Shallow copy: after copying an object, the variables of the basic data type will be recreated, and the reference type still points to the original object.

Deep copy: after copying an object, both basic data types and reference types are recreated. In short, deep replication is a complete and complete replication, while shallow replication is not complete.

Here, write an example of deep and shallow replication:

To realize deep replication, you need to read in the binary input of the current object in the form of stream, and then write the object corresponding to the binary data.

We then discuss design patterns. In the last article, I finished talking about five creation patterns. At the beginning of this chapter, I will talk about seven structural patterns: adapter pattern, decoration pattern, agent pattern, appearance pattern, bridge pattern, combination pattern and sharing pattern. The adapter mode of the object is the origin of various modes. Let's see the following figure:

The adapter class inherits the source class and implements the targetable interface. The following is the test class:

Output:

this is original method! this is the targetable method!

In this way, the implementation class of targetable interface has the function of source class.

Adapter mode for object

The basic idea is the same as the adapter mode of the class, except that the adapter class is modified. This time, it does not inherit the source class, but holds an instance of the source class to solve the compatibility problem. Look at the picture:

Test class:

The output is the same as the first, but the adaptation method is different.

The third adapter mode is the adapter mode of the interface. The adapter of the interface is like this: sometimes there are multiple abstract methods in an interface we write. When we write the implementation class of the interface, we must implement all the methods of the interface, which is obviously wasteful sometimes, because not all the methods are needed, sometimes only some are needed, Here, in order to solve this problem, we introduce the adapter mode of the interface. With the help of an abstract class, the abstract class implements the interface and implements all methods. However, we do not deal with the original interface and only contact the abstract class. Therefore, we write a class, inherit the abstract class and rewrite the methods we need. Take a look at the class diagram:

Abstract class wrapper2:

Test output:

the sourceable interface's first Sub1! the sourceable interface's second Sub2!

Achieved our effect!

After all, let's summarize the application scenarios of three adapter modes:

Class adapter mode: when you want to convert a class to a class that meets another new interface, you can use the class adapter mode to create a new class, inherit the original class and implement the new interface.

Object adapter mode: when you want to transform an object into another object that satisfies another new interface, you can create a Wrapper class that holds an instance of the original class. In the Wrapper class method, the method of invoking the instance is OK.

Adapter mode of interface: when you do not want to implement all methods in an interface, you can create an abstract class wrapper to implement all methods. When we write other classes, we can inherit the abstract class.

7. Decorator

As the name suggests, the decoration mode is to add some new functions to an object, which is dynamic. It is required that the decoration object and the decorated object implement the same interface. The decoration object holds an instance of the decorated object. The relationship diagram is as follows:

Test class:

Output:

before decorator! the original method! after decorator!

Application scenario of decorator mode:

1. You need to extend the function of a class.

2. Dynamically add functions to an object, and it can also be revoked dynamically. (inheritance cannot do this. The inherited function is static and cannot be added or deleted dynamically.)

Disadvantages: too many similar objects are generated, which is not easy to troubleshoot!

8. Proxy mode (proxy)

In fact, the name of each mode indicates the function of the mode. The agent mode is to create one more agent class to perform some operations for the original object. For example, when we rent a house, we go back to find an intermediary. Why? Because you don't have comprehensive information about houses in this area, I hope to find a more familiar person to help you. That's what the agent here means. Another example is that we sometimes have a lawsuit, and we need to hire a lawyer, because lawyers have expertise in law and can operate for us and express our ideas. Let's take a look at the diagram:

Test class:

Output:

before proxy! the original method! after proxy!

Application scenario of agent mode:

If the existing method needs to be improved when used, there are two methods:

1. Modify the original method to adapt. This violates the principle of "opening to expansion and closing to modification".

2. Is to use a proxy class to call the original method and control the results. This method is called proxy mode.

Using the agent mode, the functions can be divided more clearly, which is helpful for later maintenance!

9. Appearance mode (facade)

The appearance mode is to solve the dependency between classes and class homes. Like spring, you can configure the relationship between classes into the configuration file. The appearance mode is to place their relationship in a facade class, reducing the coupling between classes. This mode does not involve interfaces. See the class diagram below: (let's take the startup process of a computer as an example)

Let's first look at the implementation class:

The user class is as follows:

Output:

start the computer! cpu startup! memory startup! disk startup! start computer finished! begin to close the computer! cpu shutdown! memory shutdown! disk shutdown! computer closed!

If we don't have a computer class, CPU, memory and disk will hold instances and have relationships with each other, which will cause serious dependence. Modifying one class may lead to modification of other classes, which is not what we want to see. With a computer class, the relationship between them is placed in the computer class, which plays the role of understanding coupling, Is the appearance mode!

10. Bridge mode

Bridging mode is to separate things from their concrete implementation so that they can change independently. The purpose of bridging is to decouple abstraction and implementation, so that they can change independently. Like the commonly used JDBC bridge drivermanager, when JDBC connects to the database, it basically does not need to change too much code or even not at all. The reason is that JDBC provides a unified interface and each database provides its own implementation, Just use a program called database driver to bridge. Let's look at the diagram:

Implementation code:

Define the interface first:

Define two implementation classes:

Define a bridge that holds an instance of sourceable:

Test class:

output:

this is the first sub! this is the second sub!

In this way, by calling the bridge class, you can call the implementation classes sourcesub1 and sourcesub2 of the interface sourceable. Next, I'll draw another diagram, and you should understand it, because this diagram is the principle of our JDBC connection. It is based on database learning, and you can understand it when combined.

11. Composite mode

The combined mode is sometimes called the partial overall mode, which is more convenient when dealing with problems similar to tree structure. See the relationship diagram:

Usage scenario: combine multiple objects for operation. It is often used to represent tree structure, such as binary tree, number, etc.

12. Flyweight mode

The main purpose of shared meta mode is to share objects, that is, shared pool. When there are many objects in the system, it can reduce the memory overhead. It is usually used together with factory mode.

Flyweightfactory is responsible for creating and managing meta units. When a client requests, the factory needs to check whether there are qualified objects in the current object pool. If so, it will return the existing objects. If not, it will create a new object. Flyweight is a superclass. When it comes to the shared pool, we can easily think of the JDBC connection pool in Java. Considering the characteristics of each connection, it is not difficult to summarize that some objects suitable for sharing have some common attributes. Take the database connection pool for example, URL, driverclassname, username, password and dbname. These attributes are the same for each connection, Therefore, it is suitable to use the shared meta mode to process, build a factory class, take the above similar attributes as internal data and others as external data, and pass them in as parameters during method call, which saves space and reduces the number of instances.

Take an example:

@H_ 502_ 616@

Through the management of connection pool, the sharing of database connection is realized, and the connection does not need to be re created every time, which saves the cost of database re creation and improves the performance of the system! This chapter explains seven structural models. Due to the space problem, the remaining 11 behavioral models,

This chapter is the last lecture on design patterns. It will talk about the third design pattern - behavior pattern, which has 11 kinds: strategy pattern, template method pattern, observer pattern, iteration sub pattern, responsibility chain pattern, command pattern, memo pattern, state pattern, visitor pattern, mediator pattern and Interpreter pattern. I've been writing about design patterns for a long time, and I'm halfway there. Writing a blog is a time-consuming thing, because I have to be responsible for the readers. Whether it's a diagram, code or expression, I hope I can write it as clearly as possible so that the readers can understand it. I think both I and readers want to see high-quality blogs come out, starting from me, I will always stick to it and update it constantly. The driving force comes from the continuous support of readers and friends. I will try my best to write every article! I hope you can continue to give opinions and suggestions and jointly create a perfect blog!

Let's start with a diagram to see the relationship between these 11 modes:

Class 1: implemented through the relationship between parent and child classes. Class II: between two classes. The third category: the status of the class. Category 4: through intermediate classes

13. Strategy

The policy pattern defines a series of algorithms and encapsulates each algorithm so that they can replace each other, and the change of the algorithm will not affect the customers using the algorithm. It is necessary to design an interface to provide a unified method for a series of implementation classes. Multiple implementation classes implement the interface, design an abstract class (optional, belonging to auxiliary class) and provide auxiliary functions. The relationship diagram is as follows:

AbstractCalculator is an auxiliary class that provides auxiliary methods. Next, implement each class in turn:

First, unify the interface:

Auxiliary class:

Three implementation classes:

Simple test class:

Output: 10

The decision-making power of the policy mode lies with the user. The system itself provides the implementation of different algorithms, adds or deletes algorithms, and encapsulates various algorithms. Therefore, policy mode is mostly used in algorithm decision-making system, and external users only need to decide which algorithm to use.

14. Template method

Explain the template method pattern, which means that there is a main method in an abstract class, and then define 1 N methods can be abstract or actual. Define a class, inherit the abstract class, rewrite the abstract method, and call the subclass by calling the abstract class. First look at the relationship diagram:

This is to define a main method calculate in the AbstractCalculator class. Calculate() calls spit(). Plus and minus inherit the AbstractCalculator class respectively and call subclasses through the call to AbstractCalculator. See the following example:

Test class:

I'll trace the execution process of this applet: first, take exp and "\ \ +" as parameters, call the calculate (string, string) method in the AbstractCalculator class, call the same kind of split() in the calculate (string, string), and then call the calculate (int, int) method. From this method, enter the subclass. After executing return num1 + num2, return the value to the AbstractCalculator class, Assign to result and print it out. It just verifies our initial idea.

15. Observer mode (observer)

The next four patterns, including this pattern, are the relationship between classes and do not involve inheritance. You should remember induction and the figure at the beginning of this article. The observer mode is well understood. It is similar to email subscription and RSS subscription. When we browse some blogs or wikis, we often see RSS icons. This means that when you subscribe to the article, you will be notified in time if there are subsequent updates. In fact, simply put, when an object changes, other objects that depend on the object will be notified and change with it! There is a one to many relationship between objects. Let's take a look at the diagram:

Let me explain the role of these classes: the mysubject class is our main object. Observer1 and observer2 are objects that depend on mysubject. When mysubject changes, observer1 and observer2 will inevitably change. Abstractsubject class defines the list of objects to be monitored, which can be modified: add or delete monitored objects, and notify the existing objects in the list when mysubject changes. Let's look at the implementation code:

An observer interface:

Two implementation classes:

Subject interface and implementation class:

Test class:

Output:

update self! observer1 has received! observer2 has received!

In fact, these things are not difficult, but they are abstract and not easy to understand as a whole. It is recommended that readers: create new projects according to the relationship diagram, write their own code (or refer to my code), and go through it according to the overall idea, so as to understand its thought and understand it easily!

16. Iterator

As the name suggests, the iterator pattern is to access the objects in the aggregation sequentially. Generally speaking, it is very common in the collection. If you are familiar with the collection class, it will be very easy to understand this pattern. This sentence contains two meanings: one is the object to be traversed, that is, the aggregate object, and the other is the iterator object, which is used to traverse and access the aggregate object. Let's look at the diagram below:

This idea is as like as two peas we used to do. MyCollection defines some operations of the collection, MyIterator defines a series of iterative operations, and holds Collection instances. Let's look at the implementation code:

Two interfaces:

Two implementations:

Test class:

Output: a b c d e

Here we seem to simulate the process of a collection class. Isn't it cool? In fact, all classes in JDK are also these basic things. Add some design patterns and some optimization together. As long as we learn and master these things, we can also write our own collection classes and even frameworks!

17. Chain of responsibility

Next, we will talk about the responsibility chain pattern. There are multiple objects, and each object holds a reference to the next object. In this way, a chain will be formed, and the request will be passed on the chain until an object decides to process the request. However, the sender does not know which object will handle the request in the end. Therefore, the responsibility chain mode can be implemented to dynamically adjust the system while concealing the client. First look at the diagram:

Abstracthandler class provides get and set methods to facilitate myhandle class to set and modify reference objects. Myhandle class is the core. After instantiation, a series of mutually held objects are generated to form a chain.

Output:

h1deal! h2deal! h3deal!

It is emphasized here that the request on the link can be a chain, a tree or a ring. The pattern itself does not restrict this, and we need to implement it ourselves. At the same time, at one time, the command can only be passed from one object to another, not to multiple objects.

18. Command mode (command)

The command mode is easy to understand. For example, the commander orders the soldiers to do something. From the perspective of the whole thing, the commander's role is to issue a password, which is transmitted to the soldiers' ears and executed by the soldiers. The good thing about this process is that the three are decoupled from each other. Neither party needs to rely on others. It just needs to do its own thing well. The commander wants the result and won't pay attention to how the soldiers achieve it. Let's look at the diagram:

Invoker is the caller (commander), receiver is the callee (soldier), and mycommand is the command. It implements the command interface and holds the receiving object. See the implementation code:

Output: command received!

It's hard to understand that the purpose of command mode is to decouple the sender and executor of commands and separate request and execution. Students familiar with struts should know that struts is actually a technology that separates request and presentation, which must involve the idea of command mode!

In fact, each design pattern is a very important idea. It looks familiar. In fact, it is because we are involved in what we have learned. Although sometimes we don't know, it is reflected everywhere in the design of Java itself, such as AWT, JDBC, collection class, IO pipeline or web framework. Design patterns are everywhere. Because of our limited space, it is difficult to say that each design mode is very detailed, but I will try my best to write the meaning clearly in the limited space and space, so as to better let everyone understand. If there is no accident in this chapter, it should be the last part of the design pattern. First, the figure at the beginning of the previous article:

This chapter deals with the third and fourth categories.

19. Memo mode (memo)

The main purpose is to save a certain state of an object so that the object can be restored at an appropriate time. Personally, I think it is more vivid to call the backup mode. Generally speaking, suppose there is the original class A, a has various attributes, a can determine the attributes to be backed up, memo class B is used to store some internal states of a, and class C is used to store memos, which can only be stored, Operations such as modification are not allowed. Make a diagram to analyze:

The original class is the original class, which contains the attribute value to be saved and creates a memo class to save the value value. Memento class is a memo class, and storage class is a class that stores memos. It holds instances of memento class. This pattern is well understood. Look directly at the source code:

Test class:

Output:

The initialization status is: egg, the modified status is: Niu, and the restored status is: egg

A brief description: when creating a new original class, value is initialized to egg. After modification, the value is set to Niu. Finally, the penultimate line is restored. As a result, it is successfully restored. In fact, I think this mode is called "backup restore" mode.

20. State mode

The core idea is: when the state of the object changes, it changes its behavior at the same time, which is easy to understand! Take QQ as an example. There are several States, such as online, invisible and busy. Each state corresponds to different operations, and your friends can also see your state. Therefore, there are two state modes: 1. Different behaviors can be obtained by changing the state. 2. Your friends can see your changes at the same time. Look at the picture:

State class is a state class, and context class can realize switching. Let's take a look at the code:

Test class:

Output:

execute the first opt! execute the second opt!

According to this feature, the state mode is widely used in daily development, especially when making websites. Sometimes we want to distinguish some of their functions according to a certain attribute of the object, such as simple permission control.

21. Visitor mode

Visitor pattern decouples the data structure from the operations acting on the structure, so that the set of operations can evolve relatively freely. Visitor mode is suitable for systems with relatively stable data structure and easy to change algorithm. Because the visitor mode makes it easy to increase the operation of the algorithm. If the system data structure object is easy to change and new data objects are often added, the visitor mode is not suitable. The advantage of visitor mode is that adding operations is easy, because adding operations means adding new visitors. Visitor pattern centralizes relevant behaviors into a visitor object, and its changes do not affect the system data structure. The disadvantage is that it is difficult to add new data structures From Encyclopedia

In short, visitor mode is a method to separate object data structure and behavior. Through this separation, you can dynamically add new operations for a visitor without making other modifications. Simple diagram:

Let's look at the original code: a visitor class that stores the objects to be accessed,

Subject class, accept method, accept the object to be accessed, and getsubject () gets the attribute to be accessed,

Test:

Output: visit the subject: love

Applicable scenario of this mode: if we want to add new functions to an existing class, we have to consider several things: 1. Will the new functions have compatibility problems with the existing functions? 2. Will it need to be added in the future? 3. What if the class does not allow code modification? The best solution to these problems is to use visitor mode, which is suitable for systems with relatively stable data structure and decouples the data structure from the algorithm,

22. Mediator mode

The mediator pattern is also used to reduce the coupling between classes, because if there are dependencies between classes, it is not conducive to the expansion and maintenance of functions, because as long as one object is modified, other associated objects have to be modified. If you use the mediator mode, you only need to care about the relationship with the mediator class, the relationship between specific classes and scheduling to the mediator, which is a bit like the role of the spring container. First look at the picture:

The user class is a unified interface. User1 and user2 are different objects, and they are related. If the mediator mode is not adopted, they need to hold references to each other, so the coupling between them is very high. In order to decouple, the mediator class is introduced to provide a unified interface. Mymediator is its implementation class, which holds instances of user1 and user2, Used to control user1 and user2. In this way, user1 and user2 are independent of each other. They only need to maintain the relationship with the mediator. The rest is maintained by the mymediator class! Basic implementation:

Test class:

Output:

user1 exe! user2 exe!

23. Interpreter mode

Interpreter mode is our last lecture temporarily. It is generally mainly used in the development of compiler in OOP development, so its application scope is relatively narrow.

Context class is a context environment class. Plus and minus are the implementation of calculation respectively. The code is as follows:

Finally, the correct result is output: 3.

Basically, the interpreter mode is used to do all kinds of interpreters, such as regular expression interpreters and so on!

Original link: http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>