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 /** * 职责链模式 * * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 * 抽象 ...
随机推荐
- js判断浏览器在PC中打开还是移动设备中打开
var browser = { versions: function () { va ...
- C# 从字符串向 datetime 转换时失败
更改电脑的日期类型即可,把短日期和长日期修改下面的样子即可:
- cookie、session、sessionid的区别
我们都知道银行,银行的收柜台每天要接待客户存款/取款业务,可以有几种方案: 1.凭借柜台职员的记忆,由收柜台职员来为每位顾客办理存款/取款业务,单凭职员的记忆力,要记到每位顾客的相貌,并迅速这个顾客当 ...
- Asp.net mvc 知多少(三)
本系列主要翻译自<ASP.NET MVC Interview Questions and Answers >- By Shailendra Chauhan,想看英文原版的可访问http:/ ...
- 支付宝 Android 版使用的开源组件
支付宝 Android 版使用的开源组件 前言: 花了点时间整理了 支付宝 Android 客户端使用的开源组件,给需要的同学.在你不知道用什么开源框架的时候可以作下参考,毕竟支付宝是阿里的重量级产品 ...
- greenlet 详解
在前面的文章中提到python原生的generator是semicoroutine,而greenlet是 真 协程.本文内容主要来自对官网文档的翻译,在其中也加入了很多自己的理解和例子.主要包括以下内 ...
- B树的查找、插入、删除(附源代码)
B-Tree Index B-Tree搜索 B-Tree插入 分裂节点 插入节点 B-Tree删除 合并节点 删除节点 Basic B-Tree有两个比较重要的性质: 所有的leaf均在同一个leve ...
- Kafka 0.10 KafkaConsumer流程简述
ConsumerConfig.scala 储存Consumer的配置 按照我的理解,0.10的Kafka没有专门的SimpleConsumer,仍然是沿用0.8版本的. 1.从poll开始 消费的规则 ...
- 蓝桥网试题 java 基础练习 矩阵乘法
------------------------------------------------------------ 第一次感觉到好好学习的重要性QAQ 在做这道题之前请先学会 :矩阵乘法(百度百 ...
- 数据库--iOS
1.创建表 @"create table if not exists Person(id integer primary key autoincrement,name text,gender ...