设计模式(2/23)

设计模式

创建型模式

1. 单例模式

定义

提供创建对象的方式,确保只有一个对象被创建。

意义

节约资源。

缺点

引入了线程安全问题。

设计
  • 线程安全
  • 延迟加载
  • 代码安全:防止序列化、反射攻击
  • 性能
实现方法对比
实现线程安全延迟加载性能序列化/反射
饿汉式YY
懒汉式:无锁YY
懒汉式:有锁YY
双重检查YYY
静态内部类YYY
枚举YYY
扩展
  1. 双重检测的指令重排问题:volatile。避免指令重排

  2. 非枚举实现的序列化问题:实现 readResolve。大致原理浅拷贝

    // 如饿汉式
    private Singleton() {}
    private static Singleton instance = new Singleton();
    public static Singleton getInstance() { 
        return instance; 
    }
    
    private Object readResolve() {
        return instance;
    }
    
实现

构造方法私有化

// 1. 饿汉式
private static Singleton instance = new Singleton();
public static Singleton getInstance() { 
    return instance; 
}

// 2.1 懒汉式无锁
private static Singleton instance = null;
public static Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}
// 2.2 懒汉式有锁
public static synchronized Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}

// 3. 双重检测:指令重排可能导致不安全
private static Singleton instance = null;
public static Singleton getInstance() {
    if (instance == null) {
        synchronized(Singleton.class) {
            if (instance == null) {
        		instance = new Singleton();
            }
        }
    }
    return instance;
}
// 3.2 双重检测(2)
private volatile static Singleton instance = null;

// 4. 静态内部类
private static class Inner {
    private static final Singleton INSTANCE = new Singleton;
}
public static Singleton getInstance() {
    return Inner.INSTANCE;
}

// 5. 枚举
public enum Singleton {
    INSTANCE;
}
参考

面试官所认为的单例模式——咖啡拿铁

漫画:什么是单例模式——程序员小灰

更新时间1:2020.05.28

2. 工厂方法模式

简单工厂模式:静态方法模式
定义

提供静态方法,创建其他类实例。通常根据参数不同创建不同的类实例。

角色

抽象产品:AbstractProduct

具体产品:ProductA、ProductB…

工厂类:Factory

意义

创建与使用对象分隔开,用户只需传相应参数即可获取对应对象,实现了解耦。

缺点

违背“开放-关闭”原则。添加新产品则需要修改工厂类的逻辑。

简单工厂使用静态方法,无法形成继承关系的类体系。

实现
class AbstractProduct {
    public void use();
}

class ProductA extends AbstractProduct {
    @Override
    public void use() {
        System.out.println("ProductA use");
    }
}

class ProductB extends AbstractProduct {..}

// 静态工厂
class Factory {
    public static AbstractProduct getProduct(String product) {
        if (product.equals("A")) {
            return new ProductA();
        } else if (product.equals("B")) {
            return new ProductB();
        }
    }
}
// main
AbstractProduct proA = Factory.getProduct("A");
proA.use();
工厂方法模式
定义

产品族和工厂族一一对应,一种具体产品对应一个具体工厂。

如:

汽车产品族:Car(大卡车、小汽车)

汽车工厂族:CarFactory(大卡车工厂、小汽车工厂)

角色

抽象产品:Car

具体产品:BigCar、SmallCar

抽象工厂:CarFactory

具体工厂:BigCarFactory、SmallCarFactory

意义

添加同族产品,只需添加一个产品和工厂实现类,继承各自抽象父类即可,扩展性更好。

缺点

复杂性相对高(需要实现两个类)

实现
class Car {
    void run();
}

class BigCar extends Car {..}
class SmallCar extends Car {..}

// 工厂方法
class CarFactory {
    Car create();
}

class BigCarFactory extends CarFactory {
    @Override
    public Car create() {
        return new BigCar();
    }
}
class SmallCarFactory extends SmallCarFactory {..}
参考

Graphic Design Patterns

更新时间2:2020.05.29


行为模式

1. 策略模式

定义

针对一组算法,封装到具有共同接口的类中,从而根据条件选择不同的实现。

角色

抽象策略类

具体策略类

上下文类

优点

灵活。对于某些具体场景,存在需求变更,新增策略即可,然后客户端选择对应并调用。

缺点

客户端需知道所有的策略类,并决定调用哪个类。

实现
// 抽象策略及实现
class Strategy {
    // 正常价格100元
    BigDecimal price();
}

class NormalStrategy extends Strategy {
    @Override
    public BigDecimal price() {
        System.out.println("正常售价");
        return BigDecimal.valueOf("100");
    }
}

class DiscountStrategy extends Strategy {
    @Override
    public BigDecimal price() {
        System.out.println("八折优惠");
        return BigDecimal.valueOf("80");
    }
}

// 上下文
class Context {
    private Strategy strategy;
    
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    
    public BigDecimal price() {
        return strategy.price();
    }
}

// 或者工厂
class Context {
    private Strategy strategy;
    
    public Context(int strategy) {
        if (strategy == 1) {
            strategy = new NormalStrategy();
        } else if (strategy == 2) {
            strategy = new DiscountStrategy();
        }
    }
    
    public BigDecimal price() {
        return strategy.price();
    }
}
// main
Context context = new Context(1);
BigDecimal price = context.price();
参考

《大话设计模式》

Graphic Degisn Patterns

更新时间3:2020.05.30

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值