Design mode (residual)

Seven principles of OOP (OOP: Object Oriented Programming)

  • Opening and closing principle: for extension development, close for modification
  • Richter substitution principle: inheritance must ensure that the properties owned by the parent class are still valid in the child class (rewrite the methods of the parent class as little as possible)
  • Dependency Inversion Principle: interface oriented programming, not implementation oriented programming
  • Single responsibility principle: control the granularity of classes, decouple objects and improve their cohesion (one method should not deal with too many things)
  • Interface isolation principle: establish special interfaces for each class
  • Dimitri's Law: talk only to your direct friends, not to "strangers"
  • Composition Reuse Principle: try to use association relations such as composition or aggregation first, and then consider using inheritance relations

Singleton mode (creation mode)

Core role: ensure that a class has only one instance, and provide a global access point to access the instance

Common scenarios:

  • Task manager for windows
  • In the project, there is usually only one object for the class reading the configuration file. It is not necessary to read the new object every time
  • The database connection pool will also be designed in singleton mode
  • In spring, each bean is singleton by default

Factory mode (creation mode)

Function: it realizes the separation of creator and caller

Core essence:

  • The instantiated object is not applicable to new, and the factory method is used instead
  • The implementation class will be selected to create objects for unified management and control. This decouples the caller from our implementation class

It is divided into simple factory, method factory and abstract factory (factory of factory)

Builder mode (creative mode)

Function: it realizes the separation of creator and caller, combines different modules to build a complex object

In the builder mode, there are four roles:
1. Abstract Builder: it is used to standardize and abstract various components of the product, which is generally independent of the logic of the application.
2. Concrete Builder: this role implements all the methods defined in the abstract builder and returns a good product instance of the component.
3. Product: this role is a complex object in the builder. There will be multiple product classes in a system. These product classes do not necessarily have a common interface, but can be unrelated to completion.
4. Director: this role is responsible for arranging the order of existing modules, and then telling Builder to start construction

Personally, I think: the Product is equivalent to the entity class in the pojo layer; Abstract Builder is equivalent to the interface of service layer; Concrete Builder is equivalent to the implementation class of service layer; The Director is equivalent to the controller layer controller

Prototype mode (creation mode)

Prototype pattern is used to create duplicate objects and ensure performance. It is a creative design pattern and provides the best way to create objects.

java implementation prototype pattern

  • 1. Implement an interface clonable
  • 2. Override a method clone()

However, if there is a referenced data type in the class to be cloned, it will lead to shallow cloning (pointing to the same referenced data type), that is, if the data type referenced in one object is modified, the data type in another cloned object will also be changed.

Therefore, to implement deep cloning (pointing to different reference data types), that is, modify the data type referenced in one object, and the data type in the other cloned object will not change. To implement deep cloning, override the clone() method

private Date createTime;

@Override
protected Object clone() throws CloneNotSupportedException {
    Object obj = super.clone();

    // Implement deep cloning
    Video v = (Video) obj;

    //Clone the properties of this object as well
    v.createTime = (Date) this.createTime.clone();

    return obj;
}

In actual development, deep cloning is more often used, that is, the objects in the objects are also cloned

Adapter mode (structural mode)

Convert the interface of a class into another interface that the customer wants. The Adapter pattern allows classes that cannot work together because of interface incompatibility to work together.

Class adapter: implemented by inheriting the class to be adapted

Object adapter: it does not inherit, but is implemented by creating an instance of the class to be adapted, just like creating an instance of mapper in the service layer

Object adapters are recommended

Advantages of object adapter:

  • An object adapter can adapt multiple different adapters to the same target
  • A subclass of an adapter can be adapted. Because the adapter and the adapter are associated, the subclass of the adapter can also be adapted by changing the adapter according to the "Richter replacement principle"

Bridging mode (structural mode)

Advantages:

  • The bridging mode is occasionally similar to the multi inheritance scheme, but the multi inheritance scheme violates the principle of single responsibility of classes, with poor reusability and a large number of classes. The bridging mode is a better solution than the multi inheritance scheme, which greatly reduces the number of subclasses and reduces the cost of management and maintenance
  • The bridging mode improves the scalability of the system. If one of the two change dimensions is extended arbitrarily, there is no need to modify the original system. In line with the principle of opening and closing, it is like a bridge, which can connect the two changing dimensions

