桥接模式
将类功能的层次结构和实现结构分离开
实现层次结构:在模板方法模式中,我们通过重写父类的方法来达到实现自己的功能的目的。这里使用的继承只是子类为了在父类的接口下实现自己的方法。
功能层次结构:继承一个类,写一个新的方法。这里使用继承是为了给父类添加新的方法,但是又能继续用父类的方法。
桥接模式可以将实现层次结构和功能层次结构分离开。将这两种继承显示出来。
例子
我们用桥接模式实现这样一个功能。现在有一个显示类(Display),它可以显示一个字符串。
现在我们希望添加两个功能,一个是能显示的时候添加一个包围盒,另一个是能输出5次。
首先,显示的时候添加包围盒,就是怎么显示的问题。这个可以通过派生父类并重写父类的模板函数来实现。
其次,输出5次是新的功能,这个可以通过派生父类,并新增加一个方法来实现。
但是这样实现会导致功能层次和实现层次的继承混乱。
所以我们这里单独把两个抽出来,功能层次的继承,当作类的继承。而实现层次的继承,放到一个xxxImpl类中,并通过继承这个类来实现子类需要的实现方法。
// 这是个显示的基类,里面保存了一个DisplayImpl来指代不同的显示方法实现
public class Display {
private DisplayImpl impl;
public Display(DisplayImpl impl) {
this.impl = impl;
}
public void open() {
impl.rawOpen();
}
public void print() {
impl.rawPrint();
}
public void close() {
impl.rawClose();
}
public final void display() {
open();
print();
close();
}
}
// 这是实现显示的方法
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
// 这个继承是子类实现了自己的方法
public class StringDisplayImpl extends DisplayImpl{
private String string;
private int width;
public StringDisplayImpl(String string) {
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void rawOpen() {
printLine();
}
@Override
public void rawPrint() {
System.out.println("|" + string + "|");
}
@Override
public void rawClose() {
printLine();
}
private void printLine() {
System.out.print("+");
for (int i = 0; i < width;i ++) {
System.out.print("-");
}
System.out.println("+");
}
}
// 这个继承是为了给display添加新功能
public class CountDisplay extends Display{
public CountDisplay(DisplayImpl impl) {
super(impl);
}
public void multiDisplay(int times) {
open();
for (int i = 0; i < times; i++) {
print();
}
close();
}
}
注意
- 为什么要分开呢?更容易扩展。
- 继承是强关联,委托是弱关联
相关设计模式
- 模板方法模式
- 抽象工厂模式
- 适配器模式
策略模式
为了解决问题,程序会编写算法。使用策略模式可以很容易的去替换这些算法。
例子
用策略模式模拟一下猜拳
现在有两种出拳算法
- 如果上一把赢了,下一把用同样手势(Winning Strategy)
- 根据上一局的手势,从概率上计算下一句的手势(Prob Strategy)
代码太复杂了。。就不贴了,以后再说
策略模式比较简单,就是把一些解决问题的算法抽象成一个Strategy的派生类。然后在运行过程中就可以替换这些算法了。
其实去调用不同的函数也是可以的。
相关设计模式
- 享元模式,不重要
- 抽象工厂模式
- 状态模式