设计模式之桥接模式
桥接模式是一种结构模型。
场景:假如我们要实现如下的一个电脑商品的分类:我们可以用多层继承结构实现下图的关系
多层继承机制实现
用UML图表示:
public interface Computer { void sale(); } class Desktop implements Computer { @Override public void sale() { System.out.println("销售台式机"); } } class Laptop implements Computer { @Override public void sale() { System.out.println("销售笔记本"); } } class Pad implements Computer { @Override public void sale() { System.out.println("销售平板电脑"); } } class LenovoDesktop extends Desktop { @Override public void sale() { System.out.println("销售联想台式机"); } } class DellDesktop extends Desktop { @Override public void sale() { System.out.println("销售戴尔台式机"); } } class Asustop extends Desktop { @Override public void sale() { System.out.println("销售华硕台式机"); } } class LenovoLaptop extends Laptop { @Override public void sale() { System.out.println("销售联想笔记本"); } } class DellLaptop extends Laptop { @Override public void sale() { System.out.println("销售联想笔记本"); } } class AsusLaptop extends Laptop { @Override public void sale() { System.out.println("销售华硕笔记本"); } } class LenovoPad extends Pad{ @Override public void sale() { System.out.println("销售联想平板"); } } class DellPad extends Pad{ @Override public void sale() { System.out.println("销售戴尔平板"); } } class AsusPad extends Pad{ @Override public void sale() { System.out.println("销售华硕平板"); } }
问题:
(1)扩展性问题
如果需要添加新的品牌,如添加神州笔记本,那我们需要添加该品牌下面的所有的类型,如神州台式机,神州笔记本,神州Pad;
如果需要添加新的电脑类型,如添加智能手机,那我们需要给每个品牌下都添加智能手机;
(2)违反单一职责原则
一个类:联想笔记本有两个引发变化的原因,品牌和类型。
桥接模式实现
桥接模式核心是处理多层继承机制,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。
根据上图实现如下:
/** * <p> * 品牌类型维度 * <p>*/ public interface Brand { void sale(); } class Lenovo implements Brand { @Override public void sale() { System.out.println("销售联想产品"); } } class Dell implements Brand { @Override public void sale() { System.out.println("销售戴尔产品"); } } class Asus implements Brand { @Override public void sale() { System.out.println("销售华硕产品"); } }
/** * <p> * 电脑类型维度 * <p>*/ public class Computet2 { protected Brand brand; public Computet2(Brand brand) { this.brand = brand; } public void sale(){ brand.sale(); } } class Desktop2 extends Computet2{ public Desktop2(Brand brand) { super(brand); } @Override public void sale() { super.sale(); System.out.println("销售台式机"); } } class Laptop2 extends Computet2{ public Laptop2(Brand brand) { super(brand); } @Override public void sale() { super.sale(); System.out.println("销售台笔记本"); } } class Pad2 extends Computet2{ public Pad2(Brand brand) { super(brand); } @Override public void sale() { super.sale(); System.out.println("销售平板"); } }
测试类:
public class Client { public static void main(String[] args) { //销售联想台式机 Computet2 computet2 = new Desktop2(new Lenovo()); computet2.sale(); } }
桥接模式总结:
(1)桥接模式可以取代多层的继承方案。多层继承违背了单一职责原则,复用性差,类的个数较多;桥接模式可以极大的减少子类的个数,降低维护和管理成本。
(2)桥接模式极大了系统扩展性,在两个维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则。
应用场景:
(1)银行日志管理:
格式分类:操作日志、交易日志、异常日志;
距离分类:本地记录日志、异地记录日志;
(2)人力资源系统中的奖金计算模块:
奖金分类:个人奖金、团体奖金、激励奖金;
部门分类:人事部门、销售部门、开发部门;
(3)OA系统中的消息处理:
业务类型:普通消息、加急消息、特急消息;
发送消息方式:系统内消息、手机短信、邮件