JAVA SCRIPT设计模式--结构型--设计模式之Bridge桥接模式

Posted 火柴盒zhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA SCRIPT设计模式--结构型--设计模式之Bridge桥接模式相关的知识,希望对你有一定的参考价值。

         JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代表全部的正确,特此声明。若读者需要了解设原则、设计变化方向,环境相关等信息请查看设计模式开篇

        所有JAVA SCRIPT设计模式快捷连接:

              创建型:(1)  抽象工厂 (2) 生成器 (3) 工厂方法 (4) 原型  (5) 单例

              结构型:(6) 适配器  (7) 桥接  (8) 组合 (9) 装饰 (10) 外观 (11) 享元 (12) 代理​

              行为型:(13) ​职责链 (14) ​命令 (15) ​解释器 (16) ​迭代器 (17) ​中介者 (18) ​备忘录 (119) ​观察者 (20) ​状态​ (21) ​策略 (22) ​模板方法 (23) 访问者​


一、UML类图

参与者:

1.1 Abstraction(Window)

  • 定义抽象类的接口。
  • 维护一个指向Implementor类型对象的指针。

1.2 RefinedAbstraction(IconWindow)

  • 扩充由Abstraction定义的接口。

1.3 Implementor(WindowImp)

  • 定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。

1.4 ConcreteImplementor(XwindowImp,PMWindowImp)

  • 实现Implementor接口并定义它的具体实现。

二、意图

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

三、适用性

  1. 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
  2. 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。。
  3. 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
  4. (C++)你想对客户完全隐藏抽象的实现部分。在C++中,类的表示在类接口中是可见的。

四、优点和缺点

        Bridge模式有以下一些优点:

  1. 分离接口及其实现部分一个实现未必不变地绑定在一个接口上。抽象类的实现可以在运行时刻进行配置,一个对象甚至可以在运行时刻改变它的实现。将Abstraction与Implementor分离有助于降低对实现部分编译时刻的依赖性,当改变一个实现类时,并不需要重新编译Abstraction类和它的客户程序。为了保证一个类库的不同版本之间的二进制兼容性,一定要有这个性质。另外,接口与实现分离有助于分层,从而产生更好的结构化系统,系统的高层部分仅需知道Abstraction和Implementor即可。
  2. 提高可扩充性你可以独立地对Abstraction和Implementor层次结构进行扩充。
  3. 实现细节对客户透明你可以对客户隐藏实现细节,例如共享Implementor对象以及相应的引用计数机制(如果有的话)。

五、示例代码

5.1  动机

         当一个抽象可能有多个实现时,通常用继承来协调它们。抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现。但是此方法有时不够灵活。继承机制将抽象部分与它
的实现部分固定在一起,使得难以对抽象部分和实现部分独立地进行修改、扩充和重用
        让我们考虑在一个用户界面工具箱中,一个可移植的Window抽象部分的实现。例如,这一抽象部分应该允许用户开发一些在X Window System和IBM的Presentation Manager(PM)系
统中都可以使用的应用程序。运用继承机制,我们可以定义Window抽象类和它的两个子类XWindow与PMWindow,由它们分别实现不同系统平台上的Window界面。但是继承机制有两个不足之处:

  1. 扩展Window抽象使之适用于不同种类的窗口或新的系统平台很不方便。假设有Window的一个子类IconWindow,它专门将Window抽象用于图标处理。为了使IconWindow支持两个系统平台,我们必须实现两个新类XIconWindow和PMIconWindow,更为糟糕的是,我们不得不为每一种类型的窗口都定义两个类。而为了支持第三个系统平台我们还必须为每一种窗口定义一个新的Window子类,如下图所示。
  2. 继承机制使得客户代码与平台相关。每当客户创建一个窗口时,必须要实例化一个具体的类,这个类有特定的实现部分。例如,创建Xwindow对象会将Window抽象与XWindow的实现部分绑定起来,这使得客户程序依赖于XWindow的实现部分。这将使得很难将客户代码移植到其他平台上去。

         客户在创建窗口时应该不涉及到其具体实现部分。仅仅是窗口的实现部分依赖于应用运行的平台。这样客户代码在创建窗口时就不应涉及到特定的平台。

        Bridge模式解决以上问题的方法是,将Window抽象和它的实现部分分别放在独立的类层次结构中。其中一个类层次结构针对窗口接口(Window、IconWindow、TransientWindow 临时),
