image.png

传统方案

image.png

问题

扩展性问题:(类爆炸) 如果再增加手机的样式,就需要增加各个手机品牌类的手机,同样新增一个品牌类手机,需要在各个手机样式类下增加
违反了单一职责原则,当增加手机样式的时候,要同事增加所有品牌的手机

桥接模式

介绍

桥接模式 是指:将实现与抽象放在俩个不同的类层次中,使俩个层次可以独立改变
是一种结构性设计模式
桥接模式是基于类的最小设计原则,用过使用封装、聚合和继承等相位让不用的类承担不同的职责,主要特点是把抽象和行为的实现分离开,从而可以保持各部分的独立性以及对他们的功能扩展

image.png
Clinet类:桥接模式的调用者
抽象类 Abstraction 维护了 Implementor /即是他的实现类 ConCreateImolementorA…,二者是聚合关系,Abstraction充当桥接类
RefinedAbstraction 是Abstraction抽象类的子类
Imolemetor 行为实现类的接口
ConcreteImolementorA/B 行为的具体实现类

UML图 这个的抽象类和接口是聚合的关系,即是调用和被调用的关系

桥接模式案例UML
image.png

  1. //接口
  2. public interface Brand {
  3. void open();
  4. void close();
  5. void call();
  6. }
  7. public class XiaoMi implements Brand {
  8. @Override
  9. public void open() {
  10. // TODO Auto-generated method stub
  11. System.out.println(" 小米手机开机 ");
  12. }
  13. @Override
  14. public void close() {
  15. // TODO Auto-generated method stub
  16. System.out.println(" 小米手机关机 ");
  17. }
  18. @Override
  19. public void call() {
  20. // TODO Auto-generated method stub
  21. System.out.println(" 小米手机打电话 ");
  22. }
  23. }
  24. public class Vivo implements Brand {
  25. @Override
  26. public void open() {
  27. // TODO Auto-generated method stub
  28. System.out.println(" Vivo手机开机 ");
  29. }
  30. @Override
  31. public void close() {
  32. // TODO Auto-generated method stub
  33. System.out.println(" Vivo手机关机 ");
  34. }
  35. @Override
  36. public void call() {
  37. // TODO Auto-generated method stub
  38. System.out.println(" Vivo手机打电话 ");
  39. }
  40. }
  1. public abstract class Phone {
  2. //组合品牌
  3. private Brand brand;
  4. //构造器
  5. public Phone(Brand brand) {
  6. super();
  7. this.brand = brand;
  8. }
  9. protected void open() {
  10. this.brand.open();
  11. }
  12. protected void close() {
  13. brand.close();
  14. }
  15. protected void call() {
  16. brand.call();
  17. }
  18. }
  19. //折叠式手机类,继承 抽象类 Phone
  20. public class FoldedPhone extends Phone {
  21. //构造器
  22. public FoldedPhone(Brand brand) {
  23. super(brand);
  24. }
  25. public void open() {
  26. super.open();
  27. System.out.println(" 折叠样式手机 ");
  28. }
  29. public void close() {
  30. super.close();
  31. System.out.println(" 折叠样式手机 ");
  32. }
  33. public void call() {
  34. super.call();
  35. System.out.println(" 折叠样式手机 ");
  36. }
  37. }
  38. public class UpRightPhone extends Phone {
  39. //构造器
  40. public UpRightPhone(Brand brand) {
  41. super(brand);
  42. }
  43. public void open() {
  44. super.open();
  45. System.out.println(" 直立样式手机 ");
  46. }
  47. public void close() {
  48. super.close();
  49. System.out.println(" 直立样式手机 ");
  50. }
  51. public void call() {
  52. super.call();
  53. System.out.println(" 直立样式手机 ");
  54. }
  55. }
public static void main(String[] args) {

        //获取折叠式手机 (样式 + 品牌 )

        Phone phone1 = new FoldedPhone(new XiaoMi());

        phone1.open();
        phone1.call();
        phone1.close();

        System.out.println("=======================");
    }

image.png

A+B 确定一个具体的类 可以使用桥接模式

注意事项

  1. 实现了抽象和显示部分的分离,提供了很大灵活性,让抽象部分和实现部分独立开,有利于系统的分层设计。
  2. 对于系统的高层部分,只需要知道抽象部分和实体部分接口就可以了,其他部分由具体业务来完成
  3. 桥接模式替代多层继承方案,可以减少子类个数,降低系统的管理 和维护成本

缺点:
增加了系统的理解和设计难度,聚合的关联关系建立在抽象层
要求正确识别出系统的俩个独立变化的维度,因此其适用范围有一定的局限性,

使用场景举例

银行转账:
转账分类:网上转账,柜台转账,ATM转账
转账用户类型:普通用户,银卡用户,金卡用户

消息管理:
消息类型:即时消息,延迟消息
消息分类:手机短信,邮件消息,QQ消息