Hello everyone , I'm Xiaoyu .

The principle or source code of every technology stack we usually use is more or less related to the concept of design patterns , It can also be said that , Only a better grasp of the design pattern , Our ability to code More normative 、 concise , More efficient .

secondly , Design patterns are mostly based on the experience of our predecessors , Standing on the shoulders of giants , Absorb their experience and lessons , Our way of coding will last longer .

meanwhile , During our interview, too Bonus options , If you can tell the interviewer about the design pattern , The interviewer will certainly look at you with new eyes . In the work , Have a good idea of design patterns , It will also be of great help to the development of the project .

Next , Follow Xiaoyu to see what design patterns we need to know ~

Preface

Generally speaking, design patterns are divided into three categories :

Create pattern : Factory method model 、 Abstract factory pattern 、 The singleton pattern 、 Builder pattern 、 Archetypal model .

Structural mode : Adapter pattern 、 Decorator mode 、 The proxy pattern 、 Appearance mode 、 Bridging mode 、 Portfolio model 、 The flyweight pattern .

Behavioral patterns : The strategy pattern 、 Template method pattern 、 Observer mode 、 Iterative subpattern 、 The chain of responsibility model 、 Command mode 、 Memo mode 、 The state pattern 、 Visitor mode 、 Intermediary model 、 Interpreter mode .

The singleton pattern

Concept

Make sure there is only one instance of a class , and self-instantiation And provide the whole system with this example .

Use scenarios

  • The environment that requires a unique serial number to be generated ;

  • A shared access point or shared data is needed throughout the project , For example, one Web Counters on the page , No need to record every refresh to the database , Use singleton mode to keep the counter value , And make sure it's thread safe ;

  • Creating an object consumes too many resources , To access IO And database resources ;

  • A lot of static constants and static methods need to be defined ( Such as tools ) Environment , You can use the singleton mode ( Of course , It can also be declared directly as static The way ).

Code example

Thread safety :

public class Singleton {
private static final Singleton singleton = new Singleton();
// Limit the generation of multiple objects
private Singleton(){
}
// Through this method, the instance object is obtained
public static Singleton getSingleton(){
return singleton;
}
// Class , Try to be static
public static void doSomething(){
}
}

Thread unsafe :

public class Singleton {
private static Singleton singleton = null;
// Limit the generation of multiple objects
private Singleton(){
}
// Through this method, the instance object is obtained
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}

Unsafe for threads :
stay getSingleton Methods before adding synchronized keyword , It can also be in getSingleton Add... In the method synchronized To achieve .

Factory mode

Concept

Defines an interface for creating objects , Let the subclass decide which class to instantiate . The factory method makes a class Instantiation delay To its subclasses .

Use scenarios

jdbc Connect to database , Hardware access , Reduce the generation and destruction of objects

structure

Simple factory model : A module only needs one factory class , There's no need to produce it , Using static methods

Multiple factory classes : Every race ( Specific product categories ) They all correspond to a Creator , Each creator is responsible for creating the corresponding product object independently , Very consistent with the principle of single responsibility

Instead of singleton mode : The core requirement of singleton mode is that there is only one object in memory , With the factory method pattern, you can also produce only one object in memory

Delay initialization : ProductFactory Responsible for the creation of product class objects , And through prMap Variable produces a cache , Keep... For objects that need to be reused again

Code example

Product Responsible for defining product commonalities for abstract product classes , Realize the most abstract definition of things ;

Creator Create classes for abstractions , It's the abstract factory , How to create a product class is determined by the implementation factory ConcreteCreator Accomplished .

public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c){
Product product=null;
try {
product =
(Product)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// exception handling
}
return (T)product;
}
}

Abstract factory pattern

Concept

Provides an interface for creating a set of related or interdependent objects , and No need to specify their concrete classes .

Use scenarios

A family of objects ( Or a group of unrelated objects ) All have the same constraints .

When it comes to different operating systems , You can consider using the abstract factory pattern .

Code example

public abstract class AbstractCreator {
// establish A Product family
public abstract AbstractProductA createProductA();
// establish B Product family
public abstract AbstractProductB createProductB();
}

Template method pattern

Concept

