23 design modes

Posted by ashishsharma on Sun, 20 Feb 2022 16:26:20 +0100

This note is obtained from station B crazy God speaking Java

What is a design pattern

The significance of learning design patterns

GoF23

Seven principles of oop

(1) Opening and closing principle: a software entity should be open to expansion and closed to modification;

(2) Richter substitution principle: inheritance must ensure that the properties owned by the superclass are still valid in the subclass

(3) Dependency Inversion Principle: interface oriented programming, not implementation oriented programming.

(4) Single responsibility principle: control the granularity of classes, decouple objects and improve their cohesion.

(5) Interface isolation principle: establish special interfaces for various classes

(6) Dimitri's rule: talk only to your direct friends, not to "strangers".

(7) Principle of composition and reuse: try to use association relations such as combination or aggregation first, and then consider using inheritance relations.

Factory mode

1. Function: realize the separation of creator and caller

2. Seven principles 00P:

(1) Opening and closing principle: a software entity should be open to expansion and closed to modification;

(2) Dependency Inversion Principle: programming for interfaces, not for implementations;

(3) Dimitri's Law: only communicate with your direct friends and avoid communicating with strangers;

3. Core essence:

(1) Instantiated objects do not use new, but use factory methods instead

(2) The implementation class will be selected to create objects for unified management and control. This decouples the caller from our implementation class.

Simple factory mode

1.Car interface

package com.etc.factory.simple;

public interface Car {
    void name();
}

2. Wu Ling

package com.etc.factory.simple;

public class WuLing implements Car{
    @Override
    public void name() {
        System.out.println("Wuling");
    }
}

3. Tesla

package com.etc.factory.simple;

public class Tesla implements Car{
    @Override
    public void name() {
        System.out.println("Tesla");
    }
}

4.CarFactory (create factory)

package com.etc.factory.simple;
//Simple factory mode static factory mode
//Opening and closing principle
public class CarFactory {
    //Method 1
    public static Car getCar(String car) {
        //If you add other classes, you need to modify the following code and modify the logic
        if (car.equals("Wuling")) {
            return new WuLing();
        }else if (car.equals("Tesla")) {
            return new Tesla();
        }else {
            return null;
        }
    }

    //What about adding a car if there is a problem?
    //Method 2 without modifying the original logic
    public static Car getwuling() {
        return new WuLing();
    }
    public static Car getTesla() {
        return new Tesla();
    }
}

5.Consumer

package com.etc.factory.simple;

public class Consumer {
    public static void main(String[] args) {
        // 1 general creation
//        Car car1=new WuLing();
//        Car car2=new Tesla();

        // 2 create using factory
        Car car1 = CarFactory.getCar("Wuling");
        Car car2 = CarFactory.getCar("Tesla");
        car1.name();
        car2.name();

    }
}

Factory method model

1.car interface

package com.etc.factory.method;

public interface Car {
    void name();
}

2.CarFactory interface

package com.etc.factory.method;
//Factory method model
public interface CarFactory {
    Car getCar();
}

3. Wu Ling

package com.etc.factory.simple;

public class WuLing implements Car{
    @Override
    public void name() {
        System.out.println("Wuling");
    }
}

4. Create a separate WuLingFactory for Wuling

package com.etc.factory.method;

public class WuLingFactory implements CarFactory {
    @Override
    public Car getCar() {
        return new WuLing();
    }
}

5. Tesla

package com.etc.factory.simple;

public class Tesla implements Car{
    @Override
    public void name() {
        System.out.println("Tesla");
    }
}

6. Create a separate factory for Tesla

package com.etc.factory.method;

public class TeslaFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new Tesla();
    }
}

7.Consumer

package com.etc.factory.method;


public class Consumer {
    public static void main(String[] args) {

        Car car1 = new WuLingFactory().getCar();
        Car car2 = new TeslaFactory().getCar();

        car1.name();
        car2.name();
    }
}

Structural complexity: simple

