设计模式:桥接模式
一、定义
将抽象部分与实现部分分离,使它们都可以独立的进行变化。
二、角色
- Abstraction:抽象部分,该类保持一个对实现部分对象的引用,抽象部分中的方法需要调用实现部分的对象来实现,该类一般为抽象类;
- RefinedAbstraction:优化的抽象部分,抽象部分的具体实现,该类一般是对抽象部分的方法进行完善和扩展;
- Implementor:实现部分,可以为接口或抽象类,其方法不一定要与抽象部分中的一致,一般情况下是由实现部分提供基本的操作,而抽象部分定义的则是基于实现部分这些基本操作的业务方法;
- ConcreteImplementorA、ConcreteImplemetorB:实现部分的具体实现,完善实现部分中方法定义的具体逻辑;
三、使用场景
- 如果一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,可以通过桥接模式使它们在抽象层建立一个关联关系;
- 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,也可以考虑使用桥接模式;
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展;
四、模板代码
//抽象化代码
abstract class Abstraction {protected Implementor impl;public Abstraction(Implementor impl) {this.impl = impl;}public void operation() {impl.operationImpl();}
}//修正抽象化代码
class RefinedAbstraction extends Abstraction {public RefinedAbstraction(Implementor impl) {super(impl);}//其他的操作方法public void otherOperation() {}
}//实现化代码
abstract class Implementor {/* 示例方法,实现抽象部分需要的某些具体功能*/abstract void operationImpl();
}//具体实例化代码
class ConcreteImplementorA extends Implementor {@Overridepublic void operationImpl() {//具体操作}}//具体实例化代码public class ConcreteImplementorB extends Implementor {@Overridepublic void operationImpl() {//具体操作}}
}
五、案例代码
1.给圆、正方形和长方形添加白色或黑色
实现出添加颜色,所以称之为实现部分,这里可以用接口,也可以用抽象类
public interface Color {public void coloring();
}public class White implements Color {private static final String TAG = White.class.getSimpleName();@Overridepublic void coloring() {Log.d(TAG,"模拟正在涂上白色...");}
}public class Black implements Color {private static final String TAG = Black.class.getSimpleName();@Overridepublic void coloring() {Log.d(TAG,"模拟正在涂上黑色...");}
}
既可以画白色也可以画黑色。
不要和安卓原生的Color类混淆。
这里主要是对白色或黑色进行一个抽象,假如你把它想成颜料,它们是具体的一个类。
如果二者写在一起,也等于多写了一个类来包含黑色和白色这两个类。
2.抽象出具体的事物:图形,并秒回具体的图形。此部分一般使用抽象类。
public abstract class Shape {protected Color color;public Shape(Color color) {this.color = color;}public abstract void draw();
}
//正方形
public class Square extends Shape {private static final String TAG = Square.class.getSimpleName();public Square(Color color) {super(color);}@Overridepublic void draw() {Log.d(TAG,"模拟正在画正方形...");color.coloring();}
}//长方形
public class Rectangle extends Shape {private static final String TAG = Rectangle.class.getSimpleName();public Rectangle(Color color) {super(color);}@Overridepublic void draw() {Log.d(TAG,"模拟正在画长方形...");color.coloring();}
}//圆形
public class Circular extends Shape {private static final String TAG = Circular.class.getSimpleName();public Circular(Color color) {super(color);}@Overridepublic void draw() {Log.d(TAG,"模拟正在画圆形...");color.coloring();}
}
3.调用
White white = new White();
Black black = new Black();Square square = new Square(white);
Rectangle rectangle = new Rectangle(black);
Circular circular = new Circular(white);square.draw();
rectangle.draw();
circular.draw();
总结
1、抽象和实现部分的区分
实现部分主要是对抽象化的事物进一步的具体化。这里就是对抽象化的图形进一步添加颜色。
2、桥接模式结构核心
抽象部分拥有实现部分实例,并调用实现部分实例的方法。
由以上构成桥接模式。
3、减少类的个数利于扩展,并且解耦。
首先有正方形、长方形和圆形,你还可以添加更多的图形。颜色也可以添加更多的颜色。我们把图形看成一个维度,颜色看成一个维度。如果不用桥接模式,你可能像下面这样写。你不单要为白色添加一个类,还得为黑色添加一个类。如果有更多的颜色。将成倍增长。桥接模式就分离这两个维度,使这两个维度独立。达到减少类的个数和解耦的作用。
六、在Android中的使用
对于一个View来说,它有两个维度的变化,一个是它的描述比如Button、TextView等等他们是View的描述维度上的变化,另一个维度就是将View真正绘制到屏幕上,这跟Display、HardwareLayer和Canvas有关。
七、优缺点
优点:
- 分离成抽象部分和实现部分,并且两部分都可以独立的拓展,一个部分变化不会引起另一部分的变化,提高了系统的拓展性。
- 复用性强,避免了使用继承产生大量继承类的问题。
缺点:
- 将系统分离为抽象部分和实现部分,会增加系统的复杂度和设计难度。如果系统不能分离出两个独立的维度的话,就不适合使用这个模式。