Define the framework of an algorithm in an operation , Instead, defer some steps to subclasses . So that subclasses can Without changing the structure of an algorithm You can redefine some specific steps of the algorithm .

Use scenarios

  • Multiple subclasses have public methods , And when the logic is basically the same .

  • important 、 Complex algorithms , The core algorithm can be designed as a template method , The peripheral details are implemented by each subclass .

  • Refactoring , Template method pattern is a frequently used pattern , Extract the same code into the parent class , And then through the hook function ( see “ Template method pattern extension ”) Restrain their actions .

structure

Abstract template :AbstractClass For abstract templates , Its methods fall into two categories :

1、 The basic method : It's also called basic operation , Methods implemented by subclasses , And when the template method is called .

2、 Template method : There can be one or more , It's usually a specific method , It's a framework , Realize the scheduling of basic methods , Complete the fixed logic .

Be careful : In order to prevent malicious operation , General template methods add final keyword , Overwriting... Is not allowed .

Specific template : Implement one or more abstract methods defined by the parent class , That is, the basic methods defined by the parent class are implemented in the child class .

Code example

package templateMethod;
public class TemplateMethodPattern
{
public static void main(String[] args)
{
AbstractClass tm=new ConcreteClass();
tm.TemplateMethod();
}
}
// abstract class
abstract class AbstractClass
{
public void TemplateMethod() // Template method
{
SpecificMethod();
abstractMethod1();
abstractMethod2();
}
public void SpecificMethod() // The specific methods
{
System.out.println(" Concrete methods in abstract classes are called ...");
}
public abstract void abstractMethod1(); // Abstract method 1
public abstract void abstractMethod2(); // Abstract method 2
}
// Specific subclass
class ConcreteClass extends AbstractClass
{
public void abstractMethod1()
{
System.out.println(" Abstract method 1 The implementation of is called ...");
}
public void abstractMethod2()
{
System.out.println(" Abstract method 2 The implementation of is called ...");
}
}

Builder pattern

Concept

Separate the construction of a complex object from its representation , bring The same build process can create different representations .

Use scenarios

  • Same method , Different order of execution , When different event results are produced , You can use builder mode .

  • Multiple components or parts , Can be assembled into an object , But the results are not the same , You can use this mode .

  • The product category is very complex , Or the different calling order in the product class produces different performance , It's a good time to use builder mode .

structure

Product Product class : The template method pattern is usually implemented , There are template methods and basic methods .

Builder Abstract builder : Standardizing the formation of products , It is usually implemented by subclasses .

ConcreteBuilder Specific builder : Implement all methods defined by an abstract class , And return a group created object .

Director Directors : Responsible for arranging the order of existing modules , Then tell Builder Start building

Code example

public class ConcreteProduct extends Builder {
private Product product = new Product();
// Set up product parts
public void setPart(){
/*
* Logical processing within the product class
*/
}
// Build a product
public Product buildProduct() {
return product;
}
}

The proxy pattern

Concept

For other objects Provide a proxy to control Access to this object .

structure

Subject Abstract theme role : Abstract topic classes can be abstract classes or interfaces , Is the most common definition of business type , No special requirements .

RealSubject Specific subject roles : It's also called the delegated role 、 Surrogate role . It's the big loser , Is the concrete executor of business logic .

Proxy Surrogate subject role : It's also called the delegate class 、 proxy class . It's responsible for the application of real characters , Methods that define all abstract topic classes 、 Restrict delegating to real theme role implementations , And do the pre-processing and post-processing work before and after the real theme role processing .

classification

General agent : In this mode , The caller only knows the agent, not who the real role is , Shielding the influence of real role changes on high-level modules , Real theme characters can be modified as they want , No impact on high-level modules , As long as you implement the method corresponding to the interface , This mode is very suitable for the situation with high scalability requirements .

Compulsory agency : The concept of mandatory proxy is to find the proxy role from the real role , No direct access to real characters . High level modules just call getProxy You can access all the methods of the real character , It doesn't need to generate a proxy at all , Agent management has been done by real characters themselves .

  • difference : General agency means that we need to know the existence of agency , It's similar GamePlayerProxy The existence of this class , Then we can visit ; Forcing a proxy means that the caller calls the real role directly , It doesn't matter if the agent exists , The generation of its agent is determined by the real role .

