Java 23 Design Model detailed _java

Source: Internet
Author: User
Tags closure data structures inheritance int size memory usage serialization static class wrapper

Design pattern (Patterns)
--the foundation of reusable object-oriented software

Design patterns are a set of repeated use, most people know, through the classification of purpose, code design experience Summary. Design patterns are used in order to reuse code, make code easier for others to understand, and ensure code reliability. There is no doubt that design patterns in others in the system are more win, design patterns so that the code is really engineering, design pattern is the cornerstone of software engineering, like a block of bricks and stones in the building. The rational use of design patterns in the project can perfectly solve many problems, each pattern now has a corresponding principle in place, each of which describes a recurring problem around us and the core solution to the problem, which is why it is widely used. This chapter is the beauty of Java [from rookie to master evolution] series of design patterns, we will combine theory and practice to carry out this chapter of the study, hope that the vast number of program enthusiasts, learn design patterns, to do a good software engineer!
In the process of reading any questions, please contact: egg.

E-mail: xtfggef@gmail.com Weibo: HTTP://WEIBO.COM/XTFGGEF
If reproduced, please indicate the source: http://blog.csdn.net/zhangerqing

Enterprise-class project combat (with Source) address: http://zz563143188.iteye.com/blog/1825168

Operational Dimension Knowledge Finishing http://zz563143188.iteye.com/blog/2094335

23 Modes Java Implementation Source code and collection of five years of development data download address: Http://pan.baidu.com/share/home?uk=4076915866&view=share

I. Classification of design Patterns

Overall, the design pattern is divided into three main categories:
The creation pattern, altogether five kinds: The factory method pattern, the abstract factory pattern, the single case pattern, the builder pattern, the prototype pattern.
Structure mode, a total of seven kinds: Adapter mode, adorner mode, agent mode, appearance mode, bridging mode, combination mode, enjoy meta mode.
There are 11 types of behavioral Patterns: Policy mode, template method pattern, observer mode, iterative sub mode, responsibility chain mode, Command mode, Memo mode, state mode, visitor mode, mediator mode, interpreter mode.

There are two other types of concurrency: concurrent and thread-pool mode. Use a picture to describe the whole:


The six principles of design pattern

1, opening and closing principle (Open close principle)

The opening and closing principle is said to be open to expansion, to modify the closure. When the program needs to expand, can not modify the original code, to achieve a hot-swappable effect. So the bottom line is: In order to make the program more scalable, easy to maintain and upgrade. To achieve this, we need to use interfaces and abstract classes, which we'll refer to later in the specific design.

2, the Richter substitution principle (Liskov substitution principle)

The principle of the Richter substitution (Liskov substitution principle LSP) is one of the basic principles of object-oriented design. The Richter substitution principle says that where any base class can appear, subclasses must be present. LSP is the cornerstone of inheritance reuse, only if the derived class can replace the base class, the function of the Software unit is not affected, the base class can be truly reused, and the derived class can add new behavior on the base class. The principle of the Richter substitution is a supplement to the "open-closed" principle. The key step in implementing the "open-closed" principle is abstraction. And the inheritance relation of the base class and subclass is the concrete realization of abstraction, so the principle of the Richter substitution is the specification of the concrete steps to realize abstraction. --from Baidu Encyclopedia

3. The principle of Reliance reversal (dependence inversion principle)

This is the basis of the open and closed principle, the specific content: true to interface programming, rely on the abstract and not rely on the specific.

4. Interface Isolation principle (Interface segregation principle)

This principle means that using multiple isolated interfaces is better than using a single interface. or a reduction in the coupling between the class meaning, from here we see, in fact, design pattern is a software design idea, from large software architecture, in order to upgrade and maintenance convenience. So there are several times in the above: reduce dependence and reduce coupling.

5. Dimitri (minimum known principle) (Demeter principle)

Why is called the least known principle, that is to say: an entity should be as little as possible with other entities interaction, making the system functional modules relatively independent.

6. Synthetic Reuse principle (composite reuse principle)

The principle is to use the synthesis/aggregation method as much as possible, rather than using inheritance.

Three, Java 23 design pattern

Starting from this piece, we introduce the concept of 23 design Patterns in Java, the application scenarios and so on, and combine their characteristics and design patterns of the principles of analysis.

1. Factory mode (Factory method)

The factory method model is divided into three kinds:

11, the common factory model is to establish a factory class, the implementation of the same interface for some classes to create an instance. First look at the diagram:

Examples are as follows: (we give an example of sending emails and texting)

First, create a common interface between the two:

Public interface Sender {public 
 void Send (); 
} 

Second, create the implementation class:

public class MailSender implements Sender { 
 @Override public 
 void Send () { 
  System.out.println () Mailsender! "); 
 } 
} 
public class Smssender implements Sender { 
 
 @Override public 
 void Send () { 
  System.out.println ("This is SMS Sen Der! "); 
 } 
} 

Finally, build the factory class:

public class Sendfactory {public 
 
 Sender produce (String type) { 
  if (' Mail '. Equals (type)) {return 
   new Mailse NDEr (); 
  } else if ("SMS". Equals (Type)) {return 
   new Smssender (); 
  } else { 
   System.out.println ("Please enter the correct type!"); 
   return null;}}} 
 

Let's test the following:

public class Factorytest {public 
 
 static void Main (string[] args) { 
  Sendfactory factory = new Sendfactory (); 
   sender Sender = factory.produce ("SMS"); 
  Sender. Send (); 
 } 
 

Output: This is SMS sender!

22, a number of factory method models , is the general factory method model improvement, in the ordinary factory method mode, if the string passed in error, you can not create the correct object, and multiple factory method mode is to provide multiple factory methods, create objects. Diagram:

Modify the above code, change the Sendfactory class on the line, as follows:

View Plaincopypublic class Sendfactory {public 
 Sender Producemail () {return 
  new MailSender (); 
 } 
  
 Public Sender producesms () {return 
  new Smssender (); 
 } 
} 

The test classes are as follows:

public class Factorytest {public 
 
 static void Main (string[] args) { 
  Sendfactory factory = new Sendfactory (); 
   sender Sender = Factory.producemail (); 
  Sender. Send (); 
 } 
 

Output: This is mailsender!

33, Static Factory method mode , the above multiple factory method mode to static, do not need to create an instance, direct call can be.

public class Sendfactory {public 
  
 static Sender Producemail () {return 
  new MailSender (); 
 } 
  
 public static Sender Producesms () {return 
  new Smssender (); 
 } 
} 

public class Factorytest {public 
 
