桥接模式
1. 使用场景
用继承、聚合等手段让不同的类承担不同的职责。将不同职责的类分为抽象和实现,这样可以让它们分别演化,保证职责最小化,提供更好的灵活性。
2. 实现举例
在一款游戏的开发中,要设计“鸭子”,有的鸭子会叫,有的不会叫,有的会飞,有的不会飞,但是都会游泳,该如何设计?
UML
代码
public class TestDuck {
public static void main(String[] args) {
FlyBehavior FLYABLE = () -> System.out.println("飞呀飞");
FlyBehavior NONE_FLYABLE = () -> System.out.println("飞呀飞,飞不起来");
QuackBehavior QUACKABLE = () -> System.out.println("嘎嘎嘎");
QuackBehavior NONE_QUACKABLE = () -> System.out.println("不能叫");
System.out.println("======== 创建一类能叫,能飞的鸭子 ========");
Duck d1 = new Duck(FLYABLE, QUACKABLE);
d1.fly();
d1.quack();
System.out.println("======== 创建一类能叫,不能飞的鸭子 ========");
Duck d2 = new Duck(NONE_FLYABLE, QUACKABLE);
d2.fly();
d2.quack();
System.out.println("======== 创建一类不能叫,能飞的鸭子 ========");
Duck d3 = new Duck(FLYABLE, NONE_QUACKABLE);
d3.fly();
d3.quack();
System.out.println("======== 创建一类不能叫,不能飞的鸭子 ========");
Duck d4 = new Duck(NONE_FLYABLE, NONE_QUACKABLE);
d4.fly();
d4.quack();
}
}
// 鸭子类
abstract class AbstractDuck {
private FlyBehavior flyBehavior;
private QuackBehavior quackBehavior;
public AbstractDuck(FlyBehavior flyBehavior,
QuackBehavior quackBehavior) {
super();
this.flyBehavior = flyBehavior;
this.quackBehavior = quackBehavior;
}
public abstract void swim();
public void fly() {
flyBehavior.fly();
}
public void quack() {
quackBehavior.quack();
}
}
class Duck extends AbstractDuck{
public Duck(FlyBehavior flyBehavior,
QuackBehavior quackBehavior) {
super(flyBehavior, quackBehavior);
}
@Override
public void swim() {
System.out.println("游啊游");
}
}
// 飞行能力
interface FlyBehavior {
void fly();
}
// 叫唤能力
interface QuackBehavior {
void quack();
}
说明
这道题目是《Head First Design Pattern》一书中的例题,该例题把它归结为策略模式。 但我的理解是:该题目注重的是AbstractDuck,FlyBehavior,QuackBehavior三套抽象的独立演化和聚合,这符合桥接模式的特点,桥接模式偏重的是结构;而策略模式注重的是运行期间可以动态替换不同的算法实现,偏重的是行为。