今天开始进入到 Behavioral design patterns,这一类的模式着重於物件之间的沟通与责任分配,就让我们接下去一起看看吧
当有一个需要处理的需求(或请求)进入系统的时候,这个系统中负责的物件会串成一个链,然後让这个需求依序被处理。在这个过程当中,每一个物件会
假设有一间公司,准备发起一个新的 VIP 会员回馈方案,不过会员本身的点数和经验需要到一个标准值才能参与。
如果我们的 Member
类别像是下面这样
class Member {
points: number;
experience: number;
constructor(points: number, experience: number){
this.points = points
this.experience = experience
}
}
const memberA = new Member(1500, 2000)
接下来,我们就可以很简单写一个函式来进行判断。譬如我们希望找到点数大於 1000、经验值大於 1500 的会员来参与 VIP 会员回馈方案,实作如下:
const handler = (member: Member): boolean => {
const { points, experience } = member
return points > 1000 && experience > 1500
}
但如果未来我们有不同的回馈方案有不同的标准值、又或者说需要加入更多的判断条件,那麽我们就需要建立更多的 handler 函式,或者是不断的修改原有的 handler 函式。
如果我们可以用组合的方式,将不同的判断函式组合成我们需要的函式,可以随意调整,随插随用,是不是就会很方便呢?
接下来让来看看责任链模式可以怎麽处理这个问题
首先,我们建立 Handler
介面,和一个抽象类别。这里我们定义 handler 当中需要有两个方法,一个是处理需求的 handle
方法,另一个是记录下一个 handler 的位置
interface Handler {
handle(member: Member): boolean
next(handler: Handler): Handler
}
abstract class AbstractHandler implements Handler {
protected nextHandler: Handler
next(handler: Handler): Handler {
this.nextHandler = handler
return handler
}
handle(member: Member): boolean {
return false
}
}
接着,我们就可以分别建立处理 points 和处理 experience 的 handler
class PointsHandler extends AbstractHandler {
private limit: number;
constructor(limit: number){
super()
this.limit = limit
}
handle(member: Member): boolean {
if (member.points > this.limit) {
return this.nextHandler
? this.nextHandler.handle(member) && true
: true;
}
return false;
}
}
class ExperienceHandler extends AbstractHandler {
private limit: number;
constructor(limit: number){
super()
this.limit = limit
}
handle(member: Member): boolean {
if (member.experience > this.limit) {
return this.nextHandler
? this.nextHandler.handle(member) && true
: true;
}
return false;
}
}
这里我们做了几件事情
handle
方法当中,我们会进行条件判断,如果不通过,就会直接回传 false;如果通过,就会看之後的 handler 是否通过,来决定最後的回传值接下来,我们就可以分别建立 pointsHandler 和 experienceHandler
const pointsHandler = new PointsHandler(1000)
const experienceHandler = new ExperienceHandler(1500)
然後,记得把他们给串连一起
pointsHandler.next(experienceHandler)
最後,我们就可以用来判断不同 member 的状况
const memberA = new Member(1500, 2000)
const memberB = new Member(1250, 1250)
const memberC = new Member(750, 750)
pointsHandler.handle(memberA) // true
pointsHandler.handle(memberB) // false,因为 experience 不够
pointsHandler.handle(memberC) // false,因为 points 和 experience 不够
所以未来如果我们想要调整判断的条件限制(譬如降低 points 条件至 500),那麽只要透过 PointsHandler
和 ExperienceHandler
类别建立新的实例即可。
如果我们想要调整判断的方式(譬如移除 points,新增 level),那麽我们就可以依赖 AbstractHandler
实作另外一个新的 handler,然後用 next
方法把需要的方式给组合在一起
责任链模式提供了很高的扩充弹性,让我们能够依序处理需求或请求,同时不需要去修改既有的物件或函式。而缺点就是,不一定所有的请求都会被完全处理到。
证书申请和回应 证书签名请求(Certificate Signing Request) 在公钥基础结...
今天要教 mongo aggregate 中文叫做聚合 是一种将来自多个document的value...
每份专案都是团队尽心竭力的成果,而 Demo 就是向长官及其他部门展示团队实力的重要时刻! 但如果在...
今天要来学习程序语言中非常重要的一个概念(功能)-回圈,回圈到底可以拿来干嘛呢?先来看个例子: 如果...
在上一篇我们介绍的 CSS in JS, 那这次我们来使用 CSS in JS 的框架 emotio...