 static void Main (string[] args) {  
  Sender Sender = Sendfactory.producemail (); 
   sender. Send (); 
 } 
 

Output: This is mailsender!

In general, the factory pattern is appropriate: whenever a large number of products need to be created and have a common interface, they can be created through the factory method pattern. In the above three modes, the first if the passed-in string is incorrect, the object cannot be created correctly, and the third is relative to the second, no instance chemical plant class is needed, so, in most cases, we will choose the third-static factory method pattern.

2. Abstract Factory Model (abstracts Factory)

Factory method Pattern There is a problem is that the creation of a class depends on the factory class, that is, if you want to expand the program, you must modify the factory class, which violates the closure principle, so from the design point of view, there are certain problems, how to solve? Use the abstract factory pattern to create multiple factory classes so that once you need to add new functionality, you can add new factory classes directly, without needing to modify the previous code. Because the abstract factory is not very understanding, we first look at the map, and then the code, it is easier to understand.

Take a look at the example:

Public interface Sender {public 
 void Send (); 
}

Two implementation classes:

public class MailSender implements Sender { 
 @Override public 
 void Send () { 
  System.out.println () Mailsender! "); 
 } 
} 
The public class Smssender implements Sender { 
 
 @Override public 
 void Send () { 
  System.out.println ("The" is SMS SE Nder! "); 
 } 
} 

Two factory classes:

public class Sendmailfactory implements Provider { 
  
 @Override public 
 Sender Produce () {return 
  new MailSender (); 
 } 
 

public class Sendsmsfactory implements provider{ 
 
 @Override public 
 Sender Produce () {return 
  new Smssender (); 
 } 
 

In providing an interface:

Public interface Provider {public 
 Sender produce (); 
} 

Test class:

public class Test {public 
 
 static void Main (string[] args) { 
  Provider Provider = new Sendmailfactory (); 
  Sender Sender = Provider.produce (); 
  Sender. Send (); 
 } 
 

In fact, the advantage of this model is that if you now want to add a function: Send timely information, you need to do a realization class, realize sender interface, at the same time do a factory class, realize provider interface, OK, no need to change ready-made code. In this way, the expansion of the better!

3. Single case mode (Singleton)

A single Example object (Singleton) is a common design pattern. In Java applications, a singleton object can guarantee that only one instance of the object exists in a JVM. There are several benefits to this pattern:

1, some classes to create more frequent, for some large objects, this is a large amount of system overhead.

2, eliminates the new operator, reduces the system memory usage frequency, reduces the GC pressure.

3, some classes, such as the exchange's core trading engine, control the transaction process, if the class can create multiple words, the system is completely chaotic. (for example, a military presence of several commanders at the same time command, will certainly mess), so only the use of single case mode, to ensure that the core trading server independent control of the entire process.

First we write a simple single example class:

public class Singleton { 
 
 /* holds a private static instance to prevent reference, the assignment is null here to implement deferred loading 
 /private static Singleton instance = null; 
 
 /* Private construction method to prevent being instantiated 
 /private Singleton () { 
 }/ 
 
 * Static Engineering method, create instance 
 /public static Singleton getinstance () {
   if (Instance = = null) { 
   instance = new Singleton (); 
  } 
  return instance; 
 } 
 
 /* If the object is used for serialization, the object can be guaranteed to remain consistent before and after serialization/public object 
 Readresolve () {return 
  instance 
 } 
} 

This class can meet the basic requirements, but, like such a thread-safe class, if we put it into a multithreaded environment, there will be problems, how to solve? We will first think of the getinstance method plus synchronized keyword, as follows:

public static synchronized Singleton getinstance () { 
  if (instance = = null) { 
   instance = new Singleton (); 
  } return 
  instance; 
 } 

However, the Synchronized keyword locks This object, such usage, will be reduced in performance, because each call getinstance (), the object is locked, in fact, only the first time you create the object need to lock, and then do not need, so, This place needs to be improved. Let's change this to the following:

public static Singleton getinstance () { 
  if (instance = null) { 
   synchronized (instance) { 
    if (instance = null { 
     instance = new Singleton (); 
  }}} return instance; 
 } 

It seems to solve the problem mentioned before, add the Synchronized keyword in the internal, that is, when the call is not required to lock, only in instance null, and create objects when the need to add locks, performance has a certain degree of improvement. However, there may be a problem with this scenario: the creation of objects and assignment operations in a Java directive is done separately, i.e. instance = new Singleton (), and the statement is executed in two steps. But the JVM does not guarantee the sequencing of these two operations, which means it is possible for the JVM to allocate space for the new singleton instance and then assign the value directly to the instance member before initializing the singleton instance. This could be an error, we take a, b two threads for example:

A>a and B Threads entered the first if judgment at the same time
B>a first enters the synchronized block, because instance is null, so it executes instance = new Singleton ();
C> because of the internal optimization mechanism of the JVM, the JVM first drew some blank memory allocated to the singleton instance and assigned it to the instance member (note that the JVM did not begin initializing this instance), then a left the synchronized block.
D>b enters the synchronized block, and since instance is not NULL at this time, it immediately leaves the synchronized block and returns the result to the program that invoked the method.
E> at this point the B thread intended to use the singleton instance, but found that it was not initialized, so the error occurred.
So the program is still likely to be wrong, in fact, the program in the running process is very complex, from this we can see, especially in the write multithreaded environment of the program more difficult, challenging. We make further optimizations for this program:

private static class singletonfactory{   
  private static Singleton instance = new Singleton ();   
 }   
 public static Singleton getinstance () {return   
  singletonfactory.instance;   
 } 

The reality is that a single case pattern uses an internal class to maintain a single instance, and the mechanism inside the JVM ensures that when a class is loaded, the loading process of the class is thread-exclusive. So when we first call getinstance, the JVM can help us make sure that the instance is created once and that the memory assigned to instance is initialized so that we don't have to worry about the problem above. At the same time, this method will only use the mutex mechanism at the first call, which solves the low performance problem. This allows us to briefly summarize a perfect single case pattern:

public class Singleton { 
 
 /* Private constructor method to prevent being instantiated 
 /private Singleton () { 
 }/ 
 
 * Here use an internal class to maintain a single 
 instance/private Static class Singletonfactory { 
  private static Singleton instance = new Singleton (); 
 } 
 
 /* Get instance 
 /public static Singleton getinstance () {return 
  singletonfactory.instance; 
 } 
 
 /* If the object is used for serialization, you can ensure that the object is consistent before and after serialization */public Object 
 Readresolve () {return 
  getinstance ()} 
} 

Actually say it is perfect, also not necessarily, if the exception is thrown in the constructor, the instance will never be created and there will be an error. So, the perfect thing is not, we can only according to the actual situation, choose the most suitable for their own application scenario implementation. Others do this: since we only need to synchronize when we create the class, it's OK to separate the creation and getinstance () and create the Synchronized keyword individually:

public class Singletontest { 
 
 private static singletontest instance = null; 
 
 Private Singletontest () { 
 } 
 
 private static synchronized void Syncinit () { 
  if (instance = = null) { 
   Instanc E = new Singletontest (); 
  } 
 } 
 
 public static Singletontest getinstance () { 
  if (instance = null) { 
   syncinit (); 
  } 
  return instance 
 } 
} 

Considering performance, the entire program only needs to create one instance, so performance will not have any effect.

Add: A "shadow instance" approach is used to synchronize updates for the properties of a single Case object

 public class Singletontest {private static singletontest instance = NULL; 
 
 Private Vector properties = null; 
 Public Vector getProperties () {return properties; Private Singletontest () {} private static synchronized void Syncinit () {if (instance = = null) {Insta 
  nce = new Singletontest (); 
  } public static Singletontest getinstance () {if (instance = null) {syncinit (); 
 return instance; 
  public void Updateproperties () {singletontest shadow = new Singletontest (); 
 Properties = Shadow.getproperties (); } 
} 

By learning from a single example model, you tell us:
1, a single example of the model to understand simple, but the specific implementation of a certain degree of difficulty.
2, synchronized keyword locked is the object, in use, must be in the appropriate place to use (note the need to use the lock object and process, may sometimes not the whole object and the whole process need to lock).
Here, the single example mode has been basically finished, at the end, the author suddenly thought of another problem, that is, the use of static methods of class, to achieve the effect of a single case model, is also feasible, where are the two different?
First, a static class cannot implement an interface. (From a class point of view, that's OK, but that would destroy the static.) Because a method of static modification is not allowed in an interface, it is also non-static even if it is implemented.
Second, a single example can be delayed initialization, and static classes are typically initialized at the first load. Delays in loading are due to the fact that some classes are larger, so deferred loading can help improve performance.
Again, a single instance class can be inherited, and his methods can be overwritten. However, static class internal methods are static and cannot be overwritten.
Finally, the single example class is more flexible, after all, from the implementation is just a common Java class, as long as the basic requirements to meet the single example, you can do whatever you want to implement some other functions, but static classes do not. From the above summary, the basic can see the difference between the two, but, on the other hand, we have the last implementation of the single example pattern, the internal is to use a static class to achieve, so, they have a great relationship, but we consider the level of the problem is different. The combination of two ideas to create a perfect solution, just like HashMap using array + linked list to achieve the same, in fact, many things in life is so, single different methods to deal with the problem, there are always advantages and disadvantages, the most perfect method, combined with the advantages of each method, can best solve the problem!

4. Builder model (Builder)

The factory class pattern provides a pattern for creating a single class. The builder's model is to centralize all kinds of products to manage, to create composite objects, the so-called composite object refers to a class with different attributes, in fact, the builder model is the previous abstract factory model and the last test combined to get. Let's take a look at the code:
Also as before, a sender interface, two implementation classes MailSender and Smssender. Finally, the builder classes are as follows:

public class Builder { 
  
 private list<sender> List = new arraylist<sender> (); 
  
 public void Producemailsender (int count) {for 
  (int i=0; i<count; i++) { 
   list.add (new MailSender ()); 
  } 
 Public 
  
 void Producesmssender (int count) {for 
  (int i=0; i<count; i++) { 
   list.add (new Smssender ()); 
  } 
 } 
} 

Test class:

public class Test {public 
 
 static void Main (string[] args) { 
  Builder Builder = new Builder (); 
  Builder.producemailsender (ten); 
 } 
} 

From this point of view, the builder model integrates many functions into a class that can create more complex things. So the difference with the engineering model is that the factory model is concerned with creating a single product, while the builder pattern focuses on creating a conforming object, multiple parts. Therefore, choose the factory model or the builder model, depending on the actual situation.

5. Prototype mode (PROTOTYPE)

Although the prototype model is a model of creation, it has nothing to do with engineering mode, and the idea of the model is to use an object as a prototype, copy it, clone it, and produce a new object similar to the original object. This summary will be explained through the replication of the object. In Java, replication objects are implemented through clone (), creating a prototype class first:

public class Prototype implements cloneable {public 
 
 Object clone () throws Clonenotsupportedexception { 
  Prototype proto = (Prototype) super.clone (); 
  return proto 
 } 
} 

Very simple, a prototype class, only need to implement the Cloneable interface, overwrite the Clone method, where the Clone method can be changed to any name, because the Cloneable interface is an empty interface, you can arbitrarily define the method name of the implementation class, such as Clonea or CLONEB, Because the point here is Super.clone (), Super.clone () calls the object's clone () method, and in the object class, the Clone () is native, specifically how to implement it, and I will, in another article, There is no further discussion here about the call to interpret native methods in Java. Here, I will combine the object's shallow copy and deep copy to say, first need to understand object deep, shallow copy concept:

Shallow copy: When an object is copied, a variable of the base data type is recreated, and the reference type is pointed to or pointed to by the original object.
Deep copy: After copying an object, both the base data type and the reference type are recreated. In short, the deep copy is completely copied, and the shallow copy is not thorough.
Here, write an example of a shade copy:

public class Prototype implements Cloneable, Serializable {private static final long serialversionuid = 1L; 
 
 private string string; 
 
 Private Serializableobject obj; 
  /* Shallow copy */public Object clone () throws Clonenotsupportedexception {Prototype proto = (Prototype) super.clone (); 
 return proto; }/* Deep copy/public object Deepclone () throws IOException, ClassNotFoundException {/* Writes the current object's binary stream * * * Bytearr 
  Ayoutputstream BOS = new Bytearrayoutputstream (); 
  ObjectOutputStream oos = new ObjectOutputStream (BOS); 
 
  Oos.writeobject (this); 
  /* Read the new object generated by the binary stream * * Bytearrayinputstream bis = bytearrayinputstream (Bos.tobytearray ()); 
  ObjectInputStream ois = new ObjectInputStream (bis); 
 return Ois.readobject (); 
 public string getString () {return string; 
 public void SetString (string string) {this.string = string; 
 Public Serializableobject Getobj () {return obj; public void Setobj (Serializableobject obj) {this.obj = obj; 
} class Serializableobject implements Serializable {private static final long serialversionuid = 1L; 
 }

In order to realize deep copy, we need to read the binary input of the current object in the form of stream, and then write out the corresponding object of binary data.
We went on to discuss the design pattern, the last article I finished 5 types of creation mode, this chapter begins, I will talk about the next 7 kinds of structural patterns: Adapter mode, decoration mode, agent mode, appearance mode, bridging mode, combination mode, enjoy meta mode. Where the object's adapter pattern is the origin of various patterns, let's look at the following figure:

The adapter pattern converts the interface of a class to another interface expected by the client, in order to eliminate the compatibility of classes caused by an interface mismatch. Mainly divided into three categories: Class Adapter mode, object adapter mode, interface adapter mode. First, let's look at the adapter pattern for the class, first look at the class diagram:

The core idea is: There is a source class, with a method, to be adapted, the target interface targetable, through the adapter class, the source function extended to the targetable, see Code:

public class Source {public 
 
 void Method1 () { 
  System.out.println (' This is original method! '); 
 } 
 
Public interface Targetable {/ 
 
 * is the same as the method in the original class 
 /public void method1 (); 
 
 /* New class method * 
 /public void method2 (); 
} 
public class Adapter extends Source implements targetable { 
 
 @Override public 
 void Method2 () { 
  System.out.println ("This is the targetable method!"); 
 } 
 

The adapter class inherits the source class, implements the Targetable interface, and the following is a test class:

public class Adaptertest {public 
 
 static void Main (string[] args) { 
  targetable target = new Adapter (); 
  Target.method1 (); 
  TARGET.METHOD2 (); 
 } 
 

Output:
This is original method!
This is the targetable method!

Thus the implementation class of the Targetable interface has the function of the source class.

Adapter mode for Object

The basic idea and class adapter pattern is the same, but the adapter class is modified, this time does not inherit the source class, but holds the source class instance, achieves solves the compatibility question. Look at the picture:

Only need to modify the adapter class of the source code can:

public class Wrapper implements Targetable { 
 
 private source source; 
  
 Public wrapper (source source) { 
  super (); 
  This.source = source; 
 } 
 @Override public 
 void Method2 () { 
  System.out.println (' This is the targetable method! '); 
 } 
 
 @Override public 
 void Method1 () { 
  source.method1 (); 
 } 
} 

Test class:

public class Adaptertest {public 
 
 static void Main (string[] args) { 
  source Source = new source (); 
  targetable target = new wrapper (source); 
  Target.method1 (); 
  TARGET.METHOD2 (); 
 } 
 

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

The third adapter pattern is The adapter mode of the interface, and the adapter for the interface is this: sometimes we write an interface that has multiple abstract methods, and when we write the implementation class for it, we have to implement all the methods of that interface, which is obviously sometimes wasteful, Because not all of the methods are what we need, sometimes we just need some, here to solve this problem, we introduce the adapter pattern of the interface, with the help of an abstract class that implements the interface, implements all the methods, and we do not deal with the original interface, only to get in touch with the abstract class, So we write a class, we inherit the abstract class, we rewrite the method we need. Take a look at the class diagram:

This is well understood, and in actual development, we often encounter too many methods defined in this interface, so that sometimes we are not required in some implementation classes. Look at the code:

Public interface sourceable {public 
  
 void method1 (); 
 public void Method2 (); 
} 

Abstract class Wrapper2:

Public abstract class Wrapper2 implements sourceable{public 
  
 void Method1 () {} public 
 void Method2 () {} 
} 
public class SourceSub1 extends Wrapper2 {public 
 void Method1 () { 
  System.out.println ("The sourceable Interface ' s-sub1!); 
 } 
 

public class SourceSub2 extends Wrapper2 {public 
 void Method2 () { 
  System.out.println ("The sourceable Interface ' s second sub2! "); 
 } 
 
public class Wrappertest {public 
 
 static void Main (string[] args) { 
  sourceable source1 = new SourceSub1 (); 
  sourceable source2 = new SourceSub2 (); 
   
  Source1.method1 (); 
  SOURCE1.METHOD2 (); 
  Source2.method1 (); 
  SOURCE2.METHOD2 (); 
 } 
 

Test output:

The sourceable interface ' s sub1!
The Sourceable interface ' s second sub2!

To achieve our results!
Having said so much, summarize the scenarios for three adapter modes:

class Adapter pattern: When you want to convert a class to a class that satisfies another new interface, you can use the adapter pattern of the class, create a new class, inherit the original class, and implement the new interface.

object's adapter pattern: When you want to convert an object to an object that satisfies another new interface, you can create a wrapper class that holds an instance of the original class, and in the method of the wrapper class, the method of invoking the instance is OK.
Adapter pattern for an interface: When you don't want to implement all the methods in an interface, you can create an abstract class wrapper, implement all the methods, and when we write another class, we inherit the abstract class.

7, Decoration mode (decorator)

As the name suggests, the decoration mode is to add some new features to an object, but also dynamic, require decorative objects and objects to implement the same interface, decorative objects hold an instance of the decorated object, the diagram is as follows:

Source class is decorated class, decorator class is a decorative class, you can dynamically add some functionality for the source class, the code is as follows:

Public interface sourceable {public 
 void method (); 
} 
public class Source implements sourceable { 
 
 @Override public 
 Void Method () { 
  System.out.println () Original method! "); 
 } 
} 
public class Decorator implements sourceable { 
 
 private sourceable source; 
  
 Public decorator (sourceable source) { 
  super (); 
  This.source = source; 
 } 
 @Override public 
 Void Method () { 
  System.out.println ("before decorator!"); 
  Source.method (); 
  System.out.println ("after decorator!"); 
 } 
 

Test class:

public class Decoratortest {public 
 
 static void Main (string[] args) { 
  sourceable Source = new Source (); 
  sourceable obj = new decorator (source); 
  Obj.method (); 
 } 
 

Output:

Before decorator!
The original method!
After decorator!

Application scenario for Adorner mode:
1, need to extend the function of a class.
2, dynamic for an object to add functionality, but also dynamic undo. (Inheritance cannot do this, the inherited functionality is static and cannot be dynamically deleted.) )
Disadvantages: Produce too many similar objects, not easy to row wrong!

8, Agent mode (proxy)

In fact, each pattern name shows the role of the model, Agent mode is more than one proxy class out, for the original object to do some operations, such as we rent a house when back to find an intermediary, why? Because you do not have a comprehensive knowledge of the house in the area, I hope to find a more familiar person to help you do, the agent here is this meaning. And if we have to go to court sometimes, we need to get a lawyer, because the lawyers have the expertise in the law, can carry out the operation for us, express our ideas. Let's take a look at the diagram first:

According to the above elaboration, the proxy mode is easier to understand, we look at the code:

Public interface sourceable {public 
 void method (); 
} 
public class Source implements sourceable { 
 
 @Override public 
 Void Method () { 
  System.out.println () Original method! "); 
 } 
} 

public class Proxy implements sourceable { 
 
 private source source; 
 Public Proxy () { 
  super (); 
  This.source = new Source (); 
 } 
 @Override public 
 Void Method () { 
  before (); 
  Source.method (); 
  Atfer (); 
 } 
 private void Atfer () { 
  System.out.println ("after proxy!"); 
 } 
 private void Before () { 
  System.out.println ("before proxy!"); 
 } 
 

Test class:

public class Proxytest {public 
 
 static void Main (string[] args) { 
  sourceable Source = new Proxy (); 
  Source.method (); 
 } 
 
 

Output:

Before proxy!
The original method!
After proxy!

Application scenario for Agent mode:
If the existing methods need to be improved when they are in use, there are two ways to do this:
1, modify the original method to adapt. This violates the principle of "openness to expansion, closure of modifications".
2, is to use a proxy class to invoke the original method, and the resulting results to control. This method is the proxy mode.
The use of proxy mode, you can divide the function more clearly, to help later maintenance!

9, Appearance mode (façade)

The appearance pattern is to solve the dependencies of class and class family, like spring, relationships between classes and classes can be configured into configuration files, and the appearance pattern is to place their relationships in a façade class, reducing the degree of coupling between class classes, which does not involve interfaces. Look at the class diagram: (We take the startup process of a computer as an example)

Let's look at the implementation class first:

public class CPU {public 
  
 void startup () { 
  System.out.println ("CPU startup!"); 
 } 
  
 public void shutdown () { 
  System.out.println ("CPU shutdown!"); 
 } 
 
public class Memory {public 
  
 void startup () { 
  System.out.println ("Memory startup!"); 
 } 
  
 public void shutdown () { 
  System.out.println ("Memory shutdown!"); 
 } 
 
public class Disk {public 
  
 void startup () { 
  System.out.println ("Disk startup!"); 
 } 
  
 public void shutdown () { 
  System.out.println ("Disk shutdown!"); 
 } 
 
public class Computer { 
 private CPU CPU; 
 Private Memory Memory; 
 private disk disk; 
  
 Public Computer () { 
  CPU = new CPU (); 
  Memory = new memory (); 
  disk = new disk (); 
 } 
  
 public void Startup () { 
  System.out.println ("Start the computer!"); 
  Cpu.startup (); 
  Memory.startup (); 
  Disk.startup (); 
  System.out.println ("Start computer finished!"); 
 } 
  
 public void shutdown () { 
  System.out.println ("Begin to close the computer!"); 
  Cpu.shutdown (); 
  Memory.shutdown (); 
  Disk.shutdown (); 
  SYSTEM.OUT.PRINTLN ("Computer closed!"); 
 } 
 

The user class is as follows:

public class User {public 
 
 static void Main (string[] args) { 
  Computer Computer = new Computer (); 
  Computer.startup (); 
  Computer.shutdown (); 
 } 
 

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 do not have computer class, then CPU, Memory, disk they will hold each other instance, create a relationship, which will cause serious dependencies, modify a class, may bring other classes of changes, this is not what we want to see, with the Computer class, The relationship between them is placed in the computer class, so as to understand the role of coupling, this is the appearance of the model!

10, Bridging mode (bridge)

Bridge mode is to separate things from their specific implementation, so that they can be independent of the changes. Bridging the purpose is: the abstraction and implementation of decoupling, so that the two can be independent changes, like our common JDBC Bridge DriverManager, JDBC to connect the database, the various databases to switch between the basic do not need to move too much code, or even the slightest move, The reason is that JDBC provides a unified interface, each database provides its own implementation, using a program called database-driven to bridge the line. Let's take a look at the diagram:

Implementation code:

First define the interface:

Public interface sourceable {public 
 void method (); 
} 

Define two implementation classes, respectively:

The public class SourceSub1 implements sourceable { 
 
 @Override 
 the public void method () { 
  System.out.println () Is the "" "); 
 } 
} sub! 

public class SourceSub2 implements sourceable { 
 
 @Override public 
 Void Method () { 
  System.out.println () This is the second sub! "); 
 } 
 

Define a bridge that holds an instance of sourceable:

Public abstract class Bridge { 
 private sourceable source; 
 
 public void Method () { 
  source.method (); 
 } 
  
 Public sourceable GetSource () {return 
  source; 
 } 
 
 public void SetSource (sourceable source) { 
  This.source = source; 
 } 
} 
public class Mybridge extends bridge {public 
 void method () { 
  GetSource (). method (); 
 } 
} 

Test class:

public class Bridgetest {public 
  
 static void Main (string[] args) {Bridge bridge 
   
  = new Mybridge (); 
   
  /* Call the first object 
  /* sourceable source1 = new SourceSub1 (); 
  Bridge.setsource (source1); 
  Bridge.method (); 
   
  /* Call the Second object 
  /* sourceable source2 = new SourceSub2 (); 
  Bridge.setsource (SOURCE2); 
  Bridge.method (); 
 } 
 

Output
This is the sub!
This is the second sub!

In this way, through the call of Bridge class, the SourceSub1 and SourceSub2 of the docking port sourceable are realized. Next I draw a diagram, we should understand, because this diagram is the principle of our JDBC connection, there is the basis of database learning, a combination of all understand.

11. Combination mode (composite)

The combination pattern is sometimes called a partial-integral mode to handle problems similar to the tree structure, and look at the diagram:

Look at the code directly:

public class TreeNode { 
  
 private String name; 
 Private TreeNode parent; 
 Private vector<treenode> children = new vector<treenode> (); 
  
 Public TreeNode (String name) { 
  this.name = name; 
 } 
 
 Public String GetName () {return 
  name; 
 } 
 
 public void SetName (String name) { 
  this.name = name; 
 } 
 
 Public TreeNode GetParent () {return 
  parent; 
 } 
 
 public void SetParent (TreeNode parent) { 
  this.parent = parent; 
 } 
  
 Add child node public 
 void Add (TreeNode node) { 
  Children.add (node); 
 } 
  
 Delete child node public 
 void Remove (TreeNode node) { 
  Children.remove (node); 
 } 
  
 Get child node public 
 enumeration<treenode> GetChildren () {return 
  children.elements (); 
 } 
} 
public class Tree { 
 
 TreeNode root = null; 
 
 Public tree (String name) { 
  root = new TreeNode (name); 
 } 
 
 public static void Main (string[] args) {tree tree 
  = new Tree ("A"); 
  TreeNode NodeB = new TreeNode ("B"); 
  TreeNode NodeC = new TreeNode ("C"); 
   
  Nodeb.add (NODEC); 
  Tree.root.add (NodeB); 
  SYSTEM.OUT.PRINTLN ("Build the Tree finished!"); 
 } 
 

Working with scenarios: combining multiple objects to manipulate, often used to represent tree structures, such as binary trees, numbers, and so on.

12, the element mode (Flyweight)

The main purpose of the pattern is to share the object, that is, the shared pool, which can reduce the overhead of memory when there are more objects in the system, and is usually used in conjunction with Factory mode.

Flyweightfactory is responsible for creating and managing the unit, when a client requests, the factory needs to check whether there are eligible objects in the current object pool, if so, to return the existing object, or, if not, to create a new object, flyweight is a superclass. When it comes to sharing pools, we can easily associate the JDBC Connection pool in Java, think about the characteristics of each connection, we are not difficult to sum up: for the sharing of some objects, they have some common attributes, take the database connection pool, URL, Driverclassname, Username, password, and dbname, these attributes are the same for each connection, so it is appropriate to use the Meta mode to deal with, build a factory class, the above similar properties as internal data, and other as external data, in the method call, as a parameter pass in, This saves space and reduces the number of instances.
Look at an example:

Look at the code for the database connection pool:

public class ConnectionPool {private vector&lt;connection&gt; pool; 
 /* Public Properties * * Private String URL = "Jdbc:mysql://localhost:3306/test"; 
 Private String username = "root"; 
 Private String Password = "root"; 
 
 Private String Driverclassname = "Com.mysql.jdbc.Driver"; 
 private int poolsize = 100; 
 private static ConnectionPool instance = NULL; 
 
 Connection conn = null; 
 
  /* Construction method, do some initialization work * * Private ConnectionPool () {pool = new vector&lt;connection&gt; (poolsize); 
    for (int i = 0; i &lt; poolsize i++) {try {class.forname (driverclassname); 
    conn = drivermanager.getconnection (URL, username, password); 
   POOL.ADD (conn); 
   catch (ClassNotFoundException e) {e.printstacktrace (); 
   catch (SQLException e) {e.printstacktrace (); 
 Return connection to Connection pool */public synchronized void release () {POOL.ADD (conn); /* Return a database connection in the connection pool/* Public synchronized Connection getconnection () {if (pool.size () &gt; 0) {ConnEction conn = pool.get (0); 
   Pool.remove (conn); 
  Return conn; 
  else {return null; 
 
 } 
 } 
}

Through the connection pool management, realizes the database connection sharing, does not need each time to re-create the connection, saves the database to re-create the expense, has promoted the system performance! This chapter explains 7 types of structural patterns, because of the length of the problem, the remaining 11 behavioral patterns,
This chapter is the last lecture on design patterns, we will talk about the third design pattern-behavioral pattern, a total of 11 kinds: Policy mode, template method pattern, observer mode, iterative sub mode, responsibility chain mode, Command mode, Memo mode, state mode, visitor mode, mediator mode, interpreter mode. I've been writing about design patterns for a while, and I've finally written half of them, blogging is a time-consuming thing, because I have to be responsible for the reader, whether it is the picture or the code or presentation, all want to write clearly, so that readers understand, I think whether I or the reader, want to see the quality of the blog out, from my own , I will continue to go on, constantly updated, the source of power from the readers of the continuous support of friends, I will do my best to write every article! Hope that we can continue to give advice and suggestions, together to create the perfect blog!

Let's take a look at the relationship between these 11 patterns:

The first class is implemented through the relationship between the parent class and the subclass. Category II: Between two classes. Class III: The state of the class. Class fourth: Through the middle class

13. Strategy Mode (strategy)

The policy pattern defines a series of algorithms and encapsulates each one so that they can be substituted for each other, and the changes in the algorithm do not affect the customers who use the algorithm. You need to design an interface that provides a unified approach to a series of implementation classes, implements the interface with multiple implementation classes, designs an abstract class (dispensable, belongs to a helper Class), and provides auxiliary functions, as follows:

In the diagram, ICalculator provides a method of consent,

Abstractcalculator is a helper class that provides an auxiliary method, followed by the implementation of each of the following classes:

First Unified Interface:

Public interface ICalculator {public 
 int calculate (String exp); 
} 

Auxiliary class:

Public abstract class Abstractcalculator {public 
  
 int[] Split (string exp,string opt) { 
  string array[] = Exp.split ( opt); 
  int arrayint[] = new int[2]; 
  Arrayint[0] = Integer.parseint (array[0]); 
  ARRAYINT[1] = Integer.parseint (array[1]); 
  Return Arrayint 
 } 
} 

Three implementation classes:

public class Plus extends Abstractcalculator implements ICalculator { 
 
 @Override public 
 int Calculate (String EXP) { 
  int arrayint[] = Split (exp, "\\+"); 
  return arrayint[0]+arrayint[1]; 
 } 
 

public class minus extends Abstractcalculator implements ICalculator { 
 
 @Override public 
 int calculate (String exp { 
  int arrayint[] = Split (exp, "-"); 
  return arrayint[0]-arrayint[1]; 
 } 
 

public class Multiply extends Abstractcalculator implements ICalculator { 
 
 @Override public 
 int Calculate (String EXP) { 
  int arrayint[] = Split (exp, "\\*"); 
  return arrayint[0]*arrayint[1]; 
 } 
 

Simple test class:

public class Strategytest {public 
 
 static void Main (string[] args) { 
  String exp = "2+8"; 
  ICalculator cal = new Plus (); 
  int result = Cal.calculate (exp); 
  SYSTEM.OUT.PRINTLN (result); 
 } 
 

Output: 10

The decision power of the policy mode is in the user, the system itself provides the implementation of different algorithms, add or remove algorithms, and encapsulate various algorithms. Therefore, the strategy pattern is used in the algorithm decision system, the external user only needs to decide which algorithm to use.

14. Template Method Mode (Template methods)

Explain the template method pattern, which means: in an abstract class, there is a main method, and then a 1...N method, which can be abstract or practical, define a class, inherit the abstract class, override the abstract method, call the abstract class, implement the call to the subclass, and first look at the diagram:

is to define a Main method in the Abstractcalculator class Calculate,calculate () call spilt (), and so on, plus and minus inherit the Abstractcalculator class respectively, The invocation of the subclass is implemented by the invocation of the Abstractcalculator, as shown in the following example:

Public abstract class Abstractcalculator { 
  
 /* Main method to implement calls to other methods in this class 
 /public final int calculate (String exp,string opt) { 
  int array[] = split (exp,opt); 
  Return calculate (array[0],array[1]); 
  
 /* The quilt class overrides the method * * 
 abstract public int calculate (int num1,int num2); 
  
 Public int[] Split (string exp,string opt) { 
  string array[] = Exp.split (opt); 
  int arrayint[] = new int[2]; 
  Arrayint[0] = Integer.parseint (array[0]); 
  ARRAYINT[1] = Integer.parseint (array[1]); 
  Return Arrayint 
 } 
}
public class Plus extends Abstractcalculator { 
 
 @Override public 
 int calculate (int num1,int num2) {return 
  num 1 + num2; 
 } 
} 

Test class:

public class Strategytest {public 
 
 static void Main (string[] args) { 
  String exp = "8+8"; 
  Abstractcalculator cal = new Plus (); 
  int result = Cal.calculate (exp, "\\+"); 
  SYSTEM.OUT.PRINTLN (result); 
 } 
 

I tracked the implementation of this applet: first, exp and "\\+" were used as parameters to invoke the Calculate (string,string) method in the Abstractcalculator class, in Calculate (string,string) To call the same kind of split (), and then call the Calculate (int, int) method, from this method into the subclass, after the return NUM1 + num2, the value returned to the Abstractcalculator class, assigned to result, printed out. It just validates the way we start.

15. Observer Mode (OBSERVER)

The next four patterns, including this one, are the relationships between classes and classes, not inheritance, and when you learn, you should remember to generalize and remember the first diagram of this article. Observer mode is well understood, similar to email subscriptions and RSS feeds, when we browse some blogs or wikis, we often see the RSS icon, which means that when you subscribe to the article, if there are updates, you will be notified in time. In fact, simply speaking: When an object changes, other objects dependent on the object will be notified, and with the change! Objects are a one-to-many relationship. Let's take a look at the diagram first:

I explain the role of these classes: The Mysubject class is our main object, Observer1 and Observer2 are objects that depend on Mysubject, and Mysubject and Observer1 inevitably change when Observer2 change. The Abstractsubject class defines a list of objects that you need to monitor to modify: Add or remove monitored objects and, when mysubject change, be responsible for notifying objects that exist in the list. Let's look at the implementation code:
A observer interface:

Public interface Observer {public 
 void Update (); 
} 

Two implementation classes:

public class Observer1 implements Observer { 
 
 @Override public 
 Void Update () { 
  System.out.println () Observer1 has received! "); 
 } 
 
public class Observer2 implements Observer { 
 
 @Override public 
 Void Update () { 
  System.out.println () Observer2 has received! "); 
 } 
 
 

Subject interface and implementation class:

Public interface Subject { 
  
 /* Add observer 
 /public void Add (Observer Observer); 
  
 * * Delete Observer 
 /public void del (Observer Observer); 
  
 /* Notify all observers/public 
 void Notifyobservers (); 
  
 /* Own operation * 
 /public void operation (); 
} 
Public abstract class Abstractsubject implements Subject { 
 
 private vector<observer> Vector = new Vector<obse Rver> (); 
 @Override public 
 void Add (Observer Observer) { 
  vector.add (Observer); 
 } 
 
 @Override public 
 void del (Observer Observer) { 
  vector.remove (Observer); 
 } 
 
 @Override public 
 void Notifyobservers () { 
  enumeration<observer> Enumo = vector.elements (); 
  while (Enumo.hasmoreelements ()) { 
   enumo.nextelement (). Update ();}} 
 
public class Mysubject extends Abstractsubject { 
 
 @Override public 
 void operation () { 
  System.out.println ("Update self!"); 
  Notifyobservers (); 
 } 
 
 

Test class:

public class Observertest {public 
 
 static void Main (string[] args) { 
  Subject sub = new Mysubject (); 
  Sub.add (New Observer1 ()); 
  Sub.add (New Observer2 ()); 
   
  Sub.operation (); 
 } 
 
 

Output:
Update self!
Observer1 has received!
Observer2 has received!

These things, in fact, is not difficult, just some abstract, not easy to understand the whole, suggested that the reader: According to the diagram, the new project, write their own code (or reference to My Code), follow the general idea to walk again, so as to realize its thinking, easy to understand!

16, iterative sub-mode (iterator)

As the name implies, the iterator pattern is the sequential access to the objects in the aggregation, generally speaking, the collection is very common, if the collection class is more familiar with, understand this mode is very easy. This sentence contains two meanings: One is the object that needs to be traversed, that is, the aggregate object, and the other is the iterator object, which is used to traverse the clustered object. Let's look at the diagram:

This idea is exactly the same as we used to, mycollection defines a set of operations, Myiterator defines a series of iterative operations, and holds collection instances, let's look at the implementation code:
Two interfaces:

Public interface Collection {public 
  
 iterator iterator (); 
  
 /* Gets the Set element 
 /public Object get (int i); 
  
 /* Get the collection size * 
 /public int size (); 
} 
Public interface Iterator { 
 //forward-Move public 
 Object Previous (); 
  
 Move the public 
 Object next () later; 
 public boolean hasnext (); 
  
 Gets the first element public 
 Object one (); 
 

Two implementations:

public class MyCollection implements Collection {public 
 
 String string[] = {"A", "B", "C", "D", "E"}; 
 @Override Public 
 iterator iterator () {return to 
  new Myiterator (this); 
 } 
 
 @Override public 
 Object get (int i) {return 
  string[i]; 
 } 
 
 @Override public 
 int size () {return 
  string.length; 
 } 
} 

public class Myiterator implements iterator { 
 
 private Collection Collection; 
 private int pos =-1; 
  
 Public Myiterator (Collection Collection) { 
  this.collection = Collection; 
 } 
  
 @Override public 
 Object Previous () { 
  if (pos > 0) { 
   pos-- 
  } 
  Return Collection.get (POS); 
 
 @Override public 
 Object Next () { 
  if (pos<collection.size ()-1) { 
   pos++ 
  } 
  Return Collection.get (POS); 
 
 @Override Public 
 Boolean hasnext () { 
  if (pos<collection.size ()-1) {return 
   true; 
  } else{return 
   false; 
  } 
 
 @Override Public 
 Object A () { 
  pos = 0; 
  Return Collection.get (POS); 
 } 
 
 

Test class:

public class Test {public 
 
 static void Main (string[] args) { 
  Collection Collection = new mycollection (); 
  Iterator it = Collection.iterator (); 
   
  while (It.hasnext ()) { 
   System.out.println (It.next ()); 
  } 
}} 

Output: A B C D E

Here we seem to simulate the process of a collection class, does it feel cool? In fact, all the classes in the JDK are these basic things, plus some design patterns, plus some optimization put together, as long as we learn these things, master, we can also write their own collection classes, and even the framework!

17. Responsibility chain mode (Chain of responsibility)

Next we're going to talk about the responsibility chain model, where there are multiple objects, each holding a reference to the next object, which creates a chain that requests to be passed on the chain until an object decides to process the request. But the issue is not clear to the end that the object will handle the request, so the responsibility chain model can be implemented, in the case of concealing the client, the system dynamic adjustment. First look at the diagram:

The Abstracthandler class provides get and set methods to facilitate Myhandle classes to set up and modify reference objects, and Myhandle classes are cores that generate a series of mutually held objects that form a chain.

Public interface Handler {public 
 void operator (); 
} 

Public abstract class Abstracthandler { 
  
 private Handler Handler; 
 
 Public Handler GetHandler () {return 
  Handler; 
 } 
 
 public void SetHandler (Handler Handler) { 
  this.handler = Handler; 
 } 
  
} 

public class MyHandler extends Abstracthandler implements Handler { 
 
 private String name; 
 
 Public MyHandler (String name) { 
  this.name = name; 
 } 
 
 @Override public 
 void operator () { 
  System.out.println (name+ "deal!"); 
  if (GetHandler ()!=null) { 
   gethandler (). operator ();}}} 
 
public class Test {public 
 
 static void Main (string[] args) { 
  MyHandler h1 = new MyHandler ("H1"); 
  MyHandler h2 = new MyHandler ("H2"); 
  MyHandler h3 = new MyHandler ("H3"); 
 
  H1.sethandler (H2); 
  H2.sethandler (H3); 
 
  H1.operator (); 
 } 
 

Output:
h1deal!
h2deal!
h3deal!
One thing to emphasize here is that the request on the link can be a chain, a tree, or a loop, the pattern itself does not constrain this, it needs to be implemented by ourselves, and at one time, the command allows only one object to be passed to another object, not to multiple objects.

18. Command mode

Command mode is well understood, for example, the commander ordered the soldiers to do something, from the point of view of the whole thing, the commander's role is to send a password, the password passed, reached the soldiers ear, the soldiers to carry out. The process is good, the three mutual decoupling, no one need to rely on others, just to do their own thing on the line, the commander is the result, not to pay attention to exactly how the soldiers to achieve. Let's look at the diagram:

Invoker is the caller (commander), receiver is the callee (soldier), MyCommand is the command, implements the command interface, holds the receiving object, and looks at the implementation code:

Public interface Command {public 
 void exe (); 
} 

public class MyCommand implements Command { 
 
 private Receiver Receiver; 
  
 Public mycommand (Receiver Receiver) { 
  this.receiver = Receiver; 
 } 
 
 @Override public 
 void exe () { 
  receiver.action (); 
 } 
} 

public class Receiver {public 
 void action () { 
  System.out.println ("command received!"); 
 } 
 

public class Invoker { 
  
 private command command; 
  
 Public invoker (Command command) { 
  this.command = command; 
 } 
 
 public void Action () { 
  command.exe (); 
 } 
} 

public class Test {public 
 
 static void Main (string[] args) { 
  Receiver Receiver = new Receiver (); 
  Command cmd = new mycommand (receiver); 
  Invoker invoker = new Invoker (cmd); 
  Invoker.action (); 
 } 
 

Output: Command received!

This is very well understood, the purpose of the command mode is to achieve the command of the creator and performer decoupling between the implementation of the request and implementation of the separation, familiar with struts should know, struts is a kind of separation of request and presentation of technology, which necessarily involves the idea of command mode!
In fact, every design pattern is a very important thought, it looks familiar, but it's all about what we're learning, although sometimes we don't know it's in the Java design itself, like AWT, JDBC, collection class, Io pipe, or web framework, Inside the design pattern is everywhere. Because we have limited space, it is difficult to say that every design pattern is very detailed, but I will do my best, as far as possible in the limited room and length, the meaning of writing clearly, better let everyone understand. This chapter is not an accident, it should be the design pattern of the last lecture, first or last on the beginning of the previous diagram:

The third and fourth categories are covered in this chapter.

19, Memo mode (Memento)

The main purpose is to save a state of an object, in order to restore the object at the appropriate time, personal feel called backup mode more image, popular talk: Suppose there are a variety of properties in the original class A,a, a can determine the attributes to be backed up, Memo Class B is used to store a some of the internal state, Class C, is one that stores memos, and can only be stored, not modified, and so on. Make a diagram to analyze:

The original class is the original class, which has the property value that needs to be saved and creates a memo class to hold the value. The Memento class is a memo class, and the storage class is the class that stores the memo, and holds an instance of the Memento class, which is well understood. Look at the source directly:

public class Original { 
  
 private String value; 
  
 Public String GetValue () {return 
  value; 
 } 
 
 public void SetValue (String value) { 
  this.value = value; 
 } 
 
 Public Original (String value) { 
  this.value = value; 
 } 
 
 Public Memento Creatememento () {return 
  new Memento (value); 
 } 
  
 public void Restorememento (Memento Memento) { 
  this.value = Memento.getvalue (); 
 } 
} 

public class Memento { 
  
 private String value; 
 
 Public Memento (String value) { 
  this.value = value; 
 } 
 
 Public String GetValue () {return 
  value; 
 } 
 
 public void SetValue (String value) { 
  this.value = value; 
 } 
} 
public class Storage { 
  
 private Memento Memento; 
  
 Public Storage (Memento Memento) { 
  this.memento = Memento; 
 } 
 
 Public Memento Getmemento () {return 
  Memento; 
 } 
 
 public void Setmemento (Memento Memento) { 
  this.memento = Memento; 
 } 
} 

Test class:

public class Test {public 
 
 static void Main (string[] args) { 
   
  //Create the original class 
  Original Origi = new Original ("egg"); 
 
  //Create Memo 
  Storage Storage = new Storage (Origi.creatememento ()); 
 
  Modifies the state System.out.println of the original class 
  ("Initialization state is:" + origi.getvalue ()); 
  Origi.setvalue ("Niu"); 
  SYSTEM.OUT.PRINTLN ("The Modified State is:" + origi.getvalue ()); 
 
  Reply to the state Origi.restorememento of the original class 
  (Storage.getmemento ()); 
  System.out.println ("The restored state is:" + origi.getvalue ()); 
 } 
 

Output:

Initialization status is: Egg
The modified status is: NIU
The status after recovery is: egg
Under simple description: When creating a new original class, value is initialized to egg, then modified, the value is set to Niu, the last penultimate line is restored, and the result is successfully restored. In fact, I think this mode is called "Backup-Restore" mode the most image.

20, Status mode (state)

The core idea is: when the state of the object changes, at the same time change its behavior, very good understanding! Take QQ, there are several states, online, stealth, busy and so on, each state corresponds to different operations, and your friends can see your state, so, state mode on two points: 1, you can change the state to obtain different behavior. 2, your friends can see your changes at the same time. Look at the picture:

The State class is a status class, and the context class can switch, so let's look at the code:

Package com.xtfggef.dp.state; 
 
/** 
 * The Core class * 
 2012-12-1 * @author erqing * */Public 
 class State 
{ 
  
 private String value ; 
  
 Public String GetValue () {return 
  value; 
 } 
 
 public void SetValue (String value) { 
  this.value = value; 
 } 
 
 public void Method1 () { 
  System.out.println ("Execute the The"); 
 } 
  
 public void Method2 () { 
  System.out.println ("Execute the second opt!"); 
 } 
 


Package com.xtfggef.dp.state; 
 
/** 
 * State mode switching class 2012-12-1 
 * @author erqing * * * * 
 /public class context 
{ 
 
 private 
 
 states state; Public Context { 
  this.state = state; 
 } 
 
 Public State getState () {return state 
  ; 
 } 
 
 public void SetState (state state) { 
  this.state = state; 
 } 
 
 public void Method () { 
  if (State.getvalue (). Equals ("State1")) { 
   state.method1 (); 
  } else if ( State.getvalue (). Equals ("State2")) { 
   state.method2 (); 
  } 
 } 
} 

Test class:

public class Test {public 
 
 static void Main (string[] args) {state 
   
  = new State (); 
  Context context = new context (state); 
   
  Set the first state 
  state.setvalue ("State1"); 
  Context.method (); 
   
  Set the second state 
  state.setvalue ("State2"); 
  Context.method (); 
 } 
 

Output:
Execute the opt!
Execute the second opt!

According to this feature, the state pattern in the day-to-day development of a lot of, especially when doing a website, we sometimes want to according to a certain attribute of the object, distinguish their functions, such as simple permissions control.

21, Visitor mode (Visitor)

The visitor pattern coupling the data structure with the operations on the structure allows the operation set to evolve relatively freely. The visitor pattern is suitable for the system with a relatively stable algorithm and a variable structure. Because the visitor pattern makes it easy to increase the algorithm operation. If the system data structure object is easy to change, there are often new data objects added in, it is not suitable to use the visitor mode. The advantage of the visitor pattern is that it is easy to increase the operation because adding the operation means adding new visitors. The visitor pattern centralizes the behavior in a visitor object, and the change does not affect the system data structure. The disadvantage is that it is difficult to add new data structures. --from Encyclopedia
In simple terms, the visitor pattern is a way of separating the data structure and behavior of the object, and by this separation, it can be achieved by dynamically adding a new operation to a visitor without making any other modifications. Simple diagram:

Look at the original code: A visitor class that holds the objects to be accessed,

Public interface Visitor {public 
 void visit (Subject sub); 
} 

public class Myvisitor implements Visitor { 
 
 @Override public 
 void Visit (Subject sub) { 
  System.out.println (" Visit the Subject: +sub.getsubject ()); 
 } 
 

Subject class, accept method, accepts the object that will be accessed, getsubject () Gets the property that will be accessed,

Public interface Subject {public 
 void accept (Visitor Visitor); 
 Public String getsubject (); 
} 
public class Mysubject implements Subject { 
 
 @Override public 
 void Accept (Visitor Visitor) { 
  Visitor.visit (this); 
 } 
 
 @Override public 
 String Getsubject () {return 
  ' love '; 
 } 
} 

Test:

public class Test {public 
 
 static void Main (string[] args) { 
   
  Visitor Visitor = new Myvisitor (); 
  Subject sub = new Mysubject (); 
  Sub.accept (visitor);  
 } 
 

Output: Visit the Subject:love

This pattern applies to scenarios: if we want to add new functionality to an existing class, we have to consider several things: 1. Will the new feature be compatible with existing features? 2, later will not need to add? 3. What if the class doesn't allow you to modify the code? In the face of these problems, the best solution is to use the visitor pattern, the visitor pattern is suitable for the system with relatively stable data structure, and the algorithm is decoupled,

22. Intermediary mode (mediator)
The mediator pattern is also used to reduce the coupling between class classes, because if there is a dependency between class classes, it is not conducive to the expansion and maintenance of the function, because as long as the object is modified, the other associated objects have to be modified. If you use the mediator pattern, just care about the relationship with the Mediator class, the relationship between the class class and the dispatch to mediator, which is a bit like the role of the spring container. First look at the picture:

User Class Unified interface, User1 and User2 are different objects, there is a correlation between the two, if you do not use the intermediary model, you need to hold a reference to each other, so the two are very high coupling, for understanding coupling, the introduction of the Mediator class, providing a unified interface,

Mymediator for its implementation class, which holds User1 and User2 instances, used to achieve User1 and User2 control. So User1 and User2 two objects are independent of each other, they only need to keep the relationship between good and mediator on the line, the rest of the entire Mymediator class to maintain! Basic implementation:

Public interface Mediator {public 
  void Createmediator (); 
  public void Workall (); 
} 

Public class Mymediator implements mediator { 
 
  private User user1; 
  Private User user2; 
   
  Public User GetUser1 () {return 
    user1; 
  } 
 
  Public User GetUser2 () {return 
    user2; 
  } 
 
  @Override public 
  void Createmediator () { 
    user1 = new User1 (this); 
    User2 = new User2 (this); 
  } 
 
  @Override public 
  void Workall () { 
    user1.work (); 
    User2.work (); 
  } 
 
Public abstract class User { 
   
  private mediator mediator; 
   
  Public Mediator Getmediator () {return 
    mediator; 
  } 
   
  Public User (mediator mediator) { 
    this.mediator = mediator; 
  } 
 
  public abstract void work (); 
} 

public class User1 extends User {public 
 
  User1 (mediator mediator) { 
    super (mediator); 
  } 
   
  @Override public 
  void work () { 
    System.out.println ("user1 exe!"); 
  } 
[Java] View plaincopy public
class User2 extends User {public 
 
  User2 (mediator mediator) { 
    Super (mediator) ; 
  } 
   
  @Override public 
  void work () { 
    System.out.println ("User2 exe!"); 
  } 
 

Test class:

public class Test {public 
 
  static void Main (string[] args) { 
    Mediator mediator = new Mymediator (); 
    Mediator.createmediator (); 
    Mediator.workall (); 
  } 
 

Output:
User1 exe!
User2 exe!

23. Interpreter Mode (interpreter)

Interpreter mode is our temporary last talk, generally used in OOP development in the development of the compiler, so the application surface is relatively narrow.

The context class is a contextual environment class, plus and minus are used to compute the implementation, the code is as follows:

Public interface Expression {public 
  int interpret; 
} 
public class Plus implements Expression { 
 
  @Override public 
  int interpret 
    CONTEXT.GETNUM1 () +context.getnum2 (); 
  } 
 
public class minus implements Expression { 
 
  @Override public 
  int interpret 
    CONTEXT.GETNUM1 ()-context.getnum2 (); 
  } 
 

Public class Context { 
   
  private int num1; 
  private int num2; 
   
  public context (int num1, int num2) { 
    this.num1 = NUM1; 
    this.num2 = num2; 
  } 
   
  public int getNum1 () {return 
    num1; 
  } 
  public void setNum1 (int num1) { 
    this.num1 = num1; 
  } 
  public int getNum2 () {return 
    num2; 
  } 
  public void setNum2 (int num2) { 
    this.num2 = num2; 
  } 
   
   
} 
public class Test {public 
 
  static void Main (string[] args) { 
 
    //compute 9+2-8 value 
    int result = new minus (). Interpre T (new context (New-Plus () 
        . Interpret (new context (9, 2)), 8)); 
    SYSTEM.OUT.PRINTLN (result); 
  } 
 

Finally output the correct result: 3.

Basically, the interpreter pattern is used to do all kinds of interpreters, such as regular expressions and so on.

The

Design pattern is basically about finished, the overall feeling a little bit short, indeed, such a little space, not enough to the entire 23 design patterns to do a comprehensive exposition, where the reader can take it as a theoretical basis to learn, through these four posts, the first basic concept, although I speak a little simple, But the basic can explain the problem and their characteristics, if interested in which, you can continue to further study! At the same time I will continue to update, as far as possible to complete the omission, the amendment is insufficient, welcome readers to put forward good suggestions, we learn together! The code involved in the project has been placed in my resources: http://download.csdn.net/detail/zhangerqing/4835830 (because I do not like to get something for nothing, so there is no free integral, only 5 sets, If someone does not have the points and the rush, then contact me, I send you the past.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.