JAVA SCRIPT设计模式--行为型--设计模式之Responsibility职责链模式(13)

         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 Handler(如HelpHandler)

  • 定义一个处理请求的接口。

1.2 ConcreteHandler(如PrintButton和PrintDialog)

  • 处理它所负责的请求。
  • 可访问它的后继者。
  • 如果可处理该请求,就处理之;否则将该请求转发给它的后继者。

1.3 Client

  • 向链上的具体处理者(ConcreteHandler)对象提交请求。 

二、意图

     将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

三、适用性 

  1. 多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
  2. 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  3. 可处理一个请求的对象集合应被动态指定

四、优点和缺点

  1. 降低耦合度该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求会被“正确”地处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需知道链的结构。结果是,职责链可简化对象的相互连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
  2. 增强了给对象指派职责(Responsibility)的灵活性当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。
  3. 不保证被接受既然一个请求没有明确的接收者,那么就不能保证它一定会被处理—该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。

五、示例代码

5.1  动机

        考虑一个图形用户界面中的上下文有关的帮助机制。用户在界面的任一部分上点击就可以得到帮助信息,所提供的帮助依赖于点击的是界面的哪一部分以及其上下文。例如,对话 框中的按钮的帮助信息就可能和主窗口中类似的按钮不同。如果对那一部分界面没有特定的 帮助信息,那么帮助系统应该显示一个关于当前上下文的较一般的帮助信息。

        这儿的问题是提交帮助请求的对象(如按钮)并不明确知道谁是最终提供帮助的对象。我们 要有一种办法将提交帮助请求的对象与可能提供帮助信息的对象解耦(decouple)。ChainofResponsibility模式告诉我们应该怎么做。

        这一模式的想法是,给多个对象处理一个请求的机会,从而解耦发送者和接受者。该请求沿对象链传递直至其中一个对象处理它,如下图所示。

        从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提交请求的对象并不明确地知道哪一个对象将会处理它—我们说该请求有一个隐式的
接收者(implicitreceiver)。

        假设用户在一个标有“Print”的按钮窗口组件上单击帮助,而该按钮包含在一个PrintDialog的实例中,该实例知道它所属的应用对象(见前面的对象框图)。下面的交互框图
(diagram)说明了帮助请求怎样沿链传递

      

        在这个例子中,既不是aPrintButton也不是aPrintDialog处理该请求;它一直被传递给anApplication,anApplication处理它或忽略它。 

5.2  示例UML

目录结构:

5.2 Handler(如HelpHandler)

  • 定义一个处理请求的接口。
export default  class HelpHandler {
	handler;
    constructor(handler) {
		this.handler=handler;
    }
    HandleHelp() {   
		this.handler.HandleHelp();
    }
  }

5.3 ConcreteHandler(如PrintButton和PrintDialog)

  • 处理它所负责的请求。
  • 可访问它的后继者。
  • 如果可处理该请求,就处理之;否则将该请求转发给它的后继者。
import HelpHandler  from '../HelpHandler.js'; 
export default  class PrintButton extends HelpHandler {
   
	constructor(handler) {
		super(handler)
	}
    HandleHelp() {
   	  console.log(` 我是 PrintButton ,我不处理,交给上级处理  `);
   	  this.handler.HandleHelp();
    }
 
  } 
import HelpHandler  from '../HelpHandler.js'; 

export default  class PrintDialog extends HelpHandler {
   
	constructor(handler) {
		super(handler)
	}
   
	HandleHelp() {
		  console.log(` 我是 PrintDialog ,我不处理,交给上级处理  `);
		this.handler.HandleHelp();
	}
  } 
import HelpHandler  from '../HelpHandler.js'; 
export default  class Application extends HelpHandler {
   
	constructor(handler) {
		super(handler)
	}
   
	HandleHelp() {
		console.log(` 我是 Application ,我来处理这次的帮助。  `);
		console.log(` 请。。。  `); 
	}
  } 

5.4 Client

  • 向链上的具体处理者(ConcreteHandler)对象提交请求。 
import PrintButton  from './Handler/impl/PrintButton.js';
import Application  from './Handler/impl/Application.js';
import PrintDialog  from './Handler/impl/PrintDialog.js';

export default class Client{
    main(ctx){
	    let anApplication=new Application(null);
		let aPrintDialog=new PrintDialog(anApplication);
		let aPrintButton=new PrintButton(aPrintDialog);
		aPrintButton.HandleHelp();
    } 
 }

5.5 测试HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
 
 
 <script  type="module" >
 import Client  from './Client.js'; 
 var x=document.getElementById("mycanvas")
 var ctx=x.getContext("2d") //create 2d object
let cl=new Client();
cl.main(ctx)

 </script>
</head>
<body>
<canvas id="mycanvas" width=900px height=900px></canvas>
    
</body>
</html>

测试结果:



PrintButton.js:8  我是 PrintButton ,我不处理,交给上级处理  
PrintDialog.js:10  我是 PrintDialog ,我不处理,交给上级处理  
Application.js:9  我是 Application ,我来处理这次的帮助。  
Application.js:10  请。。。  

六、源代码下载

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值