桥接模式
2016-02-01 09:20
253 查看
思考一个这样的场景,如果你是一个会变通的卖肉夹馍的商人,你觉得只卖传统的一种没有什么新意。所以你提供的馍有白吉馍、面包片、馒头片等多种类型,同时肉也分为牛肉、驴肉、猪肉等。一经上市,果然大受欢迎,卖得非常好。这时,你又开始在馍和肉上继续寻找新的原料来增加你的种类。那么问题来了,如果每天开卖之前,你都对每种馍和肉的组合(就目前种类来说就有3*3=9种)都做出 一定数量,不仅麻烦,而且不够灵活。每增加一种原料就要多做出很多种产品来,并随着扩展越来越多。所以你决定让员工准备好每种材料,每天边卖便根据顾客的需求动态的将原料组合起来。
在上面的故事中,就隐含了桥接模式的思想。将这个故事中的案例抽象总结后,核心的问题就是多个变化维度的问题:馍和肉。上例中,馍和肉分别是不同的原料,都可能随时进行扩展,所以都是变化因子。在最开始的售卖方法中,将两种变化因子杂糅在一起,使得扩展变得麻烦,每一次扩展都要成倍数的增加工作量。改进之后,将原料之间解耦,只在“肉夹馍”这个概念模型中,两者有一个抽象的关系:馍包着肉组成最终产品。
下面是前后结构对比:
![](https://img-blog.csdn.net/20160201091939311?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20160201091946562?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
其中肉夹馍是个抽象类,它包含了一个肉接口类型的成员。这样,具体的肉实现“肉接口”,具体的馍继承肉夹馍抽象类。两个维度的变化被分隔开,可以各自对对方几乎无干扰的扩展。仅在抽象类中将其桥接起来。最终,两者动态的耦合,形成各种各样的产品。
下面以一个笔的例子,用最简单的代码实现桥接模式:
输出结果:
writing with big pen
color is blue
writing with big pen
color is red
总结:
优点:
将变化维度分离解耦,使各维度的变化和扩展隔离开来。
对比多层继承的方式,符合单一职责原则;扩展简单,符合开闭原则。
动态耦合,减少子类个数。
缺点:
增加系统设计和理解难度
需要一定经验识别出系统中的独立变化维度。
适用场景:
系统中存在多个独立变化维度,切均有扩展/变化的可能,不希望有过多的子类。
在上面的故事中,就隐含了桥接模式的思想。将这个故事中的案例抽象总结后,核心的问题就是多个变化维度的问题:馍和肉。上例中,馍和肉分别是不同的原料,都可能随时进行扩展,所以都是变化因子。在最开始的售卖方法中,将两种变化因子杂糅在一起,使得扩展变得麻烦,每一次扩展都要成倍数的增加工作量。改进之后,将原料之间解耦,只在“肉夹馍”这个概念模型中,两者有一个抽象的关系:馍包着肉组成最终产品。
下面是前后结构对比:
其中肉夹馍是个抽象类,它包含了一个肉接口类型的成员。这样,具体的肉实现“肉接口”,具体的馍继承肉夹馍抽象类。两个维度的变化被分隔开,可以各自对对方几乎无干扰的扩展。仅在抽象类中将其桥接起来。最终,两者动态的耦合,形成各种各样的产品。
下面以一个笔的例子,用最简单的代码实现桥接模式:
public abstract class Pen { protected Color color; public abstract void write(); } public interface Color { public void paintColer(); } public class BigPen extends Pen { @Override public void write() { System.out.println("writing with big pen"); color.paintColer(); } } public class SmallPen extends Pen { @Override public void write() { System.out.println("Writing with small pen"); color.paintColer(); } } public class ColorBlue implements Color { @Override public void paintColer() { System.out.println("color is blue"); } } public class ColorRed implements Color { @Override public void paintColer() { System.out.println("color is red"); } } public class Test { public static void main(String[] args) { BigPen bigPen = new BigPen(); ColorBlue colorBlue = new ColorBlue(); bigPen.color = colorBlue; bigPen.write(); bigPen.color = new ColorRed(); bigPen.write(); } }
输出结果:
writing with big pen
color is blue
writing with big pen
color is red
总结:
优点:
将变化维度分离解耦,使各维度的变化和扩展隔离开来。
对比多层继承的方式,符合单一职责原则;扩展简单,符合开闭原则。
动态耦合,减少子类个数。
缺点:
增加系统设计和理解难度
需要一定经验识别出系统中的独立变化维度。
适用场景:
系统中存在多个独立变化维度,切均有扩展/变化的可能,不希望有过多的子类。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- PHP设计模式之装饰者模式代码实例
- php设计模式之单例模式实例分析
- 介绍php设计模式中的工厂模式
- PHP设计模式之适配器模式代码实例
- 深入浅出23种设计模式
- 浅谈c#设计模式之单一原则
- C#设计模式之观察者模式实例讲解
- C#设计模式之单例模式实例讲解
- 学习JavaScript设计模式(接口)
- 深入理解JavaScript系列(28):设计模式之工厂模式详解
- 面向对象设计模式的核心法则
- JavaScript设计模式之单件模式介绍
- 学习JavaScript设计模式之观察者模式