`
edison0663
  • 浏览: 78936 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

装饰模式随笔

阅读更多

上周看代码的时候,看到一坨shit(其实shit很多,我自己也经常写出Shit)如果由自己来想,如何写出优雅的代码呢?

 

 

场景: 初步请求其实再简单不过, 就是一个经典的 请求处理接口

 

          int Handle( Buffer * ptBuffReq, Buffer * ptBuffResp )

 

          网络层将请求包收到后(验证请求包正确后), 将请求包的内容,交给Handle去处理。

 

          Handle 的处理流程: A版本

          1 从ptBufferReq 反序列化出具体结构体stReq;

          2 具体逻辑处理, 处理结果stReq;

          3 序列化 stResp 到ptBufferResp;

 

          代码在这个时候还是很清晰,并且层次分明的。

 

需求变更:需要在原有的逻辑处理,希望打印所有的请求类型 stReq.type及其他参数 到日志中。

 

          于是Handle的处理流程:

          1 从ptBufferReq 反序列化出具体结构体stReq;

          2 (插入代码Log(stReq.type)) 具体逻辑处理, 处理结果stReq;

          3 序列化 stResp 到ptBufferResp;

 

需求再变更: 请求量大,日志开销较大,对请求进行抽样大

 

           继续在Handle 这个接口中 加入  if( 抽样范围 ) Log 的代码。

 

需求变更持续ing:  异步分析请求合法性功能, 染色Log(一旦被染色中都打log), 开关这些后续添加的功能。

 

           Handle的代码终于 shit 一般了。虽然勉强可读,确实已经 很恶心了。

 

这种场景,我们描述为: 接口职责不变,接口 功能增加,且要求功能能灵活组合,开关

装饰模式在这种场景下,非常适用: 不改变其接口职责,动态组合增加的功能

 

如何做呢?

           class VHandle 纯虚函数 Handle;

 

具体子类 class HandleImpl  Handle 实现 A版本的 流程。

 

抽象插件子类 class HandlePlugin 其构造函数要求传入 一个VHandle的指针. Handle() 实现是m_ptVHanlde->Handle(), 再回调一个纯虚函数, PluginHandle();

 

具体插件子类 AsyncAnalyseHandle, StatLogHandle 继承 HandlePlush.  并在PluginHandle实现自己的具体逻辑z。

 

具体类图如:

 

     

 

     现在这堆代码已经很灵活了,可以根据配置文件达成各种组装。

     比如: VHandle * ptHandle = new HandleImpl();

               VHandle * ptHandlePlugedAsyncAnalyse = new AsyncAnalyseHandle( ptHandle );

               VHandle * ptHandlePlugedAll = new StatLogHandle( ptHandlePlugedAsyncAnalyse );

 

 

     ShowCase 就到这了。 还有各种非常优雅的应用, 装饰模式非常好用,顶一个。

 

 

  • 大小: 65.4 KB
1
8
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics