桥接模式
Bridge Pattern:桥接模式,是GoF23种设计模式中属于结构型模式的一种。
桥接模式通过在抽象和具体实现之间创建桥接的结构用以实现两者的解耦合。抽象部分和实现部分是完全分离的,两者都可以独自变化而不影响对方。
桥接模式的关注点在于抽象和实现两者之间的关系,并不是传统上所体现的抽象类和他的派生类这样的的关系(或者说是父类和子类这样的关系,而是说是一种抽象类具体的表达形式),也就是说 实现 指的就是抽象类和派生类用来实现自己的对象,再换句话说就是 实现的方法方式或者角度有多种,每一种都有自己的变化,而我们就是需要将这种多角度多方式分离出来,让它们独立变化,达到减少它们之间耦合的目的。
举个例子说,对于同一个形状。比如说是圆,对其进行分类的话,我们可以通过半径的大小分类,同时我们也可以按照颜色分类,或者按照圆的边缘不同线(点线啊,实线啊,虚线啊等等)分类。
这个例子中,形状就是抽象,圆就是派生类。4CM的圆或者红色的圆,或者虚线绘制的圆就是具体的实现方式,抽象和实现两者都可以独立更改,两者是解耦合的。
结构
结合类图分析,桥接模式分割明确,总共有两大阵营:
- 作为抽象化角色和实际对象(也叫做修正抽象化角色)组成的抽象阵营。
- 抽象化角色:给出的抽象化定义,同时保存一个对实现化角色对象的引用。
- 实际对象(修正抽象化角色):扩展了抽象角色的实际对象,改变抽象化角色对于抽象化的定义。
- 作为实现化角色和具体实现化角色组成的实现阵营。
- 实现化角色:只给出实现化的接口。
- 具体实现角色:给出实现化角色接口的具体实现。
有点不好理解,额~~~
对于桥接模式来说解决的是一个多角度的问题,多方向的问题,多维度的问题,让它们独立出来,考虑的时候只考虑某一个维度/角度/方向,最后才组合在一起形成最后的具体所需要的对象。
举例
-
常用的例子是绘制图形。比如说想要绘制一个正方形,三角形,圆,那么我们应该有三个对应的解决方案。但是很快新的需求来了,我们需要加颜色,红色,白色,黑色。
也就是这个时候,对于同一个抽象的形状他是有两个维度的变化的,一是具体的形状,二是具体的颜色。
那么如果我们可以将这两个维度分开考虑,最后组合在一起,这样是不是复杂的下降了呢?
这也就是桥接模式的作用,可以让我们不需要定义红色的正方形,红色的三角形,红色的圆或者白色的正方形,白色的三角形,白色的圆这种复杂的形式。而是,直接,正方形,红色,之后组合成为红色的正方形,这样是不是变得简单了些?
注意
- 桥接模式适用与描绘多维度变化的系统,通过该模式和面向对象技术来使得系统能够轻松的沿着多个方向进行变化但是又不增加额外的复杂度。
- 桥接模式使用的要求较高,会怎加理解和设计的难度。
- 抽象和实现的分离使得代码低耦合,同时扩展能力也很优秀。
一个小DEMO
-
场景
就以举例中的小例子为例
-
实现化角色
/** * 桥接模式 —— 实现化角色 * @author wq */ public interface Implementor { void doSomething(); }
-
维度一:颜色
/** * 桥接模式 —— 具体实现化角色 * @author wq */ public class Red implements Implementor{ @Override public void doSomething() { System.out.println("红色"); } } //---------------------------------------------------- /** * 桥接模式 —— 具体实现化角色 * @author wq */ public class Blue implements Implementor{ @Override public void doSomething() { System.out.println("蓝色"); } }
-
抽象化角色
/** * 桥接模式 —— 抽象化角色 * @author wq */ public abstract class Abstraction { // 保存着一个实现化角色的对象 这是组合/聚合原则的使用 protected Implementor implementor; public Abstraction(Implementor implementor) { this.implementor = implementor; } public abstract void doSomething(); }
-
维度二:形状
/** * 桥接模式 —— 修正抽象化角色 * @author wq */ public class Circle extends Abstraction{ public Circle(Implementor implementor) { super(implementor); } @Override public void doSomething() { System.out.println("修正抽象化角色 ---- 我是一个圆"); System.out.print("实现化角色 ---- "); implementor.doSomething(); } } //------------------------------------------------------------- /** * 桥接模式 —— 修正抽象化角色 * @author wq */ public class Triangle extends Abstraction{ public Triangle(Implementor implementor) { super(implementor); } @Override public void doSomething() { System.out.println("修正抽象化角色 ---- 我是一个三角形"); System.out.print("实现化角色 ---- "); implementor.doSomething(); } }
-
测试类
/** * 桥接模式 —— 测试类 * @author wq */ public class Main { public static void main(String[] args) { Abstraction circle = new Circle(new Red()); Abstraction triangle = new Triangle(new Blue()); circle.doSomething(); System.out.println("------------------------------"); triangle.doSomething(); } }
-
测试走一波
修正抽象化角色 ---- 我是一个圆 实现化角色 ---- 红色 ------------------------------ 修正抽象化角色 ---- 我是一个三角形 实现化角色 ---- 蓝色
完成!!!