软件系统设计-8-桥接模式、装饰器模式

1. 桥接模式

1.1. 模式动机

  1. 设想如果要绘制矩形、圆形、椭圆、正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、蓝色等,此时至少有如下两种设计方案:
    1. 第一种设计方案是为每一种形状都提供一套各种颜色的版本。
    2. 第二种设计方案是根据实际需要对形状和颜色进行组合。

1.2. 模式定义

  1. 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
  2. Bridge Pattern: Decouple an abstraction from its implementation so that the two can vary independently.

1.3. 模式结构

1.6. 实例二:跨平台视频播放器

  1. 如果需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Linux、Unix等)上播放多种格式的视频文件,常见的视频格式包括MPEG、RMVB、AVI、WMV等。现使用桥接模式设计该播放器。

  1. 一个 Java桌面软件总是带有所在操作系统的视感(LookAndFeel),如果一个Java软件是在Unix系统上开发的,那么开发人员看到的是Motif用户界面的视感;在Windows上面使用这个系统的用户看到的是Windows用户界面的视感;而一个在Macintosh上面使用的用户看到的则是Macintosh用户界面的视感,Java语言是通过所谓的Peer架构做到这一点的。Java为AWT中的每一个GUI构件都提供了一个Peer构件,在AWT中的Peer架构就使用了桥接模式
  2. JDBC驱动程序也是桥接模式的应用之一。使用JDBC驱动程序的应用系统就是抽象角色,而所使用的数据库是实现角色。一个JDBC驱动程序可以动态地将一个特定类型的数据库与一个Java应用程序绑定在一起,从而实现抽象角色与实现角色的动态耦合

1.10. 模式扩展

1.10.1. 适配器模式与桥接模式的联用

  1. 桥接模式和适配器模式用于设计的不同阶段,桥接模式用于系统的初步设计,对于存在两个独立变化维度的类可以将其分为抽象化和实现化两个角色,使它们可以分别进行变化;而在初步设计完成之后,当发现系统与已有类无法协同工作时,可以采用适配器模式。但有时候在设计初期也需要考虑适配器模式,特别是那些涉及到大量第三方应用接口的情况。

1.10.2. 适配器模式与桥接模式的联用

  1. 一般有两种方式可以实现给一个类或对象增加行为:
    1. 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
    2. 关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为。
  2. 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。这就是装饰模式的模式动机。

2.2. 模式定义

  1. 装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。根据翻译的不同,装饰模式也有人称之为”油漆工模式”,它是一种对象结构型模式
  2. Decorator Pattern: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

2.3. 模式结构

2.4.2. 实例二:多重加密系统

  1. 某系统提供了一个数据加密功能,可以对字符串进行加密。最简单的加密算法通过对字母进行移位来实现,同时还提供了稍复杂的逆向输出加密,还提供了更为高级的求模加密。用户先使用最简单的加密算法对字符串进行加密,如果觉得还不够可以对加密之后的结果使用其他加密算法进行二次加密,当然也可以进行第三次加密。现使用装饰模式设计该多重加密系统。

  1. 抽象装饰类:FilterInputStream
  1. 角色分配:
    1. 抽象构件类:InputStream
    2. 具体构件类:FileInputStream、ByteArrayInputStream等
    3. 抽象装饰类:FilterInputStream
    4. 具体装饰类:BufferedInputStream、DataInputStream等
  2. 客户端使用:

2.8. 模式扩展

  1. 装饰模式的简化-需要注意的问题
    1. 一个装饰类的接口必须与被装饰类的接口保持相同,对于客户端来说无论是装饰之前的对象还是装饰之后的对象都可以一致对待。
    2. 尽量保持具体构件类Component作为一个”轻”类,也就是说不要把太多的逻辑和状态放在具体构件类中,可以通过装饰类对其进行扩展。
    3. 如果只有一个具体构件类而没有抽象构件类,那么抽象装饰类可以作为具体构件类的直接子类
  2. 装饰模式的简化

软件系统设计-8-桥接模式、装饰器模式
  1. 透明装饰模式(多重加密系统)
    1. 在透明装饰模式中,要求客户端完全针对抽象编程,装饰模式的透明性要求客户端程序不应该声明具体构件类型和具体装饰类型,而应该全部声明为抽象构件类型。
  1. 半透明装饰模式(变形金刚)
    1. **半透明(semi-transparent)**的装饰模式允许用户在客户端声明具体装饰者类型的对象,调用在具体装饰者中新增的方法。

2.9. 小结

  1. 装饰模式用于动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。它是一种对象结构型模式。
  2. 装饰模式包含四个角色
    1. 抽象构件定义了对象的接口,可以给这些对象动态增加职责(方法)
    2. 具体构件定义了具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)
    3. 抽象装饰类是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现
    4. 具体装饰类是抽象装饰类的子类,负责向构件添加新的职责。
  3. 使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。
  4. 装饰模式
    1. 主要优点在于可以提供比继承更多的灵活性,可以通过一种动态的方式来扩展一个对象的功能,并通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,而且具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类
    2. 主要缺点在于使用装饰模式进行系统设计时将产生很多小对象,而且装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
  5. 装饰模式适用情况包括
    1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
    2. 需要动态地给一个对象增加功能,这些功能也可以动态地被撤销
    3. 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
  6. 装饰模式可分为透明装饰模式和半透明装饰模式
    1. 在透明装饰模式中,要求客户端完全针对抽象编程,装饰模式的透明性要求客户端程序不应该声明具体构件类型和具体装饰类型,而应该全部声明为抽象构件类型
    2. 半透明装饰模式允许用户在客户端声明具体装饰者类型的对象,调用在具体装饰者中新增的方法。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年3月7日
下一篇 2022年3月7日

相关推荐