關於"短信處理"模式的一段討論

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

哦,那就是沒有,採用什麼模式,提早設計實際上並不可靠,要在實際中重構到模式纔是可靠的

只要記住一點,要在實際演變中注意觀察變化點,把變化點封裝起來就能夠了面向對象:封裝變化,抽象共同點

相關文章
相關標籤/搜索