哈喽,今天我们来看下桥接模式,顾名思义,就是一座‘桥’,将不同维度的内容进行链接。我们来看下具体是什么意思吧。
定义: 将抽象部分与它的实现部分分离,使他们都可以独立地变化。看下UML结构图:
其中Abstraction为抽象化角色,定义出该角色的行为,同时保存一个对实例化角色的引用。implementor 是实例化角色,它是接口或者抽象类,定义角色必须的行为和属性。RefinedAbstraction 为修正抽象化角色,引用实例化角色对抽象化角色进行修改。ConcreteImplementor,为具体实现化角色,实现接口或抽象类定义的方法或者属性。这段是不是听着很懵,哈哈哈,没错,我也看着很懵。
下面我们举个栗子。
有个需求,点奶茶,奶茶容量分为大,小杯,奶茶中添加的牛奶,水果。怎么实现呢。有人说,我创建两个奶茶容量类,再创建两个奶茶放料的两个类,分别去处理这些,也可以实现功能,但是如果奶茶容量还有超大杯,中杯,等等,添加类让你怀疑人生。我看行通过桥接模式是怎么实现的。
public abstract class MilkyTea {
protected IMilkyTeaAdditives additives;
public MilkyTea(IMilkyTeaAdditives additives) {
this.additives = additives;
}
/**
* 点奶茶
* @param count
*/
public abstract void orderMilktyTea(int count);
}
public abstract class RefinedMilkyTea extends MilkyTea {
public RefinedMilkyTea(IMilkyTeaAdditives additives) {
super(additives);
}
}
//定义大杯奶茶
public class LargeMilkyTea extends RefinedMilkyTea {
public LargeMilkyTea(IMilkyTeaAdditives additives) {
super(additives);
}
@Override
public void orderMilktyTea(int count) {
additives.addsomething();
System.out.println(String.format("大杯奶茶%d杯",count));
}
}
public class SmallMilkyTea extends RefinedMilkyTea {
public SmallMilkyTea(IMilkyTeaAdditives additives) {
super(additives);
}
@Override
public void orderMilktyTea(int count) {
additives.addsomething();
System.out.println(String.format("小杯奶茶%d杯",count));
}
}
public interface IMilkyTeaAdditives {
void addsomething();
}
public class Milk implements IMilkyTeaAdditives {
@Override
public void addsomething() {
System.out.println("加奶");
}
}
public class Fruit implements IMilkyTeaAdditives {
@Override
public void addsomething() {
System.out.println("加水果");
}
}
//测试
public class TestMain {
public static void main(String[] args) {
LargeMilkyTea largeCoffee = new LargeMilkyTea(new Milk());
largeCoffee.orderMilktyTea(10); // 加奶 大杯奶茶10杯
SmallMilkyTea smallMilkyTea = new SmallMilkyTea(new Fruit());
smallMilkyTea.orderMilktyTea(5); //加水果 小杯奶茶5杯
}
}
看完这个代码 是不是清晰了很多。
优点:
缺点:
桥接模式实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。对于两个独立变化的维度,使用桥接模式再适合不过了。