桥接模式
定义:在软件系统中,某些类型由于自身的逻辑,它具有两个纬度的变化,那么如何应对这种多维度的变化呢?就是使他的抽象部分和实现部分分离开,使他们可以独立变化。
使用场景:需要按两个维度区分的情况。比如奶茶,按杯型分为大中小,按温度分为常温、加冰。那么如果按照普通接口实现要定义3*2=6个类才能处理。
桥接模式包含了以下角色:
- 抽象化(Abstraction)角色:定义抽象类,并包含对实现化对象的引用
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- 实现化角色(Implementor):定义实现化角色的接口,供扩展抽象化角色调用。
- 具体实现化角色(Concrete Implementor):给出实现化角色接口的具体实现
例子:我们去咖啡馆喝咖啡,一般有4种选择:大杯加糖,大杯不加糖,小杯加糖,小杯不加糖。按 桥接模式 来说,应该有两个实现:大小杯,有无糖(味道)。但是两个 实现 有点冗余,完全可以把 “大小杯” 这个维度归并到咖啡本身属性中,从而这个例子的维度变成:咖啡大小杯,有无糖(味道)。
/**
* @description:桥接模式
* @author: mmc
* @create: 2019-09-04 21:56
**/
public class Client {
interface ICoffeeFlavor {
String addWhat();
}
// ConcreteImplementor:原味
static class PlainFlavor implements ICoffeeFlavor {
@Override
public String addWhat() {
return "原味";
}
}
// ConcreteImplementor:加糖
static class SugarFlavor implements ICoffeeFlavor {
@Override
public String addWhat() {
return "加糖";
}
}
// Abstraction:咖啡
static abstract class Coffee {
protected ICoffeeFlavor mFlavor;
public Coffee(ICoffeeFlavor flavor) {
this.mFlavor = flavor;
}
public abstract void makeCoffee();
}
// RefinedAbstraction:大杯咖啡
static class LargeCoffee extends Coffee {
public LargeCoffee(ICoffeeFlavor flavor) {
super(flavor);
}
@Override
public void makeCoffee() {
System.out.println("大杯咖啡: " + this.mFlavor.addWhat());
}
}
// RefinedAbstraction:小杯咖啡
static class SmallCoffee extends Coffee {
public SmallCoffee(ICoffeeFlavor flavor) {
super(flavor);
}
@Override
public void makeCoffee() {
System.out.println("小杯咖啡:" + this.mFlavor.addWhat());
}
}
public static void main(String[] args) {
Coffee coffee=new SmallCoffee(new SugarFlavor());
coffee.makeCoffee();
Coffee coffee2=new SmallCoffee(new PlainFlavor());
coffee2.makeCoffee();
}
}