目录
一、什么是桥梁模式
桥梁模式也叫做桥接模式(Bridge Pattern),是一个比较简单的模式。其定义如下:将抽象与实现解耦,使得两者可以独立的变化
二、示例程序
1、Display
package com.as.module.bridge;
/**
* 展示类
* @author Andy
* @date 2021/5/9 21:33
*/
public class Display {
private DisplayImpl impl;
public Display(DisplayImpl impl) {
this.impl = impl;
}
public void open(){
impl.rawOpen();
}
public void print(){
impl.rawPrint();
}
public void close(){
impl.rawClose();
}
public final void display(){
open();
print();
close();
}
}
2、CountDisplay
package com.as.module.bridge;
/**
* 显示规定次数的展示类
* @author Andy
* @date 2021/5/9 21:38
*/
public class CountDisplay extends Display{
public CountDisplay(DisplayImpl impl) {
super(impl);
}
public void multiDisplay(int times){
open();
for(int i=0;i<times;i++){
print();
}
close();
}
}
3、DisplayImpl
package com.as.module.bridge;
/**
* 展示抽象类
* @author Andy
* @date 2021/5/9 21:34
*/
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
4、StringDisplayImpl
package com.as.module.bridge;
/**
* 字符串展示实现类
* @author Andy
* @date 2021/5/9 21:40
*/
public class StringDisplayImpl extends DisplayImpl{
//要显示的字符串
private String string;
//以字节单位计算出的字符串的宽度
private int width;
public StringDisplayImpl(String string) {
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void rawOpen() {
printLine();
}
@Override
public void rawPrint() {
System.out.println("|"+string+"|");
}
@Override
public void rawClose() {
printLine();
}
private void printLine(){
System.out.print("+");
for(int i=0;i<width;i++){
System.out.print("-");
}
System.out.println("+");
}
}
5、TestMain
package com.as.module.bridge;
/**
* 桥梁模式测试类
* @author Andy
* @date 2021/5/9 21:44
*/
public class TestMain {
public static void main(String[] args) {
Display d1 = new Display(new StringDisplayImpl("Hello,China"));
Display d2 = new CountDisplay(new StringDisplayImpl("Hello,World"));
CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello,Universe"));
d1.display();
d2.display();
d3.display();
d3.multiDisplay(6);
}
}
6、运行结果
三、UML
在Bridge模式中有以下登场角色。
1、Abstraction(抽象化)
该角色位于类的功能层次最上层。它使用Implementor角色的方法定义 了基本的功能。该角色中保存了Implementor角色的实例。在示例程序中,由display扮演了此角色。
2、RefinedAbstraction(改善后的抽象化)
在Abstraction角色的基础上增加了新功能的角色,在示例程序中,由CountDisplay扮演此角色
3、Implementor(实现者)
该角色位于"类的实现层次结构"最上层。它定义了用于实现Abstraction角色的接口的方法。在示例程序中,由DisplayImpl扮演此角色。
4、ConcreteImplementor(具体实现者)
该角色负责实现在Implementor中定义的接口。在示例程序中,由StringDisplayImpl扮演此角色。下图 中,左侧的两个类构成了"类的功能层次结构",右侧的两个类构成了"类的实现层次结构"。类的两个类层次之间的桥梁是impl字段
四、拓展思路与注意事项
1、分开后更容易扩展
Bridge模式的特征是将"类的功能层次结构"和"类的实现层次结构"分离开了,将类的这两个层次结构分离开来有利于独立的对他们进行扩展。
当想要增加新功能时,只需要在"类的功能层次结构"一侧增加类即可,不比对"类的实现层次结构"做任何修改。而且,增加后的功能可以被“所有的实现”使用
例如:我们可以将“类的功能层次”应用在软件所运行的操作系统上。如果我们将某个程序依赖与操作系统的部分化为Windows版、Mac版、Unix版,那我们九可以用Bridge模式中的“类的实现层次结构”来表现这些依赖于操作系统的部分。也就是说,我们需要编写一个定义于这些操作系统的共同接口的Implementor角色,然后 编写Windows版、Mac版、Unix版的ConcreteImplementor角色。这样一来,无论“类的功能层次”增加多少个功能,它们都可以工作于这三个操作系统上。
2、继承是强关联,委托是弱关联
虽然使用继承容易扩展类,但是类之间也形成了一种强关联关系。例如,下面这段代码SomethingGood类是Something类的子类,但是 只要不修改代码,就无法 改变这种关系,因此,他们之间形成了一种强关联关系。
如果,想要很轻松改变类之间的关系,使用继承就不合适了。因为,每次改变类之间的关系都需要修改程序 。这时,可以使用“委托”来替代继承关系。
也就是说,当其他类要求Display“工作”的时候,Display并非自己工作,而是将工作“交给 Impl”。这就是委托。
继承是强关联关系,而委托 是弱关联关系。在设计类的时候,我们必须充分理解这一点。