【设计模式】桥接模式

文章目录

  • 引例
  • 理论
  • 使用场景
  • 课堂练习
  • 区分抽象工厂模式和桥接模式

引例

【设计模式】桥接模式_第1张图片
方案一
通过组合杯子大小和咖啡品种形成各个具体类,再设定一个IceCream作为抽象类,形成层次类结构
【设计模式】桥接模式_第2张图片

说明:这个设计符合OCP,但存在类爆炸问题
方案二
增加一个表示杯子大小的层次
【设计模式】桥接模式_第3张图片
说明:符合OCP,但应对变化时的设计修改很复杂。
增加一个冰激凌品种,需要同时在两个地方添加子类
新增一种杯子规格(例如Small Cup),需要再增加一个层次类,同时添加所有冰淇淋品种的子类
方案三
将杯子大小和冰淇淋品种这两个变化的维度分开
【设计模式】桥接模式_第4张图片
说明:在这样的设计模式下,两个类系可以独立地、互不影响的增加类,并满足开闭原则
代码实现

// IceCream类系
public abstract class IceCream {
	public abstract float getPrice();
}
public class DairyQueen extends IceCream{
	@Override
	public float getPrice() {
		return 5.0F;
	}
}
public class HaagenDazs extends IceCream {
	@Override
	public float getPrice() {
		return 6.0F;
	}
}
public class Nestle extends IceCream{
	@Override
	public float getPrice() {
		return 5.5F;
	}
}
// Cup类系
public abstract class Cup {
	protected IceCream iceCream;
	public Cup(IceCream iceCream) {
		this.iceCream = iceCream;
	}
	public abstract float getPrice();
}

public class SuperCup extends Cup{
	public SuperCup(IceCream iceCream) {
		super(iceCream);
	}
	@Override
	public float getPrice() {
		return 1.5f * iceCream.getPrice();
	}
}

public class MidCup extends Cup{
    public MidCup(IceCream iceCream) {
        super(iceCream);
    }
    @Override
    public float getPrice() {
        return iceCream.getPrice();
    }
}
// Client使用
public class Client {
public static void main(String[] args) {
	IceCream iceCream = new DairyQueen();
	Cup cup = new MidCup(iceCream);
	System.out.println("Midcup"+"DairyQueen"+cup.getPrice());
	cup = new SuperCup(iceCream);
	System.out.println("Supercup"+
				   "DairyQueen"+cup.getPrice());
	}
}

理论

将一个系统分为抽象部分和实现部分,并通过桥(Bridge)连接这两个维度

【设计模式】桥接模式_第5张图片
说明
桥接模式满足OCP
抽象部分和实现部分的分离实现了结构解耦,使得系统易于扩展和维护
将实现部分聚合到抽象部分可以在运行时动态配置

使用场景

多维度扩展
当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时
避免类爆炸
避免多层次继承带来的系统类数目急剧增加,比如引例设计的方案二
增加灵活性
当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时

课堂练习

【设计模式】桥接模式_第6张图片
【设计模式】桥接模式_第7张图片
ps:关于类中的构造函数,当类中含有实例变量时,往往这样的实例变量不会改变,就用一个构造函数进行确定,省去了繁杂的getters和setters函数

区分抽象工厂模式和桥接模式

两个模式的相似点
抽象工厂模式和桥接模式都有避免类爆炸的使用场景,并且不同的品牌如美式、意式、中式和对应的产品族如咖啡、沙拉、小面包也可以视为两个变化点
如何区分
桥接模式的关键在于分离变化点,其产品是确定的比如IceCream,并不存在产品族如咖啡、沙拉、小面包,并且从引例来看,其实上使用桥接模式的所有类是可以做成一个两层次的类层次结构,即所有类都是一个统一的IceCream的子类
而抽象工厂是使用一个工厂创建出了一个产品族,它不是同一个产品变化的问题,而是一个产品族创建的问题,如果非要用一个产品抽象类food作为全部产品族的父类,这是不自然的,因为不同的产品有不同的属性和方法

你可能感兴趣的:(#,设计模式,设计模式,桥接模式,java,学习,笔记)