关于"短信处理"模式的一段讨论

DH web

请教下你们一个设计模式的问题 spring

业务: 有多种短信指令,系统会根据接收到的指令进行相应的业务处理,处理完成后,系统会回复一条短信 设计模式

这种业务处理,能够用哪一个设计模式来作? 多线程

QX app

状态模式 函数

DH 工具

小雪,短信指令可能会增长,也可能会减小 性能

QB this

命令模式 spa

DH

用命令模式更合适?

QB

命令模式看起来挺奇怪的。

QB

interface ICommand{
ICommandResult Execute();
}

abstract class CommandResult{
virtual ToString();
}

DH

如何理解

QB

public class Invoker
{
void Invoke(ICommand cmd)
{
CommandResult ret = cmd.Execute();
MessageSender.Send(ret)
}
}

我以为 若是是同步模式话 用这种方式就能够了。很差说是什么设计模式。

interface ICommand{
CommandResult Execute();
}

敲错了,qq敲代码蛋疼。

DH

我再说下业务, 系统接收到上行短信后,会把短信push入消息队列, 有一个线程在监听消息队列,每pop出一条消息,都会判断这条消息是什么指令,不一样指令处理不一样业务

QB

能够用个工厂模式来建立消息。HandlerFactorywebserver里面基本上是这样处理的。

.aspx .ashx .asmx 不一样的扩展名经过HttpHandlerFactory 建立不一样的Handler

DH

消息类型的判断是放在工厂里作仍是放在监听消息队列的线程来作?

QB

Factory里面来作

if(aspx)
return aspxHandler;
else if
....

STST

这种方式,若是分支的数量自己就不稳定,那么维护起来不方便

QB

若是性能要求不高的话 能够用反射。

可是若是要求性能的话也只是修改一个类。能够接受。

DH

指令通常都是固定那些

应该不会怎么变

STST

尽可能避免修改一个类

QB

这个仍是看项目取舍吧。用反射来处理能够作到只修改配置文件。

DH

目前有11个指令类型,在想着怎么优雅的不须要写分支

STST

具体到这个例子,应该是工厂加职责链处理起来比较合适,我的认为

QB

用map
HandlerMap(string cmdString, Type handlerType)

QB

若是对多线程比较擅长,handler 作成单例的也能够。

QB

可是我以为11个指令 你就if else 简单有效。性能也无可挑剔

DH

STST
为何会想到职责链的?

STST

18:47:35

这里的每一个职责就是每一个相应的业务处理

而后就只要把这些职责串起来,最好把业务量最多的职责放前面

QB

若是须要对命令进行一些过滤操做的话 能够考虑责任链。若是只是单纯处理就不须要了。仍是看业务须要。

STST

而后用一个工厂,负责建立职责链

这样处理知足了OCP原则

若是之后增长了业务处理,那么咱们须要增长一个 职责
而后增长一个新的Factory20150405,负责建立新的职责链

不用去修改现有的类

QB

也是要改代码的

STST

这只是个人见解,不用改代码阿,只增长代码

QB

你新增了一个Factory 应该在程序里面去调用他啊

STST

使用那个Factory能够在配制文件里处理了

IOC的核心就是这个

选择哪一个具体的工厂,能够放配置文件里处理的

这里也同时知足了DIP原则,底层依赖了高层

高层不依赖底层

QB

那你至关于要弄一个抽象工厂,我以为不须要。简单工厂就能够了。抽象工厂的话要多很多类哦

STST

能够这么理解吧

@大模式-广州 ,这图画出来理解了吗?

DH

谢谢各位

我先看下

STST

针对一条短信X

再也不关心是什么命令,直接丢给职责链表来处理

职责链表.Do(X)

每一个职责里的处理方法象下面这样
Do(X)
{
if(须要本身处理(X)){具体处理;......}
else
Next.Do(X);
}

QB


修改一下

STST

这样处理没法知足OCP原则

QB

若是用反射的话是能够的。

STST

来了新的短信类型一定要修改

QB

不须要,我先写几句伪代码

DH

英界尔, 你的图是用什么工具画的,感受挺漂亮的

STST

VS

DH

VISIO?

STST

visual studio

DH

哦哦

STST

