设计模式-桥接模式
1.概念
桥接模式(Bridge)是把事物和具体的实现分离开来,使得两者可以独立的进行变化;使用的场景是当一个事物有多个维度,而且都可以自由的变化的时候,可以考虑使用桥接模式,降低类之间的耦合度,同时也可以减少类的数量;
2.组成
1>Implementor
定义接口
interface Implementor {
// 实现抽象部分需要的某些具体功能
public void operationImpl();
}
2>Abstraction
定义抽象接口,一般来说,会持有一个接口的引用;
abstract class Abstraction {
// 持有一个 Implementor 对象,形成聚合关系
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
// 可能需要转调实现部分的具体实现
public void operation() {
implementor.operationImpl();
}
}
3>ConcreteImplementor
实现Implementor的接口,一般来说有多个实现类;
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
// 真正的实现
System.out.println("具体实现A");
}
}
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
// 真正的实现
System.out.println("具体实现B");
}
}
4>RefinedAbstraction
用来扩展Abstraction类;
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
public void otherOperation() {
// 实现一定的功能,可能会使用具体实现部分的实现方法,
// 但是本方法更大的可能是使用 Abstraction 中定义的方法,
// 通过组合使用 Abstraction 中定义的方法来完成更多的功能。
}
}
测试代码
public class BridgePattern {
public static void main(String[] args) {
Implementor implementor = new ConcreteImplementorA();
RefinedAbstraction abstraction = new RefinedAbstraction(implementor);
abstraction.operation();
abstraction.otherOperation();
}
}
3.例子
场景:假设现在有一个电脑销售的功能模块,电脑分成品牌和类型两个维度,品牌比如宏基,苹果,联想等,类型有台式机,笔记本,平板电脑等类型;那么如何设计?按照传统的方式,我们可能会考虑使用继承;结果如下所示
先是抽象出电脑销售的接口,然后电脑又有台式机,笔记本,pad;台式机下面又有宏基台式机,苹果台式机,Dell台式机...
如果现在又有一种品牌的电脑,又要增加三个类,这里还只是三种类型,如果是10种哪?这样会导致类数量剧增,类爆炸;
传统的通过继承的方式已经无法满足要求了;那这里可以考虑使用桥接模式;解决方案:将两个维度,品牌和类型分离,使他们可以独立的变化;对应的类关系如图所示
具体的代码实现
1>Implementor
这里提供sales方法
public interface ImplementorBrand {
void sales();
}
2>Abstraction
这里是抽象的computer类,会持有一个ImplementorBrand 的引用;
public class AbstractionComputer {
protected ImplementorBrand brand;
public AbstractionComputer(ImplementorBrand brand) {
this.brand = brand;
}
public void sales() {
brand.sales();
}
}
3>ConcreteImplementor
这里是具体品牌的实现
public class ConcreteImplementorAcer implements ImplementorBrand {
@Override
public void sales() {
System.out.println("宏碁品牌");
}
}
public class ConcreteImplementorApple implements ImplementorBrand {
@Override
public void sales() {
System.out.println("苹果品牌");
}
}
public class ConcreteImplementorDell implements ImplementorBrand {
@Override
public void sales() {
System.out.println("戴尔品牌");
}
}
4>RefinedAbstraction
这里是不同的电脑类型,继承AbstractionComputer 类
public class RefinedAbstractionDesktop extends AbstractionComputer {
public RefinedAbstractionDesktop(ImplementorBrand brand) {
super(brand);
}
@Override
public void sales() {
play();
super.sales();
}
public void play() {
System.out.println("我台式机抗摔打");
}
}
public class RefinedAbstractionLaptop extends AbstractionComputer {
public RefinedAbstractionLaptop(ImplementorBrand brand) {
super(brand);
}
@Override
public void sales() {
lighting();
super.sales();
}
public void lighting(){
System.out.println("我笔记本电脑充电5分钟,续航5小时");
}
}
public class RefinedAbstractionPad extends AbstractionComputer {
public RefinedAbstractionPad(ImplementorBrand brand) {
super(brand);
}
@Override
public void sales() {
weighting();
super.sales();
}
public void weighting() {
System.out.println("我平板电脑便于携带");
}
public static void main(String[] args) {
ImplementorBrand brand = new ConcreteImplementorApple();
//机器类型纬度
AbstractionComputer computer = new RefinedAbstractionLaptop(brand);
computer.sales();
}
}
这样的话,如果以后要增加其他品牌的电脑,只需要增加一个类即可;JDBC的连接中也有用到bridge模式;