将抽象部分与实现部分分离,使它们都可以独立的变化
将继承关系转换成组合关系,用组合表示多维度的数据
事例
需求:装水果的包装有两个维度的分类,大小和材质
存在的问题:要创建所有种类的包装,需要有3*2=6个类。且每新增一个分类,类的数量就会乘积式增长
种类的组合如图
解决问题:
从每个维度入手,以大小为主要维度用抽象类BagAbstraction表示,材质维度用接口Material表示
BagAbstraction中持有Material对象即可
结构如图:
数据结构如下:
只形成数据的抽象部分
// 材质及其实现类
public interface Material {
class Plastic implements Material {
}
class Paper implements Material {
}
}
// 大小及其实现类
public abstract class BagAbstraction {
public Material mMaterial;
public static class BigBag extends BagAbstraction {
}
public static class MidBag extends BagAbstraction {
}
public static class SmallBag extends BagAbstraction {
}
}
测试:
创建对象时才是数据的实现部分
public void bridge() {
// 大号包装
BagAbstraction.BigBag bigBag = new BagAbstraction.BigBag();
// 塑料包装
bigBag.mMaterial = new Material.Plastic();
}
思路
- 挑选一个维度为主要维度,用抽象类表示
- 其他维度用接口表示
- 抽象类中持有其他维度的对象,从而建立关联关系
- 所有种类都去实现对应维度的抽象类/接口
- 构建具体数据类时,先创建一个主要维度的对象,其他维度注入到成员中即可
总结
适用场景
当一个数据结构由多个维度组成时。数据类则需要继承/实现多个接口(代码如下),导致数据类的数量爆炸
public class BigPlasticBag extends BagAbstraction implements Plastic {
}
优点
- 分离了抽象部分和实现部分
- 扩展性强。新增种类时,只需要在一个维度上添加种类
缺点
- 关联关系在抽象层,需要掌握系统的抽象关系