另外一个独立的类层次结构针对平台相关的窗口实现部分,这个类层次结构的根类为WindowImp。例如XwindowImp子类提供了一个基于XWindow系统的实现,如下页上图所示。

        对Window子类的所有操作都是用WindowImp接口中的抽象操作实现的。这就将窗口的抽象与系统平台相关的实现部分分离开来。因此,我们将Window与WindowImp之间的关系称之
为桥接
,因为它在抽象类与它的实现之间起到了桥梁作用,使它们可以独立地变化。

5.2  示例UML

目录结构:

5.2 Abstraction(Window)

  • 定义抽象类的接口。
  • 维护一个指向Implementor类型对象的指针。
import  WindowImp from '../WindowImp/WindowImp.js';

export default  class Window 
	windowImp;
    constructor(windowImp) 
		this.windowImp=windowImp;
    
	
    DrawText()   
		this.windowImp.DevDrawText();  
    
	
	DrawRect() 
		console.log(` Window 的DrawRect方法 `);   
		this.windowImp.DevDrawLine();
		this.windowImp.DevDrawLine();
		this.windowImp.DevDrawLine();
		this.windowImp.DevDrawLine();
	
    
  

5.3 RefinedAbstraction(IconWindow)

  • 扩充由Abstraction定义的接口。
import Window  from '../Window.js';
 
export default  class IconWindow extends Window 
   
	constructor(windowImp) 
		 super(windowImp);
    
   DrawBorder() 
   	   this.DrawText();
	   this.DrawRect();
   
    
    
   

5.4 Implementor(WindowImp)

  • 定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。
export default  class WindowImp 
	
    constructor() 
    
    DevDrawText()   
		  
    
    DevDrawRect()     
		 
    
  

5.5 ConcreteImplementor(XwindowImp,PMWindowImp)

  • 实现Implementor接口并定义它的具体实现。
import WindowImp  from '../WindowImp.js';
 
export default  class XWindowImp extends WindowImp 
   
	constructor() 
		 super();
    
    DevDrawText() 
    	 console.log(` XWindowImp 的DevDrawText方法 `);   
    
    DevDrawLine()     
       console.log(` XWindowImp 的DevDrawLine方法 `);   
    
    
   

5.6 Client

import Window  from './Window/Window.js';
import IconWindow  from './Window/impl/IconWindow.js';
import TranslentWindow  from './Window/impl/TranslentWindow.js';
import XWindowImp  from './WindowImp/impl/XWindowImp.js';
 
export default class Client
    main()
	    let iconwindow =new IconWindow(new XWindowImp() );//Window
		let tranwindow =new TranslentWindow(new XWindowImp() );//Window 
		iconwindow.DrawBorder();
		tranwindow.DrawCloseBox();
     
 

5.7 测试html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
 
 
 <script  type="module" >
 import Client  from './Client.js'; 
 
let cl=new Client();
cl.main()

 </script>
</head>
<body>

    
</body>
</html>

测试结果:

XWindowImp.js:9  XWindowImp 的DevDrawText方法 
Window.js:14  Window 的DrawRect方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 
Window.js:14  Window 的DrawRect方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 
XWindowImp.js:12  XWindowImp 的DevDrawLine方法 

六、源代码下载

        下载链接:https://pan.baidu.com/s/1XuPqp84cccBNVkbnMY3sKw 
         提取码:q2ut

以上是关于JAVA SCRIPT设计模式--结构型--设计模式之Bridge桥接模式的主要内容,如果未能解决你的问题,请参考以下文章

JAVA SCRIPT设计模式--结构型--设计模式之Decorator装饰模式

JAVA SCRIPT设计模式--结构型--设计模式之FACADE外观模式(10)

JAVA SCRIPT设计模式--结构型--设计模式之FACADE外观模式(10)

JAVA SCRIPT设计模式--结构型--设计模式之Proxy代理模式(12)

JAVA SCRIPT设计模式--结构型--设计模式之ADAPTER适配器

JAVA SCRIPT设计模式--结构型--设计模式之FlyWeight享元模式(11)