1.定义
将抽象和实现解耦,使得两者可以独立地变化
2.例子
定义看不明白?没关系,我将通过下面这个例子来阐述桥梁的概念。
小时候我们都用蜡笔画画,一盒蜡笔12种颜色。一开始我都是用最小号的蜡笔画个太阳公公、月亮婆婆足够了。后来开始画一些抽象派的作品,就得换中号的了,要不然画个背景都要描半天,好一盒中号的也是12种颜色。再后来我开始转向豪放派,中号就有些捉襟见肘了,只好换大号的了,好一盒大号的也只有12种颜色。你看,像我这样不太出名的画家就需要36种画笔,哇,太麻烦了。但是据我观察,另一些比我出名的画家倒是没有这么多笔,他们只有几把刷子和一些颜料,这样就解决了蜡笔的“种类爆炸”问题。”
==========================================================
呵呵,您是不是已经看出来了,不错,我今天要说的就是Bridge模式。为了一幅画,我们需要准备36支型号不同的蜡笔,而改用毛笔三支就够了,当然还要搭配上12种颜料。通过Bridge模式,我们把乘法运算3×12=36改为了加法运算3+12=15,这一改进可不小。那么我们这里蜡笔和毛笔到底有什么区别呢?
实际上,蜡笔和毛笔的关键一个区别就在于笔和颜色是否能够分离。【GOF95】桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。关键就在于能否脱耦。蜡笔的颜色和蜡笔本身是分不开的,所以就造成必须使用36支色彩、大小各异的蜡笔来绘制图画。而毛笔与颜料能够很好的脱耦,各自独立变化,便简化了操作。在这里,抽象层面的概念是:"毛笔用颜料作画",而在实现时,毛笔有大中小三号,颜料有红绿蓝等12种,于是便可出现3×12种组合。每个参与者(毛笔与颜料)都可以在自己的自由度上随意转换。
蜡笔由于无法将笔与颜色分离,造成笔与颜色两个自由度无法单独变化,使得只有创建36种对象才能完成任务。Bridge模式将继承关系转换为组合关系,从而降低了系统间的耦合,减少了代码编写量。
桥梁模式是一种非常简单的模式,它只是使用了类间的聚合关系、继承、重写等常用功能,但是它却提供了一个非常清晰、稳定的架构。
下面还有个小例子:
====================================================
3.桥梁模式的使用场景
4.桥梁模式的四个角色
下面是它们的类图:
5.桥梁模式的通用代码
package _23BridgePattern; /** * 实现化角色 * (颜料) */ public interface Implementor { // 基本方法 // 画图 public void paint(); // 提名 public void title(); }
package _23BridgePattern; /** * 具体实现化角色 * (假装红颜料) */ public class ConcreteImplementor1 implements Implementor { @Override public void paint() { System.out.println("使用红色颜料画画"); } @Override public void title() { System.out.println("使用红色颜料提名"); } }
package _23BridgePattern; /** * 具体实现化角色 * (假装蓝颜料) */ public class ConcreteImplementor2 implements Implementor { @Override public void paint() { System.out.println("使用蓝色颜料画画"); } @Override public void title() { System.out.println("使用蓝色颜料提名"); } }
package _23BridgePattern; /** * 抽象化角色 * (假装毛笔) */ public abstract class Abstraction { // 定义对实现化角色的引用 private Implementor implementor; // 约束子类必须实现该构造函数 public Abstraction(Implementor implementor) { this.implementor = implementor; } // 自身的行为和属性 public void paint() { this.implementor.paint(); } public Implementor getImplementor() { return implementor; } }
package _23BridgePattern; /** * 具体抽象化角色 * (假装小号毛笔) * */ public class RefinedAbstraction extends Abstraction { public RefinedAbstraction(Implementor implementor) { super(implementor); } // 修正父类的行为 @Override public void paint() { super.paint(); super.getImplementor().title(); } }
package _23BridgePattern; /** * 场景类 */ public class Client { public static void main(String[] args) { // 定义一个实现化角色(颜料) // 还可以定义别的颜色 Implementor implementor = new ConcreteImplementor1(); // 定义一个抽象化角色(毛笔) // 还可以定义别的大小的毛笔 Abstraction abstraction = new RefinedAbstraction(implementor); // 执行(画画),这样你画画就不需要36支笔了,只需要三支笔,12种颜料就行了 abstraction.paint(); } }
6.桥梁模式的优点
7.桥梁模式的注意事项