• 设计模式(九)Bridge模式


      Bridge模式就是将类的功能层次结构和类的实现层次结构连接起来。

      类的功能层次结构就是根据实际非抽象类来说的,也就是父类具有基本功能,然后在子类中增加新功能。用于增加新功能。

      类的实现层次结构就是根据抽象类来说的,也就是父类通过声明抽象方法来定义接口,子类通过实现具体方法来实现接口。用于增加新实现。

     1 package bigjunoba.bjtu.function;
     2 
     3 import bigjunoba.bjtu.implement.DisplatImpl;
     4 
     5 public class Display {
     6     
     7     private DisplatImpl impl;
     8 
     9     public Display(DisplatImpl impl) {
    10         this.impl = impl;
    11     }
    12     
    13     public void open() {
    14         impl.rawOpen();
    15     }
    16     
    17     public void pring() {
    18         impl.rawPrint();
    19     }
    20     
    21     public void close() {
    22         impl.rawClose();
    23     }
    24     
    25     public final void display() {
    26         open();
    27         pring();
    28         close();
    29     }
    30 }

      Display类位于“类的功能层次结构”的最上层。这里的原理和Builder模式比较一下还是有点相似的。DisplatImpl类是个抽象类,定义了三个抽象方法。同样的Display类通过构造函数将DisplatImpl类传递进来,由于抽象类不能被实例化,因此传递进来的也就是DisplatImpl的子类,并保存在impl字段中。impl字段就是类的两个层次结构的“桥梁”。

     1 package bigjunoba.bjtu.function;
     2 
     3 import bigjunoba.bjtu.implement.DisplatImpl;
     4 
     5 public class CountDisplay extends Display{
     6 
     7     public CountDisplay(DisplatImpl impl) {
     8         super(impl);
     9     }
    10     
    11     public void multiDisplay(int times) {
    12         open();
    13         for (int i = 0; i < times; i++) {
    14             pring();
    15         }
    16         close();
    17     }
    18     
    19 }

      CountDisplay类位于“类的功能层次结构”的最下层。CountDisplay类继承了Display类,用于在Display类的基础上增加一个新功能。首先通过构造器调用父类的构造函数,然后multiDisplay方法用来增加新的功能。

      下面来看一下“类的实现层次结构”部分。也就是桥的另外一侧。

    1 package bigjunoba.bjtu.implement;
    2 
    3 public abstract class DisplatImpl {
    4     
    5     public abstract void rawOpen();
    6     public abstract void rawPrint();
    7     public abstract void rawClose();
    8     
    9 }

       DisplatImpl位于“类的实现层次结构”的最上层。声明了三个抽象方法。

     1 package bigjunoba.bjtu.implement;
     2 
     3 public class StringDisplayImpl extends DisplatImpl{
     4     
     5     private String string;
     6     private int width;
     7     public StringDisplayImpl(String string) {
     8         this.string = string;
     9         this.width = string.getBytes().length;
    10     }
    11 
    12     @Override
    13     public void rawOpen() {
    14         printLine();
    15     }
    16 
    17     @Override
    18     public void rawPrint() {
    19         System.out.println("|" + string + "|");
    20     }
    21 
    22     @Override
    23     public void rawClose() {
    24         printLine();
    25     }
    26     
    27     private void printLine() {
    28         System.out.print("+");
    29         for (int i = 0; i < width; i++) {
    30             System.out.print("-");
    31         }
    32         System.out.println("+");
    33     }
    34 
    35 }

      StringDisplayImpl类位于“类的实现层次结构”的最下层。作为DisplatImpl类的子类,用来实现DisplatImpl类的三个抽象方法。

     1 package bigjunoba.bjtu.test;
     2 
     3 import bigjunoba.bjtu.function.CountDisplay;
     4 import bigjunoba.bjtu.function.Display;
     5 import bigjunoba.bjtu.implement.StringDisplayImpl;
     6 
     7 public class Main {
     8     
     9     public static void main(String[] args) {
    10         Display display1 = new Display(new StringDisplayImpl("Lianjiang"));
    11         Display display2 = new CountDisplay(new StringDisplayImpl("Lianjiangjiang"));
    12         CountDisplay countDisplay = new CountDisplay(new StringDisplayImpl("Lianjiangjiangjiang"));
    13         display1.display();
    14         display2.display();
    15         countDisplay.display();
    16         countDisplay.multiDisplay(5);
    17     }
    18 }

      Main类作为测试类,这里需要好好理解一下。这三个实例的创建都是先向StringDisplayImpl类传递一个String类型的字符串,然后通过StringDisplayImpl类的构造器生成的对应的三个实例。display1字段保存的是Display类的构造器通过接受DisplayImpl抽象类的子类生成的实例也就是impl,然后生成了Display类的实例。display2字段保存的是具有新功能的Display类的实例。而countDisplay字段保存的也是具有新功能的CountDisplay类的实例,由于CountDisplay类是Display类的子类,本质上来说还是属于Display类的实例,说白了就是既可以调用Display类的基本功能,也可以调用CountDisplay类的新功能。

    +---------+
    |Lianjiang|
    +---------+
    +--------------+
    |Lianjiangjiang|
    +--------------+
    +-------------------+
    |Lianjiangjiangjiang|
    +-------------------+
    +-------------------+
    |Lianjiangjiangjiang|
    |Lianjiangjiangjiang|
    |Lianjiangjiangjiang|
    |Lianjiangjiangjiang|
    |Lianjiangjiangjiang|
    +-------------------+
    

       输出结果是这样的。结合上述分析来看就很明显了。

      下面是Bridge模式的类图。

      这里就不解释了。结合示例程序看就很容易理解。要强调的一点是,如果想要增加功能,只需要在“类的功能层次结构”一侧增加类即可,而“类的实现层次结构”不需要做任何改变,最关键的是,增加后的功能可以被“所有的实现”使用。

      扩展部分:继承和委托。

      继承是一种强关联关系。通俗来说,就是如果不修改代码,那么就很难改变子类和父类之间的关系。

      委托是一种弱关联关系。例如,示例中,Display类的impl字段保存了实现的实例,这样类的任务就发生了转移,比如调用open方法就会调用impl.rawOpen方法,也就是如果想让Display类工作,这个时候Display类就不自己工作,而是交给impl,让impl去工作。这就是“委托”。更加深入地理解,弱关联是因为,只有Display类的实例生成时,才与作为参数被传入的类构成关联。示例中的Main类,只有生成DIsplay类和CountDisplay类的实例时,才将StringDisplayImpl的实例作为参数传递给Display类和CountDisplay类。还有一个优点就是,如果新加了一个实现,就是讲其他ConcreteImplementor类的实例传递给Display类和CountDisplay类时也可以轻松实现,而其他Display类和DisplayImpl类不需要做任何改变,也就是上面强调的,如果想要增加功能,只需要在“类的功能层次结构”一侧增加类即可,而“类的实现层次结构”不需要做任何改变,最关键的是,增加后的功能可以被“所有的实现”使用。总结来说,这种模式的优点就是,有利于独立地对它们进行扩展。

    儿女情长什么的,最影响我们闯荡江湖了。
  • 相关阅读:
    day-16 json模块,pickle模块,collections模块,openpyxl模块
    day-15时间模块,datetime模块,random随机模块
    day-5OS与操作系统交互的模块,sys模块,加密模块
    day14内置函数,函数递归,模块
    day13三元表达式,列表生成式,生成器表达式,匿名函数,内置函数
    day13面向过程编程
    day13生成器
    叠加装饰器,
    迭代器
    day11---装饰器
  • 原文地址:https://www.cnblogs.com/BigJunOba/p/8685990.html
Copyright © 2020-2023  润新知