1.前言
之前文章讲过策略模式,不懂的可以点击
策略模式
,
今天再来说个策略模式的升级版(matcher-handler),Matcher-Handler模式也是属于略模式的一种,只不过它是处理比较复杂逻辑的,同时可以处理多种情况,并且它是在运行时决定的一种策略模式!
2.概念
Matcher-Handler模式:
用一种松耦合的方式将原始数据分发传递给一个或多个数据处理器。这个模式显式地将数据鉴别匹配(Match)的责任从数据处理(Handle)中分离出来。
3.应用场景
Matcher-Handler模式适用于以下的情况:
1. 在不明确指定接收者的情况下分发数据。
2. 需要有多个对象同时而又各自独立的处理同一个数据事件。
3. 需要动态指定处理离散数据事件的对象。
4. 需要用一个处理器处理来自多个数据源的数据。
5. 你希望在未来可以很方便地为这个应用程序引入新的数据类型。
4.模式结构
装饰器模式主要包含以下角色:
1. 匹配器(IMathcer):定义一个接口,数据源用这个接口来鉴别一个特定的数据事件是否与一个特定的处理器需要的标准相匹配
2. 具体匹配器(ConcreteMathcer):实现匹配器接口以鉴别数据是否符合标准
3. 处理器(IHandler):声明一个接口,数据源用这个接口把数据传递给处理器
4. 具体处理器(ConcreteHandler):处理数据源按照应用程序定义的某种途径传递来的数据
5. 匹配处理(Pair):来维护匹配器和处理器之间的联系
6.数据源(DataSource):实现匹配器/处理器的注册和数据分发等行为
5.案例实现
场景:一家收银员的老板想叫你想写个关于收银机的程序,目前要求顾客需要支持3种付款方式,第一是微信付款,第二是支付宝付款,第三是银行卡付款,以后可能还会添加其他方式
从场景来看这是一种比价简单的策略模式,我们可以用matcher-handler来实现(你可以理解为判断的逻辑比较复杂),首先我们画出类图
-
首先创建IMatcher(匹配器接口),IHandler(处理器接口)
//IMatcher.ts
export interface IMatcher {
isMatcher(name:string): boolean;
}
//IHandler.ts
export interface IHandler {
prcoess(data:number): any;
}
-
创建具体的Matcher类和Handler类
//WebChatMatcher.ts
import { IMatcher } from "./IMatcher"
export class WebChatMatcher implements IMatcher {
isMatcher(name: string): boolean {
if (name === "webChat") {
return true;
}
return false;
};
}
//bankCardMatcher.ts
import { IMatcher } from "./IMatcher"
export class bankCardMatcher implements IMatcher {
isMatcher(name: string): boolean {
if (name === "bankCard") {
return true;
}
return false;
};
}
//AlipayMatcher.ts
import { IMatcher } from "./IMatcher"
export class AlipayMatcher implements IMatcher {
isMatcher(name: string): boolean {
if (name === "Alipay") {
return true;
}
return false;
};
}
//AlipayHandler.ts
import { IHandler } from "./IHandler"
export class AlipayHandler implements IHandler {
prcoess(data: number): any {
console.log(`received a payment of ${data} from Alipay`)
};
}
//bankCardHandler.ts
import { IHandler } from "./IHandler"
export class bankCardHandler implements IHandler {
prcoess(data: number): any {
console.log(`received a payment of ${data} from bankCard`)
};
}
WebChatHandler.ts
import { IHandler } from "./IHandler"
export class WebChatHandler implements IHandler {
prcoess(data: number): any {
console.log(`received a payment of ${data} from WeChat`)
};
}
-
创建维护匹配器和处理器之间联系的Pair类
import { IHandler } from "./IHandler";
import { IMatcher } from "./IMatcher";
export class Pair {
constructor(private matcher: IMatcher, private handler: IHandler) {
}
getMatcher(): IMatcher {
return this.matcher;
}
getHandler(): IHandler {
return this.handler;
}
}
-
创建数据源DataSource类来实现匹配器/处理器的注册和数据分发等行为
import { AlipayHandler } from "./AlipayHandler";
import { AlipayMatcher } from "./AlipayMatcher";
import { bankCardHandler } from "./bankCardHandler";
import { bankCardMatcher } from "./bankCardMatcher";
import { IHandler } from "./IHandler";
import { IMatcher } from "./IMatcher";
import { Pair } from "./Pair";
import { WebChatHandler } from "./WebChatHandler";
import { WebChatMatcher } from "./WebChatMatcher";
export class concreateDataSource {
public pairArray: Array<Pair> = [];
constructor() {
this.addMatcherHandler(new WebChatMatcher(), new WebChatHandler());
this.addMatcherHandler(new AlipayMatcher(), new AlipayHandler());
this.addMatcherHandler(new bankCardMatcher(), new bankCardHandler());
}
addMatcherHandler(matcher: IMatcher, handler: IHandler) {
let pair = new Pair(matcher, handler)
this.pairArray.push(pair);
}
deliverData(name: string, data: number) {
if (this.pairArray.length != 0) {
this.pairArray.forEach(function (pair) {
if (pair.getMatcher().isMatcher(name)) {
pair.getHandler().prcoess(data);
}
})
} else {
throw new Error("please check the matcherHandlerConfig")
}
}
}
-
最后外层调用
let payType: Array<string> = ["webChat", "Alipay", "bankCard"];
//顾客的钱
let money: number = 10;
//创建数据源类
let DataSource = new concreateDataSource();
//3种付款方式里面随机一种
DataSource.deliverData(payType[Math.round(Math.random()*3)],money);
-
看下图执行结果(收到支付宝支付10元!)
6.总结
上面的例子是3种中只执行一中,当然matcher-handler模式也可以执行开始匹配的一种(符合条件的先执行),或者执行匹配的最后一种(最后符合条件的执行),或者执行所有的匹配的(所有符合条件的都执行),主要看业务场景!