A dynamic proxy : Generate all methods based on the interface being proxied , That is to say, given an interface , Dynamic agents will claim “ I
All the methods under this interface have been implemented ”. Two independent development lines . Dynamic agent realizes the responsibility of agent , Business logic Subject Realize the related logic function , There is no necessary coupling relationship between the two . notice Advice From another perspective , Finally, in the high-level module, that is Client Coupling , Complete the task of logic encapsulation .

  • Intention : Cross section programming , Enhance or control the behavior of objects without changing our existing code structure .

  • The first condition : The proxy class must implement an interface .

Code example

public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

Archetypal model

Concept

Using prototype instances to specify the kind of objects to create , also By copying these prototypes Create a new object .

Use scenarios

Resource optimization scenarios : Class initialization needs to digest a lot of resources , This resource includes data 、 Hardware resources, etc .

Performance and security requirements scenarios : adopt new Generating an object requires a lot of data preparation or access rights , You can use prototype mode .

A scene where an object has multiple modifiers : An object needs to be provided for other objects to access , And each caller may need to change its value , Sure 、 Consider using prototype mode to copy multiple objects for callers to use .

advantage

Prototype pattern is actually implementation Cloneable Interface , rewrite clone() Method .

Excellent performance : The prototype pattern is a copy of the binary stream in memory , More than direct new The performance of an object is much better , Especially when a large number of objects are generated in a cycle , Prototype pattern can better reflect its advantages .

Escape the constraints of constructors : This is both its advantage and its disadvantage , Copy directly in memory , Constructors don't execute .

Code example

public class PrototypeClass implements Cloneable{
// Override parent Object Method
@Override
public PrototypeClass clone(){
PrototypeClass prototypeClass = null;
try {
prototypeClass = (PrototypeClass)super.clone();
} catch (CloneNotSupportedException e) {
// exception handling
}
return prototypeClass;
}
}

Intermediary model

Concept

Encapsulating a series of object interactions with a mediation object , Mediators make objects interact without explicit interaction , To make it Loose coupling , And they can change their interaction independently .

Use scenarios

The mediator pattern is suitable for close coupling between multiple objects , The standard of tight coupling is : There is a spider web structure in the class diagram , That is, each class is directly related to other classes .

structure

Mediator The role of an abstract intermediary : Abstract mediator role defines a unified interface , It is used for communication between colleagues' roles .

Concrete Mediator Specific intermediary role : The specific intermediary role realizes cooperative behavior by coordinating the roles of colleagues , So it has to depend on the role of each colleague .

Colleague Colleague role : Every co-worker role knows the intermediary role , And when communicating with other coworker roles , Be sure to collaborate through the intermediary role . There are two types of behavior for each colleague class : One is the behavior of colleagues themselves , Such as changing the state of the object itself , Dealing with your own behavior, etc , This behavior is called spontaneous behavior (SelfMethod), There is no dependency on other colleagues or mediators ; The second is the behavior that must rely on the intermediary to complete , It's called dependency methods (Dep-Method).

Sample code

public abstract class Mediator {
// Define the colleague class
protected ConcreteColleague1 c1;
protected ConcreteColleague2 c2;
// adopt getter/setter Method to inject the colleague class
public ConcreteColleague1 getC1() {
return c1;
}
public void setC1(ConcreteColleague1 c1) {
this.c1 = c1;
}
public ConcreteColleague2 getC2() {
return c2;
}
public void setC2(ConcreteColleague2 c2) {
this.c2 = c2;
}
// The business logic of the mediator model
public abstract void doSomething1();
public abstract void doSomething2();
}

Command mode

Concept

Encapsulate a request as an object , So you can parameterize the client with different requests , Yes Request queuing or request logging , Can provide command undo and restore function .

Use scenarios

Where you think it's a command, you can use command mode , for example , stay GUI In development , The click of a button is a command , You can use command mode ; simulation DOS When ordered , Of course, command mode should also be adopted ; Trigger - Feedback mechanism, etc .

structure

Receive Receiver role : The role is the role of work , The command passed here should be executed , In our example above, it is Group Three implementation classes of ( Demand group , Art Group , Code group ).