inferiority:

  • The introduction of bridging mode will increase the difficulty of system understanding and design. Because the aggregation association relationship is based on the abstraction layer, developers are required to design and program for the abstraction
  • Bridge mode requires to correctly identify two independent changing dimensions in the system, so its application scope has certain limitations

Usage scenario

  • Java language realizes platform independence through Java virtual machine
  • The JDBC driver is also a bridge mode application

Agent mode (structured mode)

Static proxy

Role analysis:

  • Abstract role: it is usually solved by using interfaces or abstract classes
  • Real role: the role represented
  • Proxy role: represents a real role. After representing a real role, you usually do some ancillary operations
  • Client: the person who accesses the proxy object

code

  1. Interface

    //Rent a house
    public interface Rent {
        public void rent();
    
    }
    
  2. Real role

    //landlord or landlady
    public class Host implements Rent{
        
        public void rent() {
            System.out.println("The landlord wants to rent the house");
        }
    }
    
  3. delegable role

    public class Proxy implements Rent{
        private Host host;
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        public Proxy() {
        }
    
    
        public void rent() {
            host.rent();
            seeHouse();
            fare();
            hetong();
        }
        //House viewing
        public void seeHouse(){
            System.out.println("The agent will show you the house");
        }
        //Intermediary fee
        public void fare(){
            System.out.println("Intermediary fee");
        }
        //sign a contract
        public void hetong(){
            System.out.println("sign a contract");
        }
    
    }
    
  4. Client access agent role

public class Client {
    public static void main(String[] args) {
        Host host = new Host();
        //Agents, agents generally have some ancillary operations
        Proxy proxy = new Proxy(host);
        proxy.rent();
    }
}

Benefits of agent mode:

  • It can make the operation of real roles more pure without paying attention to some public businesses
  • The role of public agent is given to realize the division of business
  • When the public business is expanded, it is convenient for centralized management

Disadvantages:

  • A real role will produce a proxy role, the amount of code will double, and the development efficiency will be low

Dynamic agent

  • Dynamic agents have the same role as static agents
  • The proxy class of dynamic proxy is generated dynamically, which is not written directly
  • Dynamic agents are divided into two categories: interface based dynamic agents and class based dynamic agents
    • Interface based JDK dynamic proxy [we use it here]
    • Class based: cglib
    • java bytecode implementation: javassist

Core: InvocationHandler: call handler and Proxy: Proxy

Benefits of dynamic agents:

In addition to all the benefits of static proxies, there are

  • A dynamic agent class represents an interface, which is generally a corresponding type of business
  • A dynamic proxy class can proxy multiple classes as long as it implements the same interface

UserService interface

public interface UserService {
     void add();
     void delete();
     void update();
     void query();
}

UserServiceImpl implementation class

public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("Added a user");
    }

    @Override
    public void delete() {
        System.out.println("A user was deleted");
    }

    @Override
    public void update() {
        System.out.println("Modified a user");
    }

    @Override
    public void query() {
        System.out.println("A user was queried");
    }
}

Agent class:

//We will use this class to automatically generate proxy classes
public class ProxyInvocationHandler implements InvocationHandler {
    //Proxy interface
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }
    //Generated proxy class
    public Object getProxy(){

        return Proxy.newProxyInstance(this.getClass().getClassLoader()
                ,target.getClass().getInterfaces(),this);
    }


    //Process the proxy instance and return the result
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        //The essence of dynamic agent is to use reflection mechanism
        Object result = method.invoke(target, args);

        return result;
    }

    public void log(String msg){
        System.out.println("Yes"+msg+"method");
    }

}

test

public class Client {
    public static void main(String[] args) {
        //Real role
        UserServiceImpl userService = new UserServiceImpl();

        //Proxy role, does not exist
        ProxyInvocationHandler pih = new ProxyInvocationHandler();

        pih.setTarget(userService);//Sets the object to proxy

        //Dynamically generate proxy classes
        UserService proxy = (UserService) pih.getProxy();

        proxy.add();

    }

}

result

Tags: Java

Posted on Thu, 07 Oct 2021 03:27:39 -0400 by swr