介绍
桥接(Bridge)模式也称为桥梁模式,是结构型设计模式。桥梁模式的定义,将抽象部分与实现部分分离,使他们可以独立地进行变化。或者说将类的功能层次结构与实现层次结构分离。
模式角色
桥梁模式有以下角色:
- Abstraction(抽象化),定义抽象类,并包含一个对实现化对象的引用。
- RefinedAbstraction(修正抽象化),是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- Implementor(实现化),定义实现化角色的接口,供扩展抽象化角色调用。
- ConcreteImplementor(具体实现化),给出实现化角色接口的具体实现。
模式结构图
(结构图来源于网上)
模式实现
public abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public void operation() {
implementor.operationImpl();
}
}
public class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
// 对父类中的方法进行扩展
public void refinedOperation() {
// 业务逻辑
}
}
public abstract class Implementor {
// 实现抽象部分的具体方法
public abstract void operationImpl();
}
public class ConcreteImplementorA extends Implementor {
@Override
public void operationImpl() {
// 具体的业务逻辑
}
}
public class ConcreteImplementorB extends Implementor {
@Override
public void operationImpl() {
// 具体的业务逻辑
}
}
模式应用案例
制作一杯咖啡,有大杯加糖、大杯加盐巴、中杯加糖、中杯加盐巴、小杯…
/**
* Abstraction
* <p>
* 咖啡
*/
public abstract class Coffee {
protected CoffeeAdditives impl;
public Coffee(CoffeeAdditives impl) {
this.impl = impl;
}
// 做成什么样的咖啡由子类决定
public abstract void makeCoffee();
}
/**
* Refined Abstraction
* <p>
* 大杯咖啡
*/
public class LargeCoffee extends Coffee {
public LargeCoffee(CoffeeAdditives impl) {
super(impl);
}
@Override
public void makeCoffee() {
System.out.println("大杯的" + impl + "咖啡");
}
}
/**
* Refined Abstraction
* <p>
* 中杯咖啡
*/
public class MiddleCoffee extends Coffee {
public MiddleCoffee(CoffeeAdditives impl) {
super(impl);
}
@Override
public void makeCoffee() {
System.out.println("中杯的" + impl + "咖啡");
}
}
/**
* Refined Abstraction
* <p>
* 小杯咖啡
*/
public class SmallCoffee extends Coffee {
public SmallCoffee(CoffeeAdditives impl) {
super(impl);
}
@Override
public void makeCoffee() {
System.out.println("小杯的" + impl + "咖啡");
}
}
/**
* Implementor
* <p>
* 咖啡添加物
*/
public abstract class CoffeeAdditives {
// 具体要往咖啡添加什么由子类实现
public abstract String addSomething();
}
/**
* Concrete Implementor
* <p>
* 咖啡添加物 糖
*/
public class Sugar extends CoffeeAdditives {
@Override
public String addSomething() {
return "加糖";
}
}
/**
* Concrete Implementor
* <p>
* 咖啡添加物 盐巴
*/
public class Salt extends CoffeeAdditives {
@Override
public String addSomething() {
return "盐巴";
}
}
/**
* Concrete Implementor
* <p>
* 咖啡添加物 原味
*/
public class Ordinary extends CoffeeAdditives {
@Override
public String addSomething() {
return "原味";
}
}
/**
* Client
*/
public class BridgeClient {
public static void main(String[] args) {
Salt saltImpl = new Salt();
Sugar sugarImpl = new Sugar();
// 大杯咖啡 加盐巴
LargeCoffee largeCoffeeSalt = new LargeCoffee(saltImpl);
largeCoffeeSalt.makeCoffee();
// 大杯咖啡 加糖
LargeCoffee largeCoffeeSugar = new LargeCoffee(sugarImpl);
largeCoffeeSugar.makeCoffee();
// 小杯咖啡 加盐巴
SmallCoffee smallCoffeeSalt = new SmallCoffee(saltImpl);
smallCoffeeSalt.makeCoffee();
// 小杯咖啡 加糖
SmallCoffee smallCoffeeSugar = new SmallCoffee(sugarImpl);
smallCoffeeSugar.makeCoffee();
}
}
模式退化
在只有一个ConcreteImplementor角色的情况下,Implementor角色可以省略。但是抽象化角色(Abstraction)与实现化角色(ConcreteImplementor)的划分仍然有意义。
模式使用场景
- 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
- 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
- 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。