软件设计模式学习(十一)桥接模式

桥接模式

桥接模式用一种很巧妙的方式处理继承存在的问题,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效地控制了系统中类的个数。


模式动机

设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要四个形状类,如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有两种设计方案:第一种是为每一个行政都提供一套各种颜色的版本,这种方案使用的是多级继承结构,如果有四种形状,十二种颜色,则我们需要四十八个类。如果要增加新形状则同时也要具备所有的颜色,增加新的颜色也要为所有的形状添加对应颜色的子类;第二种提供四个形状类、十二种颜色类,根据实际对形状和颜色进行组合,此时系统中的类是十六个。如需增加新的形状或颜色,只需再增加一个新的形状类或颜色类即可。

很明显,对于有两个变化维度(即两个变化的原因)的系统,采用方案二可以使系统中类的个数更少,且系统扩展更为方便。


模式定义

将抽象部分与它的实现部分分离,使它们都可以独立地变化


模式结构

软件设计模式学习(十一)桥接模式_第1张图片

桥接模式包含如下几个角色:

  1. Abstraction(抽象类)

    用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义一个Implementor类型对象使其与implementor之间具有关联关系,它可以包含抽象的业务方法,还可以包含具体的业务方法。

  2. RefineAbstraction(扩充抽象类)

    扩充由Abstraction定义的接口,通常情况下是具体类,实现在Abstraction中定义的抽象业务方法,在RefineAbstraction可以调用Implementor中定义的业务方法。

  3. Implementor(实现类接口)

    对一些基本操作进行了定义,而具体实现交给其子类。

  4. ConcreteImplementorA(具体实现类)

    实现Implementor接口并且具体实现它,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时ConcreteImplementor对象将替换其父类对象,提供给客户具体的业务操作方法。


桥接模式实例之模拟毛笔

  1. 实例说明

    现需提供大小两种型号的画笔,能绘制三种不同的颜色,只需五个类就能实现功能。

  2. 实例代码及解释

    1. 实现类接口Color

      public interface Color {
      
          void bepaint(String penType, String name);
      }
      
    2. 具体实现类Red

      public class Red implements Color {
      
          @Override
          public void bepaint(String penType, String name) {
              System.out.println(penType + "红色的" + name);
          }
      }
      
    3. 具体实现类Green

      public class Green implements Color {
      
          @Override
          public void bepaint(String penType, String name) {
              System.out.println(penType + "绿色的" + name);
          }
      }
      
    4. 具体实现类Blue

      public class Blue implements Color {
      
          @Override
          public void bepaint(String penType, String name) {
              System.out.println(penType + "蓝色的" + name);
          }
      }
      
    5. 抽象类Pen

      public abstract class Pen {
      
          protected Color color;
      
          public void setColor(Color color) {
              this.color = color;
          }
      
          public abstract void draw(String name);
      }
      
    6. 扩充抽象类BigPen

      public class BigPen extends Pen {
      
          @Override
          public void draw(String name) {
              String penType = "大号毛笔绘制";
              this.color.bepaint(penType, name);
          }
      }
      
    7. 扩充抽象类SmallPen

      public class SmallPen extends Pen {
      
          @Override
          public void draw(String name) {
              String penType = "小号毛笔绘制";
              this.color.bepaint(penType, name);
          }
      }
      
    8. XML操作工具

      public class XMLUtilPen {
      
          public static Object getBean(String args) {
      
              try {
                  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                  DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
      
                  Document document = documentBuilder.parse(new File("configPen.xml"));
                  NodeList nodeList = document.getElementsByTagName("className");
                  Node classNode = null;
      
                  if (args.equals("color")) {
                      classNode = nodeList.item(0).getFirstChild();
                  } else if (args.equals("pen")) {
                      classNode = nodeList.item(1).getFirstChild();
                  }
      
                  String cName = classNode.getNodeValue();
      
                  Class c = Class.forName("com.bridgePattern." + cName);
                  Object o = c.newInstance();
                  return o;
      
              } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
      
          }
      }
      
    9. 客户端测试类Client

      public class Client {
      
          public static void main(String[] args) {
      
              Color color = (Color) XMLUtilPen.getBean("color");
              Pen pen = (Pen) XMLUtilPen.getBean("pen");
      
              pen.setColor(color);
              pen.draw("桃花");
          }
      }
      
    10. 结果分析

      如果在配置文件将第一个节点中内容设置为 Red,第一个节点中内容设置为 BigPen,则输出结果如下:
      在这里插入图片描述
      如果在配置文件将第一个节点中内容设置为 Blue,第一个节点中内容设置为 SmallPen,则输出结果如下:
      在这里插入图片描述
      如果需要增加新的毛笔或颜色,只需增加对应的扩充抽象类或具体实现类即可。在使用桥接模式设计的系统中,无论是哪个维度的扩展,对原有代码都无须修改,且更换具体类只需修改配置文件,桥接模式通过抽象方法耦合,使得系统具有良好的扩展能力。

你可能感兴趣的:(设计模式)