Command Command character : All commands that need to be executed are declared here .

Invoker The role of the caller : Received an order , And execute the command . In the example , I ( project manager ) That's the character .

Code example

public class Invoker {
private Command command;
// Set value injection
public void setCommand(Command command) {
this.command = command;
}
// Carry out orders
public void action() {
this.command.execute();
}
}

The chain of responsibility model

Concept

Give multiple objects a chance to process requests , This avoids the coupling between the sender and the receiver of the request . Put these objects In a chain , And pass the request along the chain , Until an object processes it .

duty

The abstract processor implements three responsibilities :

1、 Define the processing method of a request handleMessage, The only way to open up ;

2、 Define a chain arrangement setNext, Set up the next handler ;

3、 It defines two methods that a specific requester must implement : Define the level you can handle getHandlerLevel And specific processing tasks echo.

Code example

public abstract class Handler {
private Handler nextHandler;
// Every handler has to deal with the request
public final Response handleMessage(Request request){
Response response = null;
// Determine if it's your own processing level
if(this.getHandlerLevel().equals(request.getRequestLevel())){
response = this.echo(request);
}else{ // Not at your own processing level
// Determine if there is a next processor
if(this.nextHandler != null){
response =
this.nextHandler.handleMessage(request);
}else{
// There is no proper handler , The business deals with itself
} }
return response;
}
// Set who the next handler is
public void setNext(Handler _handler){
this.nextHandler = _handler;
}
// Each processor has a processing level
protected abstract Level getHandlerLevel();
// Each processor must implement the processing task
protected abstract Response echo(Request request);
}

matters needing attention

The number of nodes in the chain needs to be controlled , Avoid super long chains , The general practice is to Handler Set a maximum number of nodes in , stay setNext Method to determine whether it has exceeded its threshold , If it exceeds, the chain is not allowed to establish , Avoid unintentional damage to system performance .

Decoration mode

Concept

Dynamically give an object Add some extra responsibilities . In terms of adding functionality , Decoration patterns are more flexible than subclasses .

Use scenarios

  • Need to extend the function of a class , Or add additional functions to a class .

  • You need to dynamically add functionality to an object , These functions can be revoked dynamically .

  • You need to modify or add features to a group of siblings , Of course, the preferred decoration mode .

structure

Component Abstract component : Component It's an interface or an abstract class , It's about defining our core object , That is, the most primitive object . In decorative mode , There must be a fundamental 、 At the core 、 The most primitive interface or abstract class ACTS as Component Abstract component .

ConcreteComponent The specific components : ConcreteComponent It's the core 、 The most primitive 、 The most basic interface or abstract class implementation , That's what you're going to decorate .

Decorator To decorate a character : It's usually an abstract class , What's the use of it ? Implementing interfaces or abstract methods , It doesn't have to have abstract methods , There must be one of its attributes private Variable pointing to the Component Abstract component .

Specific decorative role : ConcreteDecoratorA and ConcreteDecoratorB There are two kinds of decoration , You have to put your core 、 ancestral 、 The most basic things are decorated with other things , The above example is to decorate a mediocre report card into a report card approved by parents .

Code example

