23种设计模式

此笔记从B站狂神说Java 获取

什么是设计模式

在这里插入图片描述

学习设计模式的意义

23种设计模式_第1张图片

GoF23

23种设计模式_第2张图片

oop七大原则

(1)开闭原则: 一个软件的实体应当对扩展开放,对修改关闭;

(2)里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立

(3)依赖倒置原则:要面向接口编程,不要面向实现编程。

(4)单一职责原则:控制类的粒度大小、将对象解耦、提高其内聚性。

(5)接口隔离原则:要为各个类建立它们需要的专用接口

(6)迪米特法则:只与你的直接朋友交谈,不跟“陌生人”说话。

(7)合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

工厂模式

1、作用:实现创建者和调用者分离

2、00P七大原则:

(1)开闭原则: 一个软件的实体应当对扩展开放,对修改关闭;

(2)依赖倒转原则:要针对接口编程,不要针对实现编程;

(3)迪米特法则:只与你直接的朋友通信,而避免和陌生人通信;

3、核心本质:

(1)实例化对象不使用new, 用工厂方法代替

(2)将选择实现类, 创建对象统一管理和控制。 从而将调用者跟我们的实现类解耦。

23种设计模式_第3张图片

简单工厂模式

1.Car接口

package com.etc.factory.simple;

public interface Car {
    void name();
}

2.车 WuLing

package com.etc.factory.simple;

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

3.车 Tesla

package com.etc.factory.simple;

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

4.CarFactory (创建工厂)

package com.etc.factory.simple;
//简单工厂模式 静态工厂模式
//开闭原则
public class CarFactory {
    //方法一
    public static Car getCar(String car) {
        //如果添加其他类,需要修改下列代码,修改逻辑
        if (car.equals("五菱")) {
            return new WuLing();
        }else if (car.equals("特斯拉")) {
            return new Tesla();
        }else {
            return null;
        }
    }

    //出现问题 增加一个车呢?
    //方法二   不修改原逻辑的情况下
    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 常规创建
//        Car car1=new WuLing();
//        Car car2=new Tesla();

        // 2 使用工厂创建
        Car car1 = CarFactory.getCar("五菱");
        Car car2 = CarFactory.getCar("特斯拉");
        car1.name();
        car2.name();

    }
}

工厂方法模式

1.car接口

package com.etc.factory.method;

public interface Car {
    void name();
}

2.CarFactory接口

package com.etc.factory.method;
//工厂方法模式
public interface CarFactory {
    Car getCar();
}

3.车 WuLing

package com.etc.factory.simple;

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

4.给五菱单独创建个工厂 WuLingFactory

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("特斯拉");
    }
}

6.给Tesla单独创建个工厂 TeslaFactory

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();
    }
}

结构复杂度: simple

代码复杂度: simple

编程复杂度: simple

管理上的复杂度: simple

根据设计原则:工厂方法模式!

根据实际业务:简单工厂模式!

图片解释

23种设计模式_第4张图片

23种设计模式_第5张图片

抽象工厂模式

23种设计模式_第6张图片

23种设计模式_第7张图片

代码演示

1.IPhoneProduct接口

//手机产品接口
public interface IPhoneProduct {
    void start();
    void shutdown();
    void callup();
    void sendMS();
}

2.IRouteProduct接口

//路由器产品接口
public interface IRouteProduct {
    void start();
    void shutdown();
    void openWife();
    void setting();
}

3.小米手机

package com.etc.factory.abstract1;

public class XiaomiPhone implements IPhoneProduct {
    @Override
    public void start() {
        System.out.println("开启小米手机");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭小米手机");
    }

    @Override
    public void callup() {
        System.out.println("小米打电话");
    }

    @Override
    public void sendMS() {
        System.out.println("小米发短信");
    }
}

4.小米路由器

package com.etc.factory.abstract1;

public class XiaomiRouter implements IRouteProduct{
    @Override
    public void start() {
        System.out.println("启动小米路由器");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭小米路由器");
    }

    @Override
    public void openWife() {
        System.out.println("开启小米wifi");

    }

    @Override
    public void setting() {
        System.out.println("设置小米路由器");
    }
}

5.华为手机

package com.etc.factory.abstract1;

