常用设计模式之单例模式、策略模式、工厂模式

单例模式

单例模式属于创建型模式

饿汉模式:立即加载

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){
    }  
    public static Singleton getInstance() {  
        return instance;  
    }  
}

懒汉模式,懒加载

  • 线程不安全

    public class Singleton {
        private static Singleton instance;
        private Singleton (){
        }
        public static Singleton getlnstance() {
            if (instance == null){
                instance = new Singleton();
            }
             return instance;
        }
    }
  • 线程安全

    public class Singleton {  
        private static Singleton instance;  
        private Singleton (){}  
        public static synchronized Singleton getInstance() {  
            if (instance == null) {  
                instance = new Singleton();  
            }  
            return instance;  
        }  
    }

  • 双重锁

    public class Singleton {  
        private volatile static Singleton singleton;  
        private Singleton (){
        }  
        public static Singleton getSingleton() {  
            if (singleton == null) {  
                synchronized (Singleton.class) {  
                    if (singleton == null) {  
                        singleton = new Singleton();  
                    }  
                }  
            }  
            return singleton;  
        }  
    }
  • 静态内部类

    public class Singleton {
        private Singleton() {
        }
        
        //内部类在外部类调用的时候才会被初始化
        // 内部类一定要在方法调用之前初始化
        private static class SingletonInstance {
            private static final Singleton instance = new Singleton();
        }
        
        // static 使单例空间共享
        // final使得方法不能被重写重载
        public static final Singleton getInstance() {
            return SingletonInstance.instance;
        }
    }

策略模式

策略模式属于行为型模式

核心思想是对算法进行封装,委派给不同对象来管理。

比如我们旅游可以选择出行的策略有:自行车、电动车、公交车等-

  • 结构

    策略模式饱汉三种类:

    角色 关系 作用
    抽象策略类strategy 是所有类的父类 定义一个公共接口,定义一些算法标识和抽象方法
    具体策略concrete strategy 是抽象策略的接口实现类 实现抽象策略定义的抽象方法,描述具体法的算法实现
    环境context 维护一个抽象策略类的引用实例 委托策略变量,调用具体策略所实现的抽象策略接口中的方法

工厂模式

概念

工厂模式,提供一种创建对象的方式,

在创建对象时提供一种封装机制,将实际创建对象的代码与使用代码分离

定义一个创建对象的接口,让其子类自己决定实例化哪个工厂类,工厂模式使其创建过程延迟到子类进行。

不暴露对象创建逻辑的情况下创建对象

主要解决接口选择问题

角色

抽象产品:产品的共同接口或抽象类

具体产品:实现了抽象产品接口

抽象工厂:声明创建产品的抽象方法

具体工厂实现抽象工厂接口

分类

分为:简单工厂、方法工厂、抽象工厂

实现

  • 简单工厂
//简单工厂:每创建一个产品就会增加一个对应的具体的工厂类
// 违背了开闭原则,不属于23种GOF
public class Test {
    public static void main(String[] args) {
        Baozi baozi = SimpleFactory.createBaozi("jiangrou");
        System.out.println(baozi.createBaozi());
        Baozi baozi1 = SimpleFactory.createBaozi("jiangrou");
        System.out.println(baozi1.createBaozi());
    }
}
​
//抽象工厂
interface Baozi {
    String createBaozi();
}
​
//产品的具体的实现
class JiangRou implements Baozi {
    @Override
    public String createBaozi() {
        return "酱肉";
    }
}
​
class XianRou implements Baozi {
    @Override
    public String createBaozi() {
        return "鲜肉";
    }
}
​
//工厂类是关键
//判断要做什么包子,整个做包子的生产都被这个工厂类封装起来了
//用户不需要关注这里面的细节
//适合创建对象比较少的情况,只需传递具体参数,忽略生产细节
class SimpleFactory {
    public static Baozi createBaozi(String type) {
        switch (type) {
            case "jiangrou":
                return new JiangRou();
            case "xianrou":
                return new XianRou();
        }
        return null;
    }
}
  • 方法工厂
//工厂方法:定义一个用于创建产品的接口,由子类决定生产什么产品
//如果还有其他类型的包子,需要在SimpleFactory里面加判断,因为只能在那里生产包子,违反开闭原则
//是简单工厂的的抽象,抽象一个工厂接口,
//增加新产品时,需要增加新的工厂
//一个工厂只生产一种产品
public class Test {
    public IPhone getPhoneGrete(String type){
        if ("huawei".equals(type)){
            HuaWeiPhoneFactory huaWeiPhoneFactory = new HuaWeiPhoneFactory();
            IPhone phone = huaWeiPhoneFactory.createPhone();
            return phone;
        }
        if ("xiaomi".equals(type)){
            XiaomiPhoneFactory xiaomiPhoneFactory = new XiaomiPhoneFactory();
            IPhone phone = xiaomiPhoneFactory.createPhone();
            return phone;
        }
        return null;
    }
    public IPC getPcCreate(String type){
        if ("huawei".equals(type)){
            HuaWeiPCFactory huaWeiPCFactory = new HuaWeiPCFactory();
            IPC pc = huaWeiPCFactory.createPC();
            return pc;
        }
        if ("xiaomi".equals(type)){
            XiaomiPCFactory xiaomiPCFactory = new XiaomiPCFactory();
            IPC pc = xiaomiPCFactory.createPC();
            return pc;
        }
        return null;
    }

