桥接模式
桥接模式定义:在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。而具体使用的方式,则是将抽象部分与他们的实现部分分离,使得它们都可以独立的变化。
以电脑为例,假定电脑由三个部分组成:cpu、主板和显卡,cpu品牌有intel、ibm,主板品牌有华硕、七彩虹,显卡有AMD、NVIDIA,这时我们组装电脑,总共可以组装 2*2*2种电脑,那么按照传统的做法,我们要建8个类才能满足要求,并且如果此时cpu又新添加了一个品牌ITD,那么我们又需要添加2*2个类,这种系统的扩展就很差,类也显得比较多。如果采用桥接模式,我们可以将cpu、主板和显卡看做电脑的三个维度,抽象为三个接口,然后有一个组装电脑的抽象类持有三个接口的实例,并提供一个方法供子类实现去完成组装工作。
类图如下:
桥接模式主要包含如下几个角色:
Abstraction:抽象类。
RefinedAbstraction:扩充抽象类。
Implementor:实现类接口,可以有多个
ConcreteImplementor:具体实现类,可以有多个
java版demo如下:
package bridge; public interface CPU { String make(); }
package bridge; public class Intel implements CPU { @Override public String make() { return "intel"; } }
package bridge; public class IBM implements CPU { @Override public String make() { return "IBM"; } }
package bridge; public interface ZHUBAN { String make(); }
package bridge; public class HUASHUO implements ZHUBAN { @Override public String make() { return "华硕"; } }
package bridge; public class QICAIHONG implements ZHUBAN { @Override public String make() { return "七彩虹"; } }
package bridge; public interface XIANKA { String make(); }
package bridge; public class AMD implements XIANKA { @Override public String make() { return "AMD"; } }
package bridge; public class NVIDIA implements XIANKA { @Override public String make() { return "NVIDIA"; } }
package bridge; public abstract class Bridge { CPU cpu; XIANKA xianka; ZHUBAN zhuban; public CPU getCpu() { return cpu; } public void setCpu(CPU cpu) { this.cpu = cpu; } public XIANKA getXianka() { return xianka; } public void setXianka(XIANKA xianka) { this.xianka = xianka; } public ZHUBAN getZhuban() { return zhuban; } public void setZhuban(ZHUBAN zhuban) { this.zhuban = zhuban; } abstract void assemble (CPU cpu,XIANKA xianka,ZHUBAN zhuban); }
package bridge; public class RedifedBridge extends Bridge { @Override void assemble(CPU cpu, XIANKA xianka, ZHUBAN zhuban) { super.cpu = cpu; super.xianka = xianka; super.zhuban = zhuban; } public void showConfig() { System.out.println("cpu:" + cpu.make() + ",xianka:" + xianka.make() + ",zhuban:" + zhuban.make()); } }
测试代码及结果:
桥接模式的使用场景:
1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3、一个类存在两个及以上的独立变化的维度,且这这些维度都需要进行扩展。
桥接模式的难点在于识别出系统中独立变化的多个纬度,这方面需要一定的技术积累才能做到。另外在使用桥接模式的时候,系统复杂度一定程度上会增加。