常用的设计模式

23种设计模式

创造型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式

结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式

行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式、访问者模式

OOP七大原则

一.单例模式

package com.example.demo.single;

/**
 * @Description: 饿汉式单例
 * @author: ZYQ
 * @date: 2021/3/25 10:53
 */
public class Hungry {

    /**
     * 浪费空间
     */
    /*private byte[] data1 = new byte[1024 * 1024];
    private byte[] data2 = new byte[1024 * 1024];
    private byte[] data3 = new byte[1024 * 1024];
    private byte[] data4 = new byte[1024 * 1024];*/

    //保证构造器私有
    private Hungry() {

    }

    private final static Hungry HUNGRY = new Hungry();

    public static Hungry getInstance() {
        return HUNGRY;
    }

}
饿汉式

注意点:

构造器私有

饿汉式立即加载对象,可能会造成空间的浪费,一般不使用。

package com.example.demo.single;

/**
 * @Description: 懒汉式单例
 * @author: ZYQ
 * @date: 2021/3/25 11:05
 */
public class LazyMan {

    //构造器私有
    private LazyMan() {
        System.out.println("构造1次");
    }
    
    private static volatile LazyMan lazyMan = null;

    public static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();
                }
            }
        }
        return lazyMan;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                LazyMan.getInstance();
            }).start();
        }
    }
}
DCL懒汉式

懒汉式注意点

1.构造器私有

2.需要使用双重检测。若为单次检测,则多条线程可能同时进入if中,造成多次构造。

3.需要对 lazyMan 对象添加 volatile 修饰词。因此new对象的过程不是原子性的,其分为3步:1.为对象分配内存空间 2.初始化对象 3.将实例指向该空间。在此过程中可能会发生指令重排导致第三步优先于第二步执行。当第三步执行完而还未进行初始化时,若此时有其余线程来到第一层判断,则会误判为lazyMan对象非空,从而直接返回一个空的lazyMan,造成错误。

二.工厂模式

作用:实现了创建者和调用者的分离

详细分类:1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式

核心本质:1.实例化对象不使用new,用工厂方法替代。2.将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

一.简单工厂模式

package com.example.demo.factory.simple;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 13:39
 */
public interface Car {

    void SayName();

}
Car接口
package com.example.demo.factory.simple;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 13:40
 */
public class WuLing implements Car {

    @Override
    public void SayName() {
        System.out.println("我是五菱宏光");
    }
}
Car的实现类-WuLing
package com.example.demo.factory.simple;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 13:45
 */
public class Tesla implements Car {

    @Override
    public void SayName() {
        System.out.println("特斯拉");
    }
}
Car的实现类-Tesla
package com.example.demo.factory.simple;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 13:57
 */
public class CarFactory {

    public static Car getCar(String carName) {
        if (carName.equals("五菱"))
            return new WuLing();
        else if (carName.equals("特斯拉"))
            return new Tesla();
        else
            return null;
    }
}
工厂类CarFactory
package com.example.demo.factory.simple;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 14:06
 */
public class Consumer {
    public static void main(String[] args) {
        Car car = CarFactory.getCar("五菱");
        Car car2 = CarFactory.getCar("特斯拉");
        car.SayName();
        car2.SayName();
    }
}
调用者

简单工厂模式实现起来方便快捷,也不复杂,但是不符合开闭原则。在扩展一个新的实现类时,需要在工厂类中进行相应的代码修改和增加。

二.工厂方法模式

在简单工厂模式的基础上增加下列代码

package com.example.demo.factory.method;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 14:17
 */
public interface CarFactory {

    Car getCar();

}
CarFactory接口
package com.example.demo.factory.method;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 14:18
 */
public class WuLingFactory implements CarFactory {

    @Override
    public Car getCar() {
        return new WuLing();
    }
}
CarFactory的实现类-WuLingFactory
package com.example.demo.factory.method;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 14:21
 */
public class TeslaFactory implements CarFactory {

    @Override
    public Car getCar() {
        return new Tesla();
    }
}
CarFactory的实现类-TeslaFactory
package com.example.demo.factory.method;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 14:06
 */
public class Consumer {
    public static void main(String[] args) {
        Car wuLing = new WuLingFactory().getCar();
        Car tesla = new TeslaFactory().getCar();
        wuLing.SayName();
        tesla.SayName();

        //添加新车
        Car MoBai = new MoBaiFactory().getCar();
        MoBai.SayName();
    }
}
调用者

细分为了多个工厂,每个工厂对应一种资源

工厂方法模式解决了简单工厂模式的扩展问题,符合开闭原则。但是可以发现其类和接口的数量会非常的多。

三.抽象工厂模式

package com.example.demo.factory.abstractFactory;

/**
 * @Description: 抽象产品工厂
 * @author: ZYQ
 * @date: 2021/3/25 15:54
 */
public interface ProductFactory {

    //生产手机
    PhoneProduct productPhone();

    //生产路由器
    RouterProduct productRouter();
}
总抽象工厂接口ProductFactory
package com.example.demo.factory.abstractFactory;

/**
 * @Description: 手机产品接口
 * @author: ZYQ
 * @date: 2021/3/25 15:46
 */
public interface PhoneProduct {

    void start();
    void shutdown();
    void callUp();
    void sendSMS();

}
接口PhoneProduct
package com.example.demo.factory.abstractFactory;

/**
 * @Description: 路由器产品接口
 * @author: ZYQ
 * @date: 2021/3/25 15:47
 */
public interface RouterProduct {

    void start();
    void shutdown();
    void openWifi();
    void setting();

}
接口RouterProduct
package com.example.demo.factory.abstractFactory;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 16:06
 */
public class HuaWeiFactory implements ProductFactory {

    @Override
    public PhoneProduct productPhone() {
        return new HuWeiPhone();
    }

    @Override
    public RouterProduct productRouter() {
        return new HuaWeiRouter();
    }
}
分工厂HuaWeiFactory
package com.example.demo.factory.abstractFactory;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 15:50
 */
public class HuaWeiRouter implements RouterProduct {

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

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

    @Override
    public void openWifi() {
        System.out.println("华为路由器打开wifi");
    }

    @Override
    public void setting() {
        System.out.println("华为路由器设置参数");
    }
}
接口实现类HuaWeiRouter
package com.example.demo.factory.abstractFactory;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 15:49
 */
public class HuWeiPhone implements PhoneProduct{

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

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

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

    @Override
    public void sendSMS() {
        System.out.println("华为手机发短信");
    }
}
接口实现类HuWeiPhone
package com.example.demo.factory.abstractFactory;

/**
 * @Description:
 * @author: ZYQ
 * @date: 2021/3/25 16:08
 */
public class Client {
    public static void main(String[] args) {
        System.out.println("================小米系列产品====================");
        //小米工厂
        XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
        PhoneProduct xiaoMiPhone = xiaoMiFactory.productPhone();
        xiaoMiPhone.callUp();
        RouterProduct xiaoMiRouter = xiaoMiFactory.productRouter();
        xiaoMiRouter.openWifi();
        System.out.println("================华为系列产品====================");
        HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
        PhoneProduct huaWeiPhone = huaWeiFactory.productPhone();
        huaWeiPhone.callUp();
    }
}
调用者

交叉型的对象统一管理比较适合

posted @ 2021-03-25 13:16  缘未到  阅读(52)  评论(0编辑  收藏  举报