Code complexity: simple

Programming complexity: simple

Management complexity: simple

According to the design principle: factory method mode!

According to the actual business: simple factory mode!

Picture interpretation

Abstract factory pattern

Code demonstration

1.IPhoneProduct interface

//Mobile product interface
public interface IPhoneProduct {
    void start();
    void shutdown();
    void callup();
    void sendMS();
}

2.IRouteProduct interface

//Router product interface
public interface IRouteProduct {
    void start();
    void shutdown();
    void openWife();
    void setting();
}

3. Xiaomi mobile phone

package com.etc.factory.abstract1;

public class XiaomiPhone implements IPhoneProduct {
    @Override
    public void start() {
        System.out.println("Turn on Xiaomi mobile phone");
    }

    @Override
    public void shutdown() {
        System.out.println("Turn off Xiaomi mobile phone");
    }

    @Override
    public void callup() {
        System.out.println("Xiaomi called");
    }

    @Override
    public void sendMS() {
        System.out.println("Xiaomi sends text messages");
    }
}

4. Xiaomi router

package com.etc.factory.abstract1;

public class XiaomiRouter implements IRouteProduct{
    @Override
    public void start() {
        System.out.println("Start Xiaomi router");
    }

    @Override
    public void shutdown() {
        System.out.println("Turn off Xiaomi router");
    }

    @Override
    public void openWife() {
        System.out.println("Open Xiaomi wifi");

    }

    @Override
    public void setting() {
        System.out.println("Set up Xiaomi router");
    }
}

5. Huawei Mobile

package com.etc.factory.abstract1;

public class HuaweiPhone implements IPhoneProduct {
    @Override
    public void start() {
        System.out.println("Turn on Huawei mobile phone");
    }

    @Override
    public void shutdown() {
        System.out.println("Turn off Huawei mobile phone");
    }

    @Override
    public void callup() {
        System.out.println("Huawei calls");
    }

    @Override
    public void sendMS() {
        System.out.println("Huawei sends text messages");
    }
}

6. Huawei router

package com.etc.factory.abstract1;

public class HuaweiRouter implements IRouteProduct{
    @Override
    public void start() {
        System.out.println("Start Huawei router");
    }

    @Override
    public void shutdown() {
        System.out.println("Turn off Huawei router");
    }

    @Override
    public void openWife() {
        System.out.println("Start Huawei wifi");

    }

    @Override
    public void setting() {
        System.out.println("Set up Huawei router");
    }
}

7. Abstract Factory

package com.etc.factory.abstract1;
//Abstract product factory
public interface IProductFactory {
    //Production of mobile phones
    IPhoneProduct iphoneProduct();
    //Production router
    IRouteProduct routeProduct();
}

8. Xiaomi factory

package com.etc.factory.abstract1;

public class XiaomiFactory implements IProductFactory{
    @Override
    public IPhoneProduct iphoneProduct() {
        return new XiaomiPhone();
    }

    @Override
    public IRouteProduct routeProduct() {
        return new XiaomiRouter();
    }
}

9. Huawei factory

package com.etc.factory.abstract1;

public class HuaweiFactory implements IProductFactory{
    @Override
    public IPhoneProduct iphoneProduct() {
        return new HuaweiPhone();
    }

    @Override
    public IRouteProduct routeProduct() {
        return new HuaweiRouter();
    }
}

10. Client use

package com.etc.factory.abstract1;

public class Client {
    public static void main(String[] args) {
        System.out.println("=======Xiaomi series products=========");
        XiaomiFactory xiaomiFactory = new XiaomiFactory();

        IPhoneProduct iPhoneProduct = xiaomiFactory.iphoneProduct();
        iPhoneProduct.callup();
        iPhoneProduct.sendMS();

        IRouteProduct iRouteProduct = xiaomiFactory.routeProduct();
        iRouteProduct.openWife();

        System.out.println("=======Huawei series products=========");
        HuaweiFactory huaweiFactory = new HuaweiFactory();

        iPhoneProduct = huaweiFactory.iphoneProduct();
        iPhoneProduct.callup();
        iPhoneProduct.sendMS();

        iRouteProduct = huaweiFactory.routeProduct();
        iRouteProduct.openWife();
    }
}