QB

public interface IHandler
{
void Handle();
}

public class ConcreteHandlerA : IHandler
{
public void Handle()
{
// handle commandA
}
}

public class ConcreteHandlerB : IHandler
{
public void Handle()
{
// handle commandB
}
}

public static class HandlerFactory
{
public static IHandler CreateHandler(string commandType)
{
switch (commandType)
{
case "A":
return new ConcreteHandlerA();
case "B":
return new ConcreteHandlerB();
default:
throw new NotSupportedException();
}
}
}

public class CommandParser
{
public void Receive(string msg)
{
Command cmd = this.ParseCommand(msg);

IHandler handler = HandlerFactory.CreateHandler(cmd.CommandType);
handler.Handle();
}
}

STST


问题就在这里,来了C,D,E,F呢

QB

罩门在HandlerFactory 增长新的command 只须要修改HandlerFactory。

可是若是在HandlerFactory中用反射的话 就能够作到不修改代码。

性能与优雅的取舍。

要优雅就用反射。要性能就用switch case

你的方法也避免不了这个问题。

罩门是同样的

STST


这一过程,有反射的话如何写?

QB

责任链比较适合要对一个命令分别处理
好比HttpModule 或 Filter之类的。

假设配置文件中已经把 commandType与handlerType作好映射。

DH

STST说的那种方案,能否经过Spring配置来避免后续修改代码问题

QB

string typeName = Configuration.GetTypeName(commandType);
Type handlerType = Type.GetType(typeName);
return (IHandler)Activator.CreateInstance(handlerType);

STST

@大模式-广州 那就是IOC

QB

是的。由于这种问题不用反射无解。必需要修改代码。

STST

看修改的是那里的代码,修改最顶层的代码代价很小,修改下面的代价较大

这里不管是哪一种方案,都在努力作一件事情,将对"具体"的了解尽可能网高层推

最理想的状况下,只有main函数须要知道全部的"具体"类

QB

哈哈 那就是标准的IOC了。

在Main里面作各类Mapping

DH

直接IOC是否是能够解决修改代码的问题,后续只要增长短信类型便可

QB

也是须要作映射的,可是通常IOC容器都支持配置文件,可使用配置文件进行映射。

STST

@大钱币-北京 没错,确定不止一种方式处理

DH

把全部短信类型IOC到一个list里,逐个循环,循环到匹配的类型跳出循环,不然next

STST

@大模式-广州 你这叫迭代,固然能够

DH

这样后面有新增的短信类型,只管新增类,往spring里配置

QB

IOC叫容器,他内部实现了这个循环匹配的过程。你要作的是把映射关系注册进去。要用的时候 直接resolve就能够了。

下班撤了。再见。

STST

若是你能本身控制循环过程的话,迭代固然能够

迭代和职责链的区别就是,谁来控制循环过程

X

没搞懂要迭代和职责链的目的是?

把获取具体的处理类抽象出来不行。?

STST

都是用来处理"循环"的

X

要加只要新加获取的处理类的抽象类的实现类。。

为何会有循环?

一条短信会对应多条处理么?

STST

那么我问你,短信X对应哪一个Handler的逻辑在那里?

DH

不是一条短信多个处理

而是有多种类型的短信

X

统一一个接收器。。根据接收到的短信类型,实例化具体的handler.

就这个场景的话不必用链啊。。

STST

具体一个短信X,选择那个Handler Y,这个处理有两个地方能够处理

X

要是有一些别的场景,校验XXX之类 的到是有可能

STST

1,分支,if else
2,由每一个业务处理类自身判断

X

若是只是处理短信这一个handler彻底不必用责任链了。

if else是用来干啥 的呢?

STST

干这个阿

X

这个方法能够抽象出来。。由子类去实现得了。

STST

那么我想了解的是,是否有一个职责链,处理一个请求的时候,会有多个职责去处理的状况吗?

X

就他这个场景。。我以为没有。

STST

哦,那就是没有,采用什么模式,提早设计实际上并不可靠,要在实际中重构到模式才是可靠的

只要记住一点,要在实际演变中注意观察变化点,把变化点封装起来就能够了面向对象:封装变化,抽象共同点

相关文章
相关标签/搜索