/**
* To decorate a character
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Log
class BufferedReader implements Reader{
private Reader reader;
@Override
public void read() {
reader.read();
}
public void readLine(){
read();
log.info(" And read only one line ");
}
}

The strategy pattern

Concept

Define a set of algorithms , take Every algorithm is encapsulated , And make them interchangeable .

Use scenarios

  • Multiple classes have only slightly different scenarios in algorithm or behavior .

  • The algorithm needs to switch freely .

  • Scenarios that need to mask algorithm rules .

  • The number of specific strategies exceeds 4 individual , You need to consider using hybrid mode

structure

Context Encapsulate the character : It's also called contextual roles , Link between the above and the next packaging role , Shield high-level modules against policies 、 Direct access to the algorithm , Encapsulate possible changes .

Strategy Abstract strategy roles : Strategy 、 The abstraction of algorithm family , Usually interface , Define the methods and properties that each policy or algorithm must have .

ConcreteStrategy Specific strategic roles : Implement operations in abstract strategies , This class contains specific algorithms .

Code example

public enum Calculator {
// Addition operation
ADD("+"){
public int exec(int a,int b){
return a+b;
}
},
// Subtraction
SUB("-"){
public int exec(int a,int b){
return a - b;
}
};
String value = "";
// Define member value types
private Calculator(String _value){
this.value = _value;
}
// Gets the value of the enumeration member
public String getValue(){
return this.value;
}
// Declare an abstract function
public abstract int exec(int a,int b);
}

Adapter pattern

Concept

Interface of a class Transform to another interface expected by the client , So that the two classes that could not work together due to interface mismatch can work together .

Use scenarios

When you have an incentive to modify an interface that is already in production , The adapter mode is probably the best for you . For example, the system has expanded , You need to use an existing or newly created class , But this class does not conform to the interface of the system , What do I do ? Don't think about using adapter patterns in the detailed design phase , The main scenario is in the extended application .

The class adapter

Target The target character : This role defines what interfaces the other classes are converted to , That's our expected interface .

Adaptee The source role : Who do you want to turn into the target character , This “ who ” That's the source role , It's already there 、 A well-functioning class or object , Through the packaging of the adapter role , It's going to be a brand new 、 Beautiful characters .

Adapter Adapter role : The core role of the adapter pattern , The other two roles are existing roles , The adapter role needs to be newly created , Its duties are very simple : Converts the source role to the target role , How to convert ? By inheritance or class Association .

Object adapter

Don't use multiple inheritance or inheritance , Instead, use direct correlation , Or the way of delegation .

The difference between object adapter and class adapter :

Class adapters are inter class inheritance , An object adapter is a composite relationship of an object , It can also be said to be the association of classes , This is the fundamental difference between the two . In the actual project, the object adapter uses a relatively large number of scenarios .

Code example

public class Adapter extends Target
{
private Adaptee adaptee;
public Adapter(Adaptee adaptee)
{
this.adaptee=adaptee;
}
public void request()
{
adaptee.specificRequest();
}
} 

Iterator pattern

Concept

It provides a way Access elements in a container object , Without exposing the internal details of the object .

structure

Iterator Abstract iterator : Abstract iterators are responsible for defining interfaces to access and traverse elements , And it's basically fixed 3 A way :first() Get the first element ,next() Access the next element ,isDone() Have you visited the bottom (Java be called hasNext() Method ).

ConcreteIterator Specific iterators : The specific iterator role should implement the iterator interface , Complete the traversal of container elements .

Aggregate Abstract container : The container role is responsible for providing an interface to create a specific iterator role , There must be a similar createIterator() This way , stay Java In general iterator() Method .

Concrete Aggregate Specific containers : The concrete container implements the method of container interface definition , Create an object to hold the iterator .

Code example

/**
* Specific iterators
*/
public class ConcreteIterator<T> implements Iterator<T> {
private List<T> list = new ArrayList<>();
private int cursor = 0;
public boolean hasNext() {
return cursor != list.size();
}
public T next() {
T obj = null;
if (this.hasNext()) {
obj = this.list.get(cursor++);
}
return obj;
}
}

Portfolio model

Concept

Combine objects into a tree structure to represent “ part - whole ” Hierarchical structure , Make the use of single object and composite object consistent .

Use scenarios

  • Maintenance and display part - The whole relationship scenario , Like a tree menu 、 File and folder management .

  • A scenario in which some modules or functions can be separated from the whole .

  • As long as it's a tree structure , Just consider using the composite pattern .

structure

Component Abstract component roles : Define the common methods and properties of the composite objects , You can define some default behaviors or properties .

Leaf Leaf component : Leaf object , There are no other branches under it , The smallest unit of traversal .

Composite Tree branches : Branch object , Its function is to combine branch nodes and leaf nodes to form a tree structure .

Code example

public class Composite extends Component {
// Component containers
private ArrayList<Component> componentArrayList = new
ArrayList<Component>();
// Add a leaf or branch component
public void add(Component component){
this.componentArrayList.add(component);
}
// Delete a leaf or branch component
public void remove(Component component){
this.componentArrayList.remove(component);
}
// Get all the leaf and branch components under the branch
public ArrayList<Component> getChildren(){
return this.componentArrayList;
}
}