Builder pattern

Code demonstration

1. Abstract builder

package com.etc.factory.builder;
//Abstract Builder: method
public abstract class Builder {
    abstract void buildA();//foundation
    abstract void buildB();//Reinforcement works
    abstract void buildC();//Lay wires
    abstract void buildD();//Whitewash

    //Completion: get the product
    abstract Product getProduct();
}

2. Product: House

package com.etc.factory.builder;
//Product: House
public class Product {
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;

    public String getBuildA() {
        return buildA;
    }

    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }

    public String getBuildB() {
        return buildB;
    }

    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }

    public String getBuildC() {
        return buildC;
    }

    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }

    public String getBuildD() {
        return buildD;
    }

    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}

3. Specific builders

package com.etc.factory.builder;
//Specific Builder: Workers
public class Worker extends Builder {
    private Product product;

    public Worker(){
        product=new Product();
    }
    @Override
    void buildA() {
        product.setBuildA("foundation");
        System.out.println("foundation");
    }

    @Override
    void buildB() {
        product.setBuildB("Reinforcement works");
        System.out.println("Reinforcement works");
    }

    @Override
    void buildC() {
        product.setBuildB("Lay wires");
        System.out.println("Lay wires");
    }

    @Override
    void buildD() {
        product.setBuildB("Whitewash");
        System.out.println("Whitewash");
    }

    @Override
    Product getProduct() {
        return product;
    }
}

4. Commander

package com.etc.factory.builder;
//Command: the core is responsible for directing the construction of a project. How to build the project is determined by it
public class Director {

    //Instruct the workers to build the house in order
    public Product build(Builder builder){
        builder.buildA();
        builder.buildB();
        builder.buildC();
        builder.buildD();
        return builder.getProduct();
    }
}

5. Test

package com.etc.factory.builder;

public class Test {
    public static void main(String[] args) {
        //command
        Director director = new Director();
        //Direct specific workers to complete the product
        Product build = director.build(new Worker());
        //The order is determined by the workers
        System.out.println(build.toString());
    }
}

Code re understanding

1. Builder

package com.etc.factory.builder2;
//builder
public abstract class Builder {
    abstract Builder buildA(String msg);//hamburger
    abstract Builder buildB(String msg);//cola
    abstract Builder buildC(String msg);//French fries
    abstract Builder buildD(String msg);//Dessert

    abstract Product getProduct();


}

2. Products

package com.etc.factory.builder2;
//Product: package
public class Product {
    private String BuildA="hamburger";
    private String BuildB="cola";
    private String BuildC="French fries";
    private String BuildD="Dessert";

    public String getBuildA() {
        return BuildA;
    }

    public void setBuildA(String buildA) {
        BuildA = buildA;
    }

    public String getBuildB() {
        return BuildB;
    }

    public void setBuildB(String buildB) {
        BuildB = buildB;
    }

    public String getBuildC() {
        return BuildC;
    }

    public void setBuildC(String buildC) {
        BuildC = buildC;
    }

    public String getBuildD() {
        return BuildD;
    }

    public void setBuildD(String buildD) {
        BuildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "BuildA='" + BuildA + '\'' +
                ", BuildB='" + BuildB + '\'' +
                ", BuildC='" + BuildC + '\'' +
                ", BuildD='" + BuildD + '\'' +
                '}';
    }
}

3. Specific builders

package com.etc.factory.builder2;
//Specific builder
public class Worker extends Builder{

    private Product product;

    public Worker(){
        product=new Product();
    }
    @Override
    Builder buildA(String msg) {
        product.setBuildA(msg);
        return this;
    }

