看看用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设计模式之职责链、状态的更多相关文章

  1. php设计模式之职责链模式

    <?php /** * @desc php设计模式之职责链模式(责任链模式) 定义:顾名思义,责任链模式为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这 ...

  2. 设计模式之职责链模式(JAVA实现)

    学习netty框架时,看到有人说netty用到了设计模式的职责链模式,学习一下职责链模式,主要参考大话设计模式. 主要场景: 小菜想要加薪,向经理提出加薪请求,经理没有权限,经理交由总监处理,总监也没 ...

  3. 设计模式-利用职责链模式消除if

    本文是对职责链设计模式的应用(变种),所以假设读者已经掌握了职责链设计模式,职责链模式只会应景简介. 本文主要内容: 需求(ShitCode) 职责链模式简介 设计理念 代码演示(消除if) 应用总结 ...

  4. 设计模式:职责链模式(Chain Of Responsibility)

    定  义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 结构图: 处理请求类: //抽象处理类 abs ...

  5. 设计模式之职责链模式(Chain of Responsibility)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  6. C#设计模式之职责链

    Iron之职责链 需求: "Iron"的建造一直没有停止,现在单个部件是有的,但是在部件从工厂里出来的时候,在组装到一起之前,我们还是非常有必要对部件进行质量检测,或者是其它个方面 ...

  7. Java设计模式之职责链设计模式

    1.什么是-职责链设计模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求 ...

  8. 深入理解JavaScript系列(38):设计模式之职责链模式

    介绍 职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象 ...

  9. php实现设计模式之 职责链模式

    <?php /** * 职责链模式 * * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 * 抽象 ...

随机推荐

  1. docker的资源限制cpuset cpuquota memory

    总结 目前,公司7u已经不再使用lxc,转而使用libcontainer 即native docker对cpuquota的支持目前是有问题的,一般大家使用docker的时候,主要是对memory,cp ...

  2. CSS 简介、语法、派生选择器、id 选择器、类选择器、属性选择器

    CSS 概述 CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与表现 ...

  3. Java泛型类型擦除导致的类型转换问题

    初步结论:泛型类型转换不靠谱: 源码: package com.srie.testjava; public class TestClassDefine4<T> { public stati ...

  4. 对lua中_ENV表的理解(lua5.2版本以后)

    当我拿到_ENV表的时候,会去想这个_ENV表是干什么用的? 首先看如下代码: print(_ENV) --0x1d005f0 print(_G) --0x1d005f0 ViewCode 看了上面的 ...

  5. python中关于元组的操作

    元组的基本操作:1.创建一个元组: tuple=(1,26); tuple1=(","sy"); 创建一个空元组: tuple=(); 元组中只包含一个元素时,需要在元素 ...

  6. 我的Linux软件集

    把我常用的软件记下来,以后重装安装的时候方便一些- 这个博文会不断更新的- 开发工具类 Monodevelop 编写C#控制台程序和GTK#窗口程序,很好,虽然没有VS强大,但是够用了 CodeBlo ...

  7. RxJava2出现:Unable to create call adapter for io.reactivex.Flowable

    前面一直使用的是Rxjava 1.x 版本,最近 Rxjava 2.x 版本发布了,并且支持了背压,便换成了 Rxjava 2.x 版本.更换之后出现了下面的错误. Caused by: java.l ...

  8. 警告1909。无法创建快捷方式VMware Workstation Pro.Ink。解决方法(附 VMware_workstation 12的安装方法)

    电脑之前装过VMware 10,很长时间没用就卸载了,也没有在意卸载的干不干净,直到最近需要用Linux系统,重新安装了VMware 12,就出现下面这样的情况: 警告1909.无法创建快捷方式VMw ...

  9. js实现省市区联动

    先来看看效果图吧,嘻嘻~~~~~~~~~~~~~~~~~~~· 代码在下面: 示例一: html: <!DOCTYPE html> <html> <head> &l ...

  10. css3 3d 与案例分析

    作者:魔洁 聊到3d那我们就先聊聊空间维度,首先一维,比如一条线就是一个一维空间,连点成线在这个空间里这些点只能前进后退,二维空间就是一个平面,这时点不仅可以前进后退还可以左右移动,3维空间也可以说是 ...