Observer mode

Concept

Define a one to many dependency between objects , Make every time an object changes state , Then all objects that depend on it will Be notified and automatically updated .

Use scenarios

  • Associated behavior scenarios . It should be noted that , Association behavior is divisible , instead of “ Combine ” Relationship .

  • Event multi-level trigger scenario .

  • Cross system message exchange scenario , Such as the processing mechanism of message queue .

structure

Subject Observed : Define the responsibilities that must be fulfilled by the observed , It has to be able to dynamically increase 、 Cancel the observer . It is usually an abstract class or an implementation class , Only fulfill the duties that must be fulfilled as the observed : Manage the observer and inform the observer .

Observer The observer : After the observer receives the message , That is to say update( Update method ) operation , Process the received information .

ConcreteSubject The specific observed : Define the business logic of the observed , It also defines which events are notified .

ConcreteObserver Specific observer : Each observation has a different processing response after receiving the message , Each observer has its own processing logic .

Code example

public abstract class Subject {
// Define an array of observers
private Vector<Observer> obsVector = new Vector<Observer>();
// Add an observer
public void addObserver(Observer o){
this.obsVector.add(o);
}
// Delete an observer
public void delObserver(Observer o){
this.obsVector.remove(o);
}
// Notify all observers
public void notifyObservers(){
for(Observer o:this.obsVector){
o.update();
}
}
}

Facade mode

Concept

The communication between the outside and the inside of a subsystem is required Through a unified object . The facade pattern provides a high-level interface , Makes the subsystem easier to use .

Use scenarios

  • Provide an interface for external access to a complex module or subsystem

  • Subsystem is relatively independent —— The access to the subsystem from the outside world only needs black box operation

  • Prevent the spread of risk from low-level personnel

structure

Facade The role of the facade : The client can call the methods of this role . This role knows all the functions and responsibilities of the subsystem . In general , This role will delegate all requests sent from the client to the corresponding subsystem , In other words, the role has no actual business logic , It's just a delegate class .

subsystem Subsystem role : There can be one or more subsystems at the same time . Each subsystem is not a separate class , It's a collection of classes . The subsystem does not know the presence of facade . For subsystems , Facade is just another client .

Code pattern

public class Client {
// The subsystem object of the delegate
private A a= new A();
private B b= new B();
private C c= new C();
// Methods of providing external access
public void methodA(){
this.a.doSomething();
}
public void methodB(){
this.b.doSomething();
}
public void methodC(){
this.c.doSomething();
}
}

Memo mode

Concept

Without breaking encapsulation , Capture the internal state of an object , And save the state outside the object . In this way, the object can be restored to the original saved state later .

Use scenarios

  • Relevant state scenarios that need to save and recover data .

  • Provide a rollback (rollback) The operation of .

  • In the replica scenario that needs to be monitored .

  • The transaction management of database connection is the memo mode .

structure

Originator Initiator role : Record the internal state of the current moment , Responsible for defining which States belong to the backup scope , Responsible for creating and restoring memo data .

Memento Memo role : Responsible for the storage Originator The internal state of the originator object , Provide the internal state the sponsor needs when needed .

Caretaker Memo administrator role : Manage memos 、 Keep and provide memos .

Code example

public class BeanUtils {
// hold bean Put all the attributes and values of into Hashmap in
public static HashMap<String,Object> backupProp(Object bean){
HashMap<String,Object> result = new
HashMap<String,Object>();
try {
// get Bean describe
BeanInfo
beanInfo=Introspector.getBeanInfo(bean.getClass());
// Get the property description
PropertyDescriptor[]
descriptors=beanInfo.getPropertyDescriptors();
// Traverse all properties
for(PropertyDescriptor des:descriptors){
// The attribute name
String fieldName = des.getName();
// Methods to read properties
Method getter = des.getReadMethod();
// Read property values
Object fieldValue=getter.invoke(bean,new
Object[]{});
if(!fieldName.equalsIgnoreCase("class")){
result.put(fieldName, fieldValue);
} } } catch (Exception e) {
// exception handling
}
return result;
}
// hold HashMap The value of is returned to bean in
public static void restoreProp(Object bean,HashMap<String,Object>
propMap){
try {
// get Bean describe
BeanInfo beanInfo =
Introspector.getBeanInfo(bean.getClass());
// Get the property description
PropertyDescriptor[] descriptors =
beanInfo.getPropertyDescriptors();
// Traverse all properties
for(PropertyDescriptor des:descriptors){
// The attribute name
String fieldName = des.getName();
// If you have this property
if(propMap.containsKey(fieldName)){
// The way to write properties
Method setter = des.getWriteMethod();
setter.invoke(bean, new
Object[]{propMap.get(fieldName)});
} } } catch (Exception e) {
// exception handling
System.out.println("shit");
e.printStackTrace();
}
}
}

