Java设计模式----桥接模式(Bridge)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a1610770854/article/details/53469065

1.什么是桥接模式

先来一段教科书般的解释:

在正式介绍桥接模式之前,我先跟大家谈谈两种常见文具的区别,它们是毛笔和蜡笔。假如我们需要大中小3种型号的画笔,能够绘制12种不同的颜色,如果使用蜡笔,需要准备3×12 = 36支,但如果使用毛笔的话,只需要提供3种型号的毛笔,外加12个颜料盒即可,涉及到的对象个数仅为 3 + 12 = 15,远小于36,却能实现与36支蜡笔同样的功能。如果增加一种新型号的画笔,并且也需要具有12种颜色,对应的蜡笔需增加12支,而毛笔只需增加一支。为什么会这样呢?通过分析我们可以得知:在蜡笔中,颜色和型号两个不同的变化维度(即两个不同的变化原因)融合在一起,无论是对颜色进行扩展还是对型号进行扩展都势必会影响另一个维度;但在毛笔中,颜色和型号实现了分离,增加新的颜色或者型号对另一方都没有任何影响。如果使用软件工程中的术语,我们可以认为在蜡笔中颜色和型号之间存在较强的耦合性,而毛笔很好地将二者解耦,使用起来非常灵活,扩展也更为方便。在软件开发中,我们也提供了一种设计模式来处理与画笔类似的具有多变化维度的情况,即本章将要介绍的桥接模式。

讲道理我觉得这个讲的很形象,不过以我个人的看法,我觉的桥接模式实现了至少三条很重要的原则就是“单一职责原则”,“依赖倒置原则”,“开闭原则”。但是其实桥接模式很简单,就像上面所说的那样。

2.桥接模式实现

例子:人拥有独立的变化维度,毛笔类也拥有大小的变化维度,颜色类也拥有颜色的变化维度

AbstractPerson.java
package cn.limbo.design_patterns.bridge.person;

import cn.limbo.design_patterns.bridge.brush.AbstractBrush;

/**
 * 人的抽象类
 * Created by limbo on 2016/12/5.
 */
public abstract class AbstractPerson {

	protected String name; //名字

	//一般将该对象的可见性定义为protected,以便在其子类中访问Implementor的方法
	protected AbstractBrush brush; //所使用的毛笔

	public void setName(String name) {
		this.name = name;
	}

	public void setBrush(AbstractBrush brush) {
		this.brush = brush;
	}

	//具体的业务方法,由子类实现
	public abstract void doWrite();
}

OldPerson.java

package cn.limbo.design_patterns.bridge.person;

/**
 * Created by limbo on 2016/12/5.
 */
public class OldPerson extends AbstractPerson {

	@Override
	public void doWrite() {

		System.out.println("人物名字: " + this.name + this.brush.doWrite());

	}
}

YoungPerson.java
package cn.limbo.design_patterns.bridge.person;

/**
 * Created by limbo on 2016/12/5.
 */
public class YoungPerson extends AbstractPerson {

	@Override
	public void doWrite() {

		System.out.println("人物名字: " + this.name + this.brush.doWrite());

	}
}

AbstractBrush.java
package cn.limbo.design_patterns.bridge.brush;

import cn.limbo.design_patterns.bridge.color.Color;

/**
 * 毛笔的抽象类
 * Created by limbo on 2016/12/5.
 */
public abstract class AbstractBrush {

	protected String size; //毛笔型号
	//一般将该对象的可见性定义为protected,以便在其子类中访问Implementor的方法

	protected Color color; //毛笔可以写出的颜色,一种毛笔只能写出一种颜色

	public void setSize(String size) {
		this.size = size;
	}

	public void setColor(Color color) {
		this.color = color;
	}

	//具体的业务方法,由子类实现
	public abstract String doWrite();

}

LargeBrush.java
package cn.limbo.design_patterns.bridge.brush;

/**
 * Created by limbo on 2016/12/5.
 */
public class LargeBrush extends AbstractBrush {

	@Override
	public String doWrite() {
		setSize("Large Brush");
		return "毛笔大小: " + this.size + this.color.doWrite();
	}

}

Color.java
package cn.limbo.design_patterns.bridge.color;

/**
 * 毛笔颜色的标准
 * Created by limbo on 2016/12/5.
 */
public interface Color {

	public String doWrite();

}

Blue.java
package cn.limbo.design_patterns.bridge.color;

/**
 * Created by limbo on 2016/12/5.
 */
public class Blue implements Color {
	@Override
	public String doWrite() {
		return "书写颜色:蓝色";
	}
}


3.优点与缺点

桥接模式的主要优点如下:

(1)分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,也就是说抽象和实现不再在同一个继承层次结构中,而是“子类化”它们,使它们各自都具有自己的子类,以便任何组合子类,从而获得多维度组合对象。

(2)在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。

(3)桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。

桥接模式的主要缺点如下:

(1)桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。

(2)桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。


4.适用场景

在以下情况下可以考虑使用桥接模式:

(1)如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。

(2)“抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。

(3)一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。

(4)对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。



展开阅读全文

没有更多推荐了,返回首页