应用
- 桥接模式(Bridge)来做(多维度变化)
效果及实现要点:
- Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
- 所谓抽象和实现沿着各自维度的变化,即“子类化”它们,得到各个子类之后,便可以任意它们,从而获得不同路上的不同汽车。
- Bridge模式有时候类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
- Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。
适用性:
在以下的情况下应当使用桥梁模式:
1. 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
2. 设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
3. 一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。
4. 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
总结:
Bridge模式是一个非常有用的模式,也非常复杂,它很好的符合了开放-封闭原则和优先使用对象,而不是继承这两个面向对象原则。
实例
- 电脑名字
public interface Brand {
void name();
}
public class Dell implements Brand {
@Override
public void name() {
System.out.println("戴尔电脑");
}
}
public class Lenovo implements Brand {
@Override
public void name() {
System.out.println("联想电脑");
}
}
- 电脑类型,讲电脑名字传入
public abstract class Computer {
private Brand brand ;
public Computer(Brand brand) {
this.brand = brand;
}
public void sale(){
brand.name();
}
}
public class Desktop extends Computer {
public Desktop(Brand brand) {
super(brand);
}
@Override
public void sale() {
super.sale();
System.out.println("台式电脑");
}
}
public class Laptop extends Computer {
public Laptop(Brand brand) {
super(brand);
}
@Override
public void sale() {
super.sale();
System.out.println("笔记本电脑");
}
}
- 销售者的名字:讲电脑类型传入进来
public abstract class Name {
private Computer computer;
public Name(Computer computer) {
this.computer = computer;
}
public void callName(){
computer.sale();
}
}
public class ShiName extends Name {
public ShiName(Computer computer) {
super(computer);
}
@Override
public void callName() {
super.callName();
System.out.println("我是配送人员:小强");
}
}
public class CaiName extends Name {
public CaiName(Computer computer) {
super(computer);
}
@Override
public void callName() {
super.callName();
System.out.println("我是配送人员:梦梦");
}
}
- 调用
Brand ln = new Lenovo();
Desktop desktop = new Desktop(ln);
ShiName shi = new ShiName(desktop);
shi.callName();
CaiName cai = new CaiName(desktop);
cai.callName();