Visitor mode

Concept

Package some Operations that act on the elements of a data structure , It can define new operations on these elements without changing the data structure .

Use scenarios

  • An object structure contains many class objects , They have different interfaces , And you want to do something with these objects that depends on their specific classes , In other words, it's a situation that can't be competent with iterator mode .

  • Many different and unrelated operations need to be performed on the objects in an object structure , And you want to avoid having these operations “ Pollution ” Classes for these objects .

structure

Visitor—— Abstract Visitor : Abstract class or interface , Declare which elements visitors can access , To be specific to the procedure is visit The parameters of the method define which objects can be accessed .

ConcreteVisitor—— Specific visitors : It affects what visitors do when they visit a class , What are you going to do .

Element—— Abstract elements : Interface or abstract class , State what kind of visitors are allowed to visit , The procedure is through accept Method .

ConcreteElement—— Specific elements : Realization accept Method , Usually visitor.visit(this), Basically, a pattern has been formed .

ObjectStruture—— The structure of the object : The element producer , Generally, it can be accommodated in many different types 、 Containers with different interfaces , Such as List、Set、Map etc. , In the project , This character is rarely abstracted .

Code example

public class CompensationVisitor implements Visitor {
@Override
public void Visit(Element element) {
// TODO Auto-generated method stub
Employee employee = ((Employee) element);
System.out.println(
employee.getName() + "'s Compensation is " + (employee.getDegree() * employee.getVacationDays() * 10));
}
}

The state pattern

Concept

Be an object When the inner state changes, allow it to change behavior , This object looks like it changed its class .

Use scenarios

  • A scene in which behavior changes as states change , This is also the starting point of the model , For example, permission design , The state of people is different, even if they perform the same behavior, the results will be different , In this case, you need to consider using state patterns .

  • Conditions 、 A substitute for a branch judgment statement

structure

State—— Abstract state role : Interface or abstract class , Responsible for object state definition , And encapsulate the role of the environment to achieve state switching .

ConcreteState—— Specific status role : Each specific state must fulfill two responsibilities : Behavior management of this state and trend state processing , In layman's terms , It's what we have to do in this state , And how this state transitions to other states .

Context—— Environmental roles : Define the interface required by the client , And responsible for the specific state switching .

Code example

// Abstract state role
public abstract class State {
// Define an environmental role , Provide subclass access to
protected Context context;
// Setting up environment roles
public void setContext(Context _context){
this.context = _context;
}
// Behavior 1
public abstract void handle1();
// Behavior 2
public abstract void handle2();
}

Interpreter mode

Concept

Give a language , A representation of the grammar that defines it , And define an interpreter , The interpreter Use this representation to explain sentences in a language .

Use scenarios

  • Recurring problems can use interpreter mode

  • A simple grammar needs to explain the scene

structure

AbstractExpression—— abstract interpreter : The specific interpretation task is completed by each implementation class , The specific interpreter is composed of TerminalExpression and Non-terminalExpression complete .

TerminalExpression—— Terminator expression : Implement the interpretation operations associated with elements in grammar , Usually there is only one terminator expression in an Interpreter pattern , But there are multiple instances , Corresponding to different terminators . To be specific, our example is VarExpression class , Each terminator in the expression produces a... In the stack VarExpression object .

NonterminalExpression—— Nonterminal expression : Each rule in grammar corresponds to a non terminal expression , Specifically, our example is that the addition and subtraction rules correspond to AddExpression and SubExpression Two classes . Nonterminal expressions increase based on the complexity of the logic , In principle, each grammar rule corresponds to a nonterminal expression .