    @Override
    Builder buildB(String msg) {
        product.setBuildB(msg);
        return this;
    }

    @Override
    Builder buildC(String msg) {
        product.setBuildC(msg);
        return this;
    }

    @Override
    Builder buildD(String msg) {
        product.setBuildD(msg);
        return this;
    }

    @Override
    Product getProduct() {
        return product;
    }

}

4. Test

package com.etc.factory.builder2;

public class Test {
    public static void main(String[] args) {
        //waiter
        Worker worker = new Worker();
         //Chain programming: on the original basis, you can combine freely. If you don't combine, there is also a default package
        Product product = worker.buildA("Family bucket")
                .buildB("Sprite").getProduct();

        System.out.println(product.toString());
        //Product{BuildA = 'family bucket', BuildB = 'sprite', BuildC = 'French Fries', BuildD =' dessert '}
    }
}

Prototype mode

Code demo demo01

1.Video

package com.etc.prototype.demo01;

import java.util.Date;

/**
 * 1.Implement an interface clonable
 * 2.Override a method clone()
 */
public class Video implements Cloneable{

    private String name;
    private Date createTime;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public Video() {
    }

    public Video(String name, Date createTime) {
        this.name = name;
        this.createTime = createTime;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Video{" +
                "name='" + name + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}

2.Bilibili

package com.etc.prototype.demo01;

import java.util.Date;

/**
 * Clients: cloning
 */
public class Bilibili {
    public static void main(String[] args) throws CloneNotSupportedException {
        //Prototype object v1
        Date date = new Date();
        Video v1 = new Video("Madness theory java", date);
        Video v2 = (Video) v1.clone();
        System.out.println("v1=>"+v1);
        System.out.println("v2=>"+v2);
        System.out.println("=======");
        date.setTime(21312231); //Nothing has changed
        System.out.println("v1=>"+v1);
        System.out.println("v2=>"+v2);
        /*
        v1=>Video{name='Crazy God said java', createTime=Sat Feb 19 14:39:15 CST 2022}
v2=>Video{name='Crazy God said java', createTime=Sat Feb 19 14:39:15 CST 2022}
=======
v1=>Video{name='Crazy God said java', createTime=Thu Jan 01 13:55:12 CST 1970}
v2=>Video{name='Crazy God said java', createTime=Thu Jan 01 13:55:12 CST 1970}
         */
  }
}
/*
        //v1 Clone v2
//        Video v2 = new Video("Mad God said java", date);
        Video v2 = (Video) v1.clone();
        System.out.println("v2=>"+v2);
        System.out.println("v2=>hash:"+v2.hashCode());

* v1=>Video{name='Crazy God said java', createTime=Sat Feb 19 14:33:53 CST 2022}
v1=>hash:1028214719
v2=>Video{name='Crazy God said java', createTime=Sat Feb 19 14:33:53 CST 2022}
v2=>hash:500977346

                 v2.setName("Clone:Crazy God says java ");
                System.out.println("v2=>"+v2);
                //v2=>Video{name='Clone:Crazy God said java', createTime=Sat Feb 19 14:34:49 CST 2022}

                */

Demo demo02 deep clone

1.Video

package com.etc.prototype.demo02;

import java.util.Date;

public class Video implements Cloneable{

    private String name;
    private Date createTime;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        //Implement deep cloning~
        Video v = (Video) obj;
        v.createTime = (Date) this.createTime.clone();//Clone the properties of this object as well~
        return obj;
    }

    public Video() {
    }

    public Video(String name, Date createTime) {
        this.name = name;
        this.createTime = createTime;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Video{" +
                "name='" + name + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}

2.Bilibili

package com.etc.prototype.demo02;

import java.util.Date;
//Prototype mode + factory mode = = "new" = "prototype mode
public class Bilibili {
    public static void main(String[] args) throws CloneNotSupportedException {
        //Prototype object v1
        Date date = new Date();
        Video v1 = new Video("Madness theory java", date);
        Video v2 = (Video) v1.clone();
        System.out.println("v1=>"+v1);
        System.out.println("v2=>"+v2);
        System.out.println("=======");
        date.setTime(21312231);
        System.out.println("v1=>"+v1);
        System.out.println("v2=>"+v2);
/*
v1=>Video{name='Crazy God said java', createTime=Sat Feb 19 14:43:22 CST 2022}
v2=>Video{name='Crazy God said java', createTime=Sat Feb 19 14:43:22 CST 2022}
=======
v1=>Video{name='Crazy God said java', createTime=Thu Jan 01 13:55:12 CST 1970}
v2=>Video{name='Crazy God said java', createTime=Sat Feb 19 14:43:22 CST 2022}
  */
  }
}

Adapter mode

Code demonstration

1.Adaptee

package com.etc.adapter;
//Class to be adapted: network cable
public class Adaptee {
    public void request(){
        System.out.println("Connect the network cable to the Internet");
    }
}

2.NetToUsb

package com.etc.adapter;
//Abstract implementation of interface converter
public interface NetToUsb {
    //Function: handle request network cable = "usb"
    public void handleRequest();
}

3.Adapter

package com.etc.adapter;
//The real adapter needs to be connected with USB and network cable

//Inheritance (class adapter inheritance)
//Combination (object adapter: common)
public class Adapter extends Adaptee implements NetToUsb{

    @Override
    public void handleRequest() {
        super.request();//You can surf the Internet
    }
}

4.Computer

package com.etc.adapter;
//Client class: if you want to surf the Internet, you can't plug in the network cable
public class Computer {
    //Our computers need to be connected to an adapter to access the Internet
    public void net(NetToUsb netToUsb){
        //Specific implementation of Internet access ~ find an adapter
        netToUsb.handleRequest();

    }

    public static void main(String[] args) {
        //Computer adapter cable
        Computer computer = new Computer();
        Adaptee adaptee = new Adaptee();
        Adapter adapter = new Adapter();
        Adapter2 adapter2=new Adapter2(adaptee);

       // computer.net(adapter);
        computer.net(adapter2);
    }
}

Upgraded Adapter2

package com.etc.adapter;
//The real adapter needs to be connected with USB and network cable

//Inheritance (class adapter inheritance)
//Combination (object adapter: common)
public class Adapter2  implements NetToUsb{
    private Adaptee adaptee;

    public Adapter2(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void handleRequest() {
        adaptee.request();
    }
}

Bridging mode

Code demonstration

1.Brand

package com.etc.bridge;
//brand
public interface Brand {
    void info();
}

2.Lenovo Lenovo brand

package com.etc.bridge;
//Lenovo brand
public class Lenovo implements Brand{
    @Override
    public void info() {
        System.out.print("association");
    }
}

3. Apple brand

package com.etc.bridge;
//Apple brand
public class Apple implements Brand{

    @Override
    public void info() {
        System.out.print("Apple");
    }
}

4. Combination

package com.etc.bridge;
//Abstract computer type class
public abstract class Computer {
    //Combined brand
    protected Brand brand;

    public Computer(Brand brand) {
        this.brand = brand;
    }

    public  void info(){
        brand.info();//Own brand
    }
}
class Desktop extends Computer{

    public Desktop(Brand brand) {
        super(brand);
    }

    @Override
    public void info() {
        super.info();
        System.out.print("Desktop");
    }
}

class Laptop extends Computer{

    public Laptop(Brand brand) {
        super(brand);
    }

    @Override
    public void info() {
        super.info();
        System.out.print("notebook");
    }
}

5. Test

package com.etc.bridge;

public class Test {
    public static void main(String[] args) {
        //Apple notebook
        Computer computer = new Laptop(new Apple());
        computer.info();
        System.out.println();
        //Lenovo desktop
        Computer computer2 = new Desktop(new Lenovo());
        computer2.info();
    }
}

Topics: Design Pattern