设计模式
文章目录
创建型模式
1. 单例模式
定义
提供创建对象的方式,确保只有一个对象被创建。
意义
节约资源。
缺点
引入了线程安全问题。
设计
- 线程安全
- 延迟加载
- 代码安全:防止序列化、反射攻击
- 性能
实现方法对比
实现 | 线程安全 | 延迟加载 | 性能 | 序列化/反射 |
---|---|---|---|---|
饿汉式 | Y | Y | ||
懒汉式:无锁 | Y | Y | ||
懒汉式:有锁 | Y | Y | ||
双重检查 | Y | Y | Y | |
静态内部类 | Y | Y | Y | |
枚举 | Y | Y | Y |
扩展
-
双重检测的指令重排问题:volatile。避免指令重排
-
非枚举实现的序列化问题:实现 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 {..}
参考
更新时间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();
参考
《大话设计模式》
更新时间3:2020.05.30