TypeScript设计模式之职责链、状态
看看用TypeScript怎样实现常见的设计模式,顺便复习一下。
学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想记住就好。
这里尽量用原创的,实际中能碰到的例子来说明模式的特点和用处。
职责链模式 Chain of Responsibility
特点:可以让一个请求被不同的对象处理多次,请求像经过管道一样, 一路上都可以被拦下处理。
用处:当请求需要被链式处理时,可以考虑职责链模式,比如事件的冒泡,WebApi的管道Handler等。
注意:链的实现。
WebApi的handler可能大家有用过,对发出去的请求和请求回来的数据都可以用自定义handler在发出前或最终回来前进行处理,非常方便,下面用TypeScript来简单实现一个HttpHandler:
先建立一个抽象Handler类,包含一个发送请求的sendReqeust以及用来链式处理的innerHandler:
abstract class HttpHandler{
constructor(protected innerHandler: HttpHandler){}
async sendRequest(req: string): Promise<string>{
if(this.innerHandler){
return await this.innerHandler.sendRequest(req);
} else {
let res = `response`;
console.log(res);
return res;
}
}
}
实现第一个Handler类:
class FirstHttpHandler extends HttpHandler{
async sendRequest(req: string): Promise<string>{
req = `<req1>${req}</req1>`; // 把请求包一下
console.log(req);
let res = await super.sendRequest(req);
res = `<res1>${res}</res1>`; // 把结果包一下
console.log(res);
return res;
}
}
再实现第二个Handler类:
class SecondHttpHandler extends HttpHandler{
async sendRequest(req: string): Promise<string>{
req = `<req2>${req}</req2>`; // 把请求包一下
console.log(req);
let res = await super.sendRequest(req);
res = `<res2>${res}</res2>`; // 把结果包一下
console.log(res);
return res;
}
}
把两个HttpHandler连起来
let httpHandler = new FirstHttpHandler(new SecondHttpHandler(undefined));
console.log('start')
httpHandler.sendRequest('request').then(res=>console.log('finish'));
输出:
start
<req1>request</req1> // 发请求前先在FirstHttpHandler里处理request
<req2><req1>request</req1></req2> // 在SecondHttpHandler里再次处理request
response // 返回数据
<res2>response</res2> // SecondHttpHandler对返回数据的第一次处理
<res1><res2>response</res2></res1> // FirstHttpHandler对返回数据的第二次处理
finish
处理的顺序就是 1221,中间是真正取数据的,这就是管道处理最基本的代码,用到的就是职责链模式。
当然职责链的形成有很多方式,这里采用的是装饰手段,保存下一个的引用的方式来形成一个链表,还可以采用队列或栈方式保存所有handler,按顺序执行。
状态模式 State
特点:通过状态来改变对象的行为。
用处:当对象的行为取决于它的状态或者有很多if else之类的是由状态控制的时候可以考虑状态模式,如常见的状态机。
注意:状态是由谁来转换。
下面用TypeScript简单实现一下状态模式:
大家都玩过游戏,控制游戏的主角时鼠标左键可以是移动,遇到怪时点击左键是攻击,遇到NPC时是对话。
下面就以这点简单实现个状态模式:
角色和状态的接口,状态只需要处理当前状态需要做的事:
interface Role{
name: string;
click();
changeState(state: State);
}
interface State{
handle(role: Role);
}
角色的具体实现:
class Player implements Role{
private state: State;
constructor(public name: string){
}
click(){
if(this.state){
this.state.handle(this);
}
}
changeState(state: State){
this.state = state;
console.log(`change to ${this.state.constructor.name}`);
}
}
状态的具体实现,分为移动状态,攻击状态,对话状态:
class MoveState implements State{
static readonly instance = new MoveState();
handle(role: Role){
console.log(`${role.name} is moving`);
}
}
class AttackState implements State{
static readonly instance = new AttackState();
handle(role: Role){
console.log(`${role.name} is attacking`);
}
}
class TalkState implements State{
static readonly instance = new TalkState();
handle(role: Role){
console.log(`${role.name} is talking`);
}
}
使用:
let player = new Player('brook');
player.changeState(MoveState.instance);
player.click();
player.changeState(AttackState.instance);
player.click();
player.changeState(TalkState.instance);
player.click();
//输出:
change to MoveState
brook is moving
change to AttackState
brook is attacking
change to TalkState
brook is talking
这样随着状态的变化,点击左键做不同的事。
对于由谁来驱动状态变化可以根据实际情况来考虑,简单的话直接放角色里面就行,由角色自己决定自己的状态,复杂的话可以考虑用表来驱动状态机,通过表过实现状态的跳转。
TypeScript设计模式之职责链、状态的更多相关文章
- php设计模式之职责链模式
<?php /** * @desc php设计模式之职责链模式(责任链模式) 定义:顾名思义,责任链模式为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这 ...
- 设计模式之职责链模式(JAVA实现)
学习netty框架时,看到有人说netty用到了设计模式的职责链模式,学习一下职责链模式,主要参考大话设计模式. 主要场景: 小菜想要加薪,向经理提出加薪请求,经理没有权限,经理交由总监处理,总监也没 ...
- 设计模式-利用职责链模式消除if
本文是对职责链设计模式的应用(变种),所以假设读者已经掌握了职责链设计模式,职责链模式只会应景简介. 本文主要内容: 需求(ShitCode) 职责链模式简介 设计理念 代码演示(消除if) 应用总结 ...
- 设计模式:职责链模式(Chain Of Responsibility)
定 义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 结构图: 处理请求类: //抽象处理类 abs ...
- 设计模式之职责链模式(Chain of Responsibility)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- C#设计模式之职责链
Iron之职责链 需求: "Iron"的建造一直没有停止,现在单个部件是有的,但是在部件从工厂里出来的时候,在组装到一起之前,我们还是非常有必要对部件进行质量检测,或者是其它个方面 ...
- Java设计模式之职责链设计模式
1.什么是-职责链设计模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求 ...
- 深入理解JavaScript系列(38):设计模式之职责链模式
介绍 职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象 ...
- php实现设计模式之 职责链模式
<?php /** * 职责链模式 * * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 * 抽象 ...
随机推荐
- 解析STL中典型的内存分配
1 vector 在C++中使用vector应该是非常频繁的,但是你是否知道vector在计算内存分配是如何么? 在c++中vector是非常类似数组,但是他比数组更加灵活,这就表现在他的大小是可以自 ...
- Servlet RequestDispatcher需要注意的情况
Servlet RequestDispatcher需要注意的情况: 如果使用getServletContext().getRequestDispatcher("/a.do")得到R ...
- saiku的源码包Bulid常见问题和jar包
最近在做kylin+mondrian+saiku的二次开发的时候,Bulid saiku的源码出现了很多问题,基本上一大部分问题jar找不到问题,很多jar国内网站都找不到.这时候只有手动下载然后注册 ...
- Myeclipse8.5 反编译插件 jad 安装(转)
准备工作 下载jad.exe文件:http://www.varaneckas.com/sites/default/files/jad/jad158g.win.zip 下载jadeclipse插件:ht ...
- 如何使用DockerHub官方的mysql镜像
Mysql是一个广泛使用的开源关系型数据库. 如何获取Mysql Docker镜像? docker pull mysql:5.7 如何使用这个Docker镜像? 1.启动一个Mysql Server容 ...
- StringUtils工具类常用方法介绍(持续更新)
StringUtils方法的操作对象是java.lang.String类型的对象,是JDK提供的String类型操作方法的补充,并且是null安全的(即如果输入参数String为null则不会抛出Nu ...
- LoRaWAN协议(七)--完整数据流程
以下的GW指Gateway 所用指令: root@lora-iot-sk:~# tcpdump -i lo -nn -x 'length>100' 入网流程 GW -> NS join_r ...
- PHP面向对象(OOP)----分页类
> 同验证码类,分页也是在个人博客,论坛等网站中不可缺少的方式,通过分页可以在一个界面展示固定条数的数据,而不至于将所有数据全部罗列到一起,实现分页的原理其实就是对数据库查询输出加了一个limi ...
- 【小分享】Date对象封装,时间格式化函数time()
今天再来分享下Date的应用知识点 先看效果,类似于php里边的time('yyyy-mm-dd')用法,但是我这里没有完全依照php的参数格式来,如果有需要稍微修改一下就行. 首先,明确需要用到的参 ...
- java类初始化,使用构造方法
public class test { /** * java类的初步学习: * 学会使用和类名相同的两种构造方法,对公共类方法的调用: */ public static void main(Str ...