    public static void main(String[] args) {
        Test test = new Test();
        IPC huawei = test.getPcCreate("huawei");
        IPC xiaomi = test.getPcCreate("xiaomi");
        IPhone xiaomi1 = test.getPhoneGrete("xiaomi");

    }
}
//抽象产品
interface IPhone {
    void createPhone();
}
interface IPC {
    void createPC();
}
interface ISW {
    void createSW();
}
//具体的产品
class HuaWeiPhone implements IPhone {
    @Override
    public void createPhone() {

    }
}
class XiaoMiPhone implements IPhone {
    @Override
    public void createPhone() {
    }
}
class HuaWeiPC implements IPC {
    @Override
    public void createPC() {

    }
}
class XiaoMiPC implements IPC {
    @Override
    public void createPC() {
    }
}

//手机工厂
interface PhoneAbstractFactory {
    IPhone createPhone();
}
//电脑工厂
interface PCAbstractFactory {
    IPC createPC();
}
//华为手机工厂
class HuaWeiPhoneFactory implements PhoneAbstractFactory {
    @Override
    public IPhone createPhone() {
        return new HuaWeiPhone();
    }
}
//华为电脑工厂
class HuaWeiPCFactory implements PCAbstractFactory {

    @Override
    public IPC createPC() {
        return new HuaWeiPC();
    }
}
//小米手机工厂
class XiaomiPhoneFactory implements PhoneAbstractFactory {


    @Override
    public IPhone createPhone() {
        return new XiaoMiPhone();
    }
}
//小米电脑工厂
class XiaomiPCFactory implements PCAbstractFactory {

    @Override
    public IPC createPC() {
        return new XiaoMiPC();
    }
}
  • 抽象工厂
//一个工厂可以生产不同产品等级的产品族
public class Test  {
    public static void main(String[] args) {
        HuaweiFactory huaweiFactory = new HuaweiFactory();
        huaweiFactory.createPhone();
        huaweiFactory.createPC();
        XiaomiFactory xiaomiFactory = new XiaomiFactory();
        xiaomiFactory.createPhone();
        xiaomiFactory.createPC();
    }
}

//抽象产品族
interface Phone {
    void createPhone();
}

interface PC {
    void createPC();
}

interface SWI {
    void createSWI();
}

//具体产品族
class XiaoMiPhone implements Phone {
    @Override
    public void createPhone() {
        System.out.println("小米手机");
    }
}
class XiaoMiSWI implements SWI {
    @Override
    public void createSWI() {
        System.out.println("小米手表");
    }
}

class HuaweiPhone implements Phone {
    @Override
    public void createPhone() {
        System.out.println("华为手机");
    }
}

class XiaoPC implements PC {
    @Override
    public void createPC() {
        System.out.println("小米电脑");
    }
}

class HuaweiPC implements PC {
    @Override
    public void createPC() {
        System.out.println("华为电脑");
    }
}


//抽象工厂,一个工厂可以生产不同产品等级的产品族
abstract class AbstractFactory {
    public abstract Phone createPhone();
    public abstract PC createPC();
    public abstract SWI ccreateSWI();
}

//具体工厂
class HuaweiFactory extends AbstractFactory {
    @Override
    public Phone createPhone() {
        return new HuaweiPhone();
    }

    @Override
    public PC createPC() {
        return new HuaweiPC();
    }

    @Override
    public SWI ccreateSWI() {
        return null;
    }
}
class XiaomiFactory extends AbstractFactory {


    @Override
    public Phone createPhone() {
        return new XiaoMiPhone();
    }

    @Override
    public PC createPC() {
        return new XiaoPC();
    }

    @Override
    public SWI ccreateSWI() {
        return new XiaoMiSWI();
    }
}

对比

简单工厂

  • 优点

    • 屏蔽产品的具体实现,调用者只关心产品的接口

  • 缺点

    • 增加产品,需要修改工厂类,违反了开闭原则

    • 工厂类集中了所有的实例的创建逻辑,违反高内聚责任分配原则

工厂方法

  • 优点

    • 继承简单工厂的优点,符合开闭原则

  • 缺点

    • 增加产品时,需要增加工厂类

抽象工厂

  • 优点

    • 不需要知道什么产品被创建

    • 可以通过具体的工厂创建多个对象,增加新的具体工厂和产品族方便

  • 缺点

    • 增加新的产品等级就比较复杂,需要修改抽象工厂和所有的具体工厂类

上一篇:《野蛮时代》数据分析项目实战——报告-一、引言


下一篇:Python 学习之生成图形验证码