DP 设计模式

策略模式

class MallardDuck extends Duck {
public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
}

class ModelDuck extends Duck {
public ModelDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyNoWay(); // 组合不同的方法
}
}

class Main {
public static void main(String[] args) {
Duck real = new MallardDuck();
Duck model = new ModelDuck();

real.fly();
model.fly(); // 调用同样的接口
}
}

识别应用中变化的方面,把它们和不变的方面分开。

针对接口编程,而不是针对实现编程。

// Implement
Dog d = new Dog();
d.bark();

// Interface
Animal dog = new Dog();
dog.makeSound(); // abstract

优先使用组合而不是继承。

summary

策略模式定义了算法族并分别封装。策略让算法变化独立于使用它的客户。

观察者模式

不要打给我,我会打给你!

尽量做到交互的对象之间的松耦合设计。

summary

观察者模式定义对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

装饰者模式

class Expresso extends Beverage {
@Override
public double cost() {
return 1.99;
}
}

class Milk {
Beverage beverage;
@Override
public int cost() {
// Decorator
return cost + beverage.cost();
}
}

类应该对拓展开放,对修改关闭。

summary

装饰者模式动态地将额外责任附加到对象上。对于拓展功能,装饰着提供子类化之外的弹性替代方案。

工厂模式

依赖抽象,不依赖具体类。

三条原则帮助你遵循依赖倒置:

  1. 变量不应该持有到具体类的引用。
  2. 类不应该派生自具体类。
  3. 方法不覆盖基类已实现的方法。

[!Warning]
注意:完全实现上面三条原则是不可能的。尽量遵循即可。

summary

抽象工厂模式提供一个接口来创建相关或依赖对象的家族,而不需要指定具体类。

工厂模式定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法让类把实例化推迟到子类。

单件模式

public MyClass {
// 私有的构造方法
private MyClass {}

// 静态的getter
public static MyClass getInstance() {
if (uniqueClass == null) {
uniqueClass = new MyClass();
}
return uniqueClass;
}
}

summary

单件模式确保一个类只有一个实例,并提供一个全局访问点。

命令模式

class SomeControl {
public void setCommand(Command command) {
slot = command;
}
public void bottonWasPressed() {
slot.execute();
}
}

class SomeCommand {
public void execute() {
on();
}
// execute和undo互为镜像
public void undo() {
off();
}
}

summary

命令模式把请求封装为对象,以便用不同的请求、队列或日志请求,来参数化其他对象,并支持可撤销的操作。

适配器模式

适配器改变接口以符合客户的期望。

summary

适配器模式,将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作。

外观模式

外观模式将客户从一个复杂子系统解耦。

summary

外观模式,为子系统中的一组接口提供了一个统一的接口。外观定义了一个更高级别的接口,使得子系统更容易使用。