Context—— Environmental roles : In our example, we use HashMap Instead of .

Code example

/**
* Terminator expression
*/
public class TerminalExpression extends AbstractExpression {
@Override
public void interpret(Context ctx) {
// Implements the interpretation operation associated with the terminator in the grammar rule
}
}
/**
* Nonterminal expression
*/
public class NonterminalExpression extends AbstractExpression {
@Override
public void interpret(Context ctx) {
// Implement the interpretation operation associated with the non terminal character in the grammar rule
}
}

The flyweight pattern

Concept

Using shared objects can effectively Supports a large number of fine-grained objects .

Object information is divided into two parts : Internal state (intrinsic) And the external state (extrinsic).

Internal state : Internal state is the information that an object can share , It is stored inside the enjoy object and does not change with the environment .

External state : An external state is a token that an object can depend on , It changes with the environment 、 Unshareable state .

Use scenarios

  • There are a large number of similar objects in the system .

  • Fine-grained objects have a similar external state , And the internal state is independent of the environment , That is, the object has no specific identity .

  • Scenarios where a buffer pool is required .

structure

Flyweight—— Abstract meta roles : It is simply an abstract class of a product , An interface or implementation that defines both the external and internal state of an object .

ConcreteFlyweight—— Specific enjoy yuan role : A specific product class , Implement the business of abstract role definition . It's important to note in this role that internal state processing should be environment independent , There shouldn't be an operation that changes the internal state , The external state was also modified , This is absolutely not allowed .

unsharedConcreteFlyweight—— Shareable role : There are no external states or security requirements ( Such as thread safety ) Objects that can't be shared , This object does not normally appear in the Heyuan factory .

FlyweightFactory—— The flyweight factory : The duties are very simple , That is to construct a pool container , It also provides methods to get objects from the pool .

Code example

public class FlyweightFactory {
// Define a pool container
private static HashMap<String,Flyweight> pool= new
HashMap<String,Flyweight>();
// The flyweight factory
public static Flyweight getFlyweight(String Extrinsic){
// The object that needs to be returned
Flyweight flyweight = null;
// There is no object in the pool
if(pool.containsKey(Extrinsic)){
flyweight = pool.get(Extrinsic);
}else{
// Create a share object based on the external state
flyweight = new ConcreteFlyweight1(Extrinsic);
// Put it in the pool
pool.put(Extrinsic, flyweight);
}
return flyweight;
}
}

Bridge mode

Concept

take Abstraction and implementation decoupling , So that the two can change independently .

Use scenarios

  • Scenarios where inheritance is not expected or applicable

  • Unstable interface or class abstraction

  • Scenarios that require high reusability

structure

Abstraction—— Abstract character : Its main responsibility is to define the behavior of the character , Also save a reference to the implemented role , The role is generally an abstract class .

Implementor—— Realize the role : It's an interface or an abstract class , Define the necessary behaviors and attributes of a character .

RefinedAbstraction—— Fixed abstract character : It refers to the implementation role to modify the abstract role .

ConcreteImplementor—— Concrete realization role : It implements methods and properties defined by interfaces or abstract classes .

Code example

public abstract class Abstraction {
// Define a reference to an implemented role
private Implementor imp;
// The constraint subclass must implement the constructor
public Abstraction(Implementor _imp){
this.imp = _imp;
}
// Their own behavior and attributes
public void request(){
this.imp.doSomething();
}
// Get realized roles
public Implementor getImp(){
return imp;
}
}

summary

When you're learning design patterns , Don't make it hard , in the final analysis , It's a summary of some generalities . We need to study and work constantly at ordinary times , Take time to understand its underlying principles , In this way, each design pattern can be applied flexibly .

The design pattern is based on the summary of predecessors , A solution to the problems in some scenarios , Design patterns are not formulas , There's no need to memorize every pattern , It's more important to understand it Abstract ideas , And how application design patterns Better problem solving , What can be achieved . There are many theories , But if we want to master it , For our actual development, it will solve many problems .

Of course, we will continue to update about Design principles The content of , It is convenient for you to further understand the design pattern .