public class HuaweiPhone implements IPhoneProduct {
    @Override
    public void start() {
        System.out.println("开启华为手机");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭华为手机");
    }

    @Override
    public void callup() {
        System.out.println("华为打电话");
    }

    @Override
    public void sendMS() {
        System.out.println("华为发短信");
    }
}

6.华为路由器

package com.etc.factory.abstract1;

public class HuaweiRouter implements IRouteProduct{
    @Override
    public void start() {
        System.out.println("启动华为路由器");
    }

    @Override
    public void shutdown() {
        System.out.println("关闭华为路由器");
    }

    @Override
    public void openWife() {
        System.out.println("开启华为wifi");

    }

    @Override
    public void setting() {
        System.out.println("设置华为路由器");
    }
}

7.抽象工厂

package com.etc.factory.abstract1;
//抽象产品工厂
public interface IProductFactory {
    //生产手机
    IPhoneProduct iphoneProduct();
    //生产路由器
    IRouteProduct routeProduct();
}

8.小米工厂

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.华为工厂

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.客户端使用

package com.etc.factory.abstract1;

public class Client {
    public static void main(String[] args) {
        System.out.println("=======小米系列产品=========");
        XiaomiFactory xiaomiFactory = new XiaomiFactory();

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

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

        System.out.println("=======华为系列产品=========");
        HuaweiFactory huaweiFactory = new HuaweiFactory();

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

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

建造者模式

23种设计模式_第8张图片

23种设计模式_第9张图片

代码演示

1.抽象的建造者

package com.etc.factory.builder;
//抽象的建造者 : 方法
public abstract class Builder {
    abstract void buildA();//地基
    abstract void buildB();//钢筋工程
    abstract void buildC();//铺电线
    abstract void buildD();//粉刷

    //完工 :得到产品
    abstract Product getProduct();
}

2.产品: 房子

package com.etc.factory.builder;
//产品: 房子
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.具体的建造者

package com.etc.factory.builder;
//具体的建造者 : 工人
public class Worker extends Builder {
    private Product product;

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

    @Override
    void buildB() {
        product.setBuildB("钢筋工程");
        System.out.println("钢筋工程");
    }

    @Override
    void buildC() {
        product.setBuildB("铺电线");
        System.out.println("铺电线");
    }

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

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

4.指挥者

package com.etc.factory.builder;
//指挥 :核心 负责指挥构建一个工程,工程如何构建,由它决定
public class Director {

    //指挥工人按照顺序建房子
    public Product build(Builder builder){
        builder.buildA();
        builder.buildB();
        builder.buildC();
        builder.buildD();
        return builder.getProduct();
    }
}

5.测试

package com.etc.factory.builder;

public class Test {
    public static void main(String[] args) {
        //指挥
        Director director = new Director();
        //指挥 具体的工人完成  产品
        Product build = director.build(new Worker());
        //顺序由工人决定
        System.out.println(build.toString());
    }
}

代码再理解

1.建造者

package com.etc.factory.builder2;
//建造者
public abstract class Builder {
    abstract Builder buildA(String msg);//汉堡
    abstract Builder buildB(String msg);//可乐
    abstract Builder buildC(String msg);//薯条
    abstract Builder buildD(String msg);//甜点

    abstract Product getProduct();


}

2.产品

package com.etc.factory.builder2;
//产品 : 套餐
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) {
        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.具体的建造者

package com.etc.factory.builder2;
//具体的建造者
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.测试

package com.etc.factory.builder2;

public class Test {
    public static void main(String[] args) {
        //服务员
        Worker worker = new Worker();
         //链式编程 : 在原来的基础上,可以自由组合了,如果不组合,也有默认的套餐
        Product product = worker.buildA("全家桶")
                .buildB("雪碧").getProduct();

        System.out.println(product.toString());
        //Product{BuildA='全家桶', BuildB='雪碧', BuildC='薯条', BuildD='甜点'}
    }
}

原型模式

代码演示 demo01

1.Video

package com.etc.prototype.demo01;

import java.util.Date;

/**
 * 1.实现一个接口 Cloneable
 * 2.重写一个方法 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;

/**
 * 客户端 : 克隆
 */
public class Bilibili {
    public static void main(String[] args) throws CloneNotSupportedException {
        //原型对象 v1
        Date date = new Date();
        Video v1 = new Video("狂神说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='狂神说java', createTime=Sat Feb 19 14:39:15 CST 2022}
v2=>Video{name='狂神说java', createTime=Sat Feb 19 14:39:15 CST 2022}
=======
v1=>Video{name='狂神说java', createTime=Thu Jan 01 13:55:12 CST 1970}
v2=>Video{name='狂神说java', createTime=Thu Jan 01 13:55:12 CST 1970}
         */
  }
}
/*
        //v1 克隆 v2
//        Video v2 = new Video("狂神说java", date);
        Video v2 = (Video) v1.clone();
        System.out.println("v2=>"+v2);
        System.out.println("v2=>hash:"+v2.hashCode());

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

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

                */

23种设计模式_第10张图片

代码演示 demo02 深克隆

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();
        //实现深克隆~
        Video v = (Video) obj;
        v.createTime = (Date) this.createTime.clone();//将这个对象的属性也进行克隆~
        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;
//原型模式+工厂模式  ==》new 《=》 原型模式
public class Bilibili {
    public static void main(String[] args) throws CloneNotSupportedException {
        //原型对象 v1
        Date date = new Date();
        Video v1 = new Video("狂神说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='狂神说java', createTime=Sat Feb 19 14:43:22 CST 2022}
v2=>Video{name='狂神说java', createTime=Sat Feb 19 14:43:22 CST 2022}
=======
v1=>Video{name='狂神说java', createTime=Thu Jan 01 13:55:12 CST 1970}
v2=>Video{name='狂神说java', createTime=Sat Feb 19 14:43:22 CST 2022}
  */
  }
}

适配器模式

23种设计模式_第11张图片

23种设计模式_第12张图片

代码演示

1.Adaptee

package com.etc.adapter;
//要被适配的类 : 网线
public class Adaptee {
    public void request(){
        System.out.println("连接网线上网");
    }
}

2.NetToUsb

package com.etc.adapter;
//接口转换器的抽象实现
public interface NetToUsb {
    //作用: 处理请求 网线=》usb
    public void handleRequest();
}

3.Adapter

package com.etc.adapter;
//真正的适配器 需要连接USB,连接网线

//继承 (类适配器 单继承)
//组合 (对象适配器:常用)
public class Adapter extends Adaptee implements NetToUsb{

    @Override
    public void handleRequest() {
        super.request();//可以上网了
    }
}

4.Computer

package com.etc.adapter;
//客户端类:想上网  插不上网线
public class Computer {
    //我们的电脑需要连接上转接器才可以上网
    public void net(NetToUsb netToUsb){
        //上网的具体实现~ 找一个转接头
        netToUsb.handleRequest();

    }

    public static void main(String[] args) {
        //电脑 适配器 网线
        Computer computer = new Computer();
        Adaptee adaptee = new Adaptee();
        Adapter adapter = new Adapter();
        Adapter2 adapter2=new Adapter2(adaptee);

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

升级版 Adapter2

package com.etc.adapter;
//真正的适配器 需要连接USB,连接网线

//继承 (类适配器 单继承)
//组合 (对象适配器:常用)
public class Adapter2  implements NetToUsb{
    private Adaptee adaptee;

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

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

桥接模式

23种设计模式_第13张图片

23种设计模式_第14张图片

23种设计模式_第15张图片

代码演示

1.Brand

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

2.Lenovo联想品牌

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

3.苹果品牌

package com.etc.bridge;
//苹果品牌
public class Apple implements Brand{

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

4.组合

package com.etc.bridge;
//抽象的电脑类型类
public abstract class Computer {
    //组合 品牌
    protected Brand brand;

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

    public  void info(){
        brand.info();//自带品牌
    }
}
class Desktop extends Computer{

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

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

class Laptop extends Computer{

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

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

5.测试

package com.etc.bridge;

public class Test {
    public static void main(String[] args) {
        //苹果笔记本
        Computer computer = new Laptop(new Apple());
        computer.info();
        System.out.println();
        //联想台式机
        Computer computer2 = new Desktop(new Lenovo());
        computer2.info();
    }
}

你可能感兴趣的:(设计模式,设计模式)