设计模式学习笔记——桥接(Bridge)模式
@(设计模式)[设计模式, 桥接模式, bridge]
基本介绍
Bridge
的意思是”桥梁”。就像在现实世界中,桥梁的功能是将河流的两侧连接起来一样,Bridge
模式的作用也是将两样东西连接起来,它们分别是类的功能层次结构和类的实现层次结构。
Bridge
模式的作用是在”类的功能层次结构”和”类的实现层次结构”之间搭建桥梁。
类的功能层次结构
Something
L一一SomethingGood
L一一SomethingBetter
这就是为了增加新功能而产生的层次结构。
- 父类具有基本功能
- 在子类中增加新的功能
这种层次结构被称为”类的功能层次结构“。
类的实现层次结构
AbstractClass
L一一ConcreteClass
L一一AnotherConcreteClass
这就是为了实现类功能而产生的层次结构。
- 父类通过声明抽象方法来定义接口(
API
) - 子类通过实现具体方法来实现接口(
API
)
这种层次结构被称为”类的实现层次结构” 。
使用桥接模式的原因
当我们想要编写子类时,就需要像这样先确认自己的意图”我是要增加功能呢?还是要增加实现呢?”当类的层次结构只有一层时,功能层次结构与实现层次结构是混杂在一个层次结构中的。这样很容易使类的层次结构变得复杂,也难以透彻地理解类的层次结构。因为自己难以确定究竟应该在类的哪一个层次结构中去增加子类。
因此,我们需要将”类的功能层次结构”与”类的实现层次结构” 分离为两个独立的类层次结构。当然,如果只是简单地将它们分开,两者之间必然会缺少联系。所以我们还需要在它们之间搭建一座桥梁。Bridge
模式的作用就是搭建这座桥梁。
桥接案例
类图
实现代码
Display类
package com.pc.bridge.example;
/**
* 显示
* Created by Switch on 2017-02-18.
*/
public class Display {
// 显示实现对象(实现层次)
private DisplayImpl displayImpl;
/**
* 构造方法,传入显示实现对象
*
* @param displayImpl 显示实现对象
*/
public Display(DisplayImpl displayImpl) {
this.displayImpl = displayImpl;
}
/**
* 打开
*/
public void open() {
this.displayImpl.rawOpen();
}
/**
* 打印
*/
public void print() {
this.displayImpl.rawPrint();
}
/**
* 关闭
*/
public void close() {
this.displayImpl.rawClose();
}
/**
* 打印
*/
public void display() {
this.open();
this.print();
this.close();
}
}
CountDisplay类
package com.pc.bridge.example;
/**
* 计数打印类(功能层次)
* Created by Switch on 2017-02-18.
*/
public class CountDisplay extends Display {
/**
* 构造方法,传入显示实现对象
*
* @param displayImpl 显示实现对象
*/
public CountDisplay(DisplayImpl displayImpl) {
super(displayImpl);
}
/**
* 打印多次
*
* @param times 次数
*/
public void multiDisplay(int times) {
this.open();
for (int i = 0; i < times; i++) {
this.print();
}
this.close();
}
}
DisplayImpl抽象类
package com.pc.bridge.example;
/**
* 显示实现抽象类(实现层次)
* Created by Switch on 2017-02-18.
*/
public abstract class DisplayImpl {
/**
* 原始打开
*/
public abstract void rawOpen();
/**
* 原始打印
*/
public abstract void rawPrint();
/**
* 原始关闭
*/
public abstract void rawClose();
}
StringDisplayImpl类
package com.pc.bridge.example;
/**
* 字符串打印实现类
* Created by Switch on 2017-02-18.
*/
public class StringDisplayImpl extends DisplayImpl {
// 字符串
private String string;
// 字符串的字节码长度
private Integer width;
public StringDisplayImpl(String string) {
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void rawOpen() {
this.printLine();
}
@Override
public void rawPrint() {
System.out.println("|" + this.string + "|");
}
@Override
public void rawClose() {
this.printLine();
}
/**
* 打印一行
*/
private void printLine() {
// 打印如 +----------+这样的一行
System.out.print("+");
for (int i = 0; i < this.width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}
测试类
package com.pc.bridge.example.test;
import com.pc.bridge.example.CountDisplay;
import com.pc.bridge.example.Display;
import com.pc.bridge.example.StringDisplayImpl;
import org.junit.Test;
/**
* Display Tester.
*
* @author Switch
* @version 1.0
*/
public class DisplayTest {
@Test
public void testDisplay() throws Exception {
Display display1 = new Display(new StringDisplayImpl("Hello World!"));
Display display2 = new CountDisplay(new StringDisplayImpl("Hello Java!"));
CountDisplay display3 = new CountDisplay(new StringDisplayImpl("Hello Design!"));
display1.display();
System.out.println();
display2.display();
System.out.println();
display3.display();
System.out.println();
display3.multiDisplay(3);
}
}
运行结果
+------------+
|Hello World!|
+------------+
+-----------+
|Hello Java!|
+-----------+
+-------------+
|Hello Design!|
+-------------+
+-------------+
|Hello Design!|
|Hello Design!|
|Hello Design!|
+-------------+
桥接模式中的角色
Abstraction(抽象化)
该角色位于”类的功能层次结构”的最上层。它使用Implementor
角色的方法定义了基本的功能。该角色中保存了Implementor
角色的实例。在案例中,由Display
类扮演此角色。
RefinedAbstraction(改善后的抽象化)
在Abstraction
角色的基础上增加了新功能的角色。在案例中,由CountDisplay
类扮演此角色。
Implementor(实现者)
该角色位于”类的实现层次结构”的最上层。它定义了用于实现Abstraction
角色的接口(API
)的方法。在案例中,由DisplayImpl
类扮演此角色。
Concretelmplementor(具体实现者)
该角色负责实现在Implementor
角色中定义的接口(API
)。在案例中,由StringDisplayImpl
类扮演此角色。
类图
GitHub:DesignPatternStudy
——————参考《图解设计模式》