C常用设计模式——策略模式

写之前说几句话。

用C语言写代码的同学看到“设计模式”不要敬而远之,借“设计模式是面向对象的语言才需要关心的东西”之名,行偷懒之实。学习设计模式,学的是设计模式里的设计思想,学习它以怎样的角度切入来实现低耦合。

C常用设计模式系列,我会以C语言常用的概念来描述这些设计模式。

本篇讲策略模式。

如图所示,C代码是过程式的,可以用“框架流程”一以贯之的,在某一个处理流程的结点处,有一个策略A代码。某一天来了一个需求,说想增加一种策略B,通过开关来控制。程序员小宋江说so easy,写了代码如下:

...
if (strategy == A)
{
    ...//一堆策略A处理代码
}
else
{
    ...//一堆策略B处理代码
}
...

程序员小李逵说:“哥哥啊,你这代码很难懂啊,我看完策略A的处理,忽然看到else,我忘了跟else并列的if是干啥的了”。

小宋江脸一红说,“你个憨货,你懂啥,来来看我改改”

...
if (strategy == A)
{
    ProcStrategyA();
}
else
{
    ProcStaregyB();
}
...

小李逵一看,“哟哥哥欸,这个不错,做了函数封装逻辑真清晰,连注释都省了”。

小宋江很受用。这个时候新员工小史进过来了,小史进一脸愁容,“二位哥哥,我们的这代码真的太难懂了,刚刚听负责质量度量的小公孙胜同学说,咱们的条件分支已经1w个了,这么复杂我们新员工学得很痛苦呀,二位哥哥我们有没有办法别在核心业务逻辑里加这么多的if判断?”小宋江摇了摇头。小李逵想,作为在团队干了很多年的小宝玉一定知道,这一问,没想到小宝玉说出这么一句话来,“研究那劳什子玩意做什么,也没见隔壁如花似玉的小林姑娘研究这玩意”。吐槽归吐槽,小宝玉还是认真地讲起来,“分析题目,这个软件是有两个相对独立的过程的,一个是这个开关配置过程,一个是软件一般运行过程,我们一般把后者叫核心模块。不想在核心模块增加圈复杂度也简单,那就把if判断放在开关配置过程里处理嘛,来来,这位哥哥把笔拿来”。

//开关配置过程
typedef void (*ProcStrategy)();
ProcStrategy procStrategy;
if (strategy == A)
{
    procStrategy = ProcStrategyA;
}
else
{
    procStrategy = ProcStaregyB;
}

//核心逻辑处理过程
...
procStrategy();
...

小宝玉道:“喏你看,核心处理里没有增加if了吧?”

小李逵道:“神了,那个 procStrategy 怎么还能当函数用?”。一边的小宋江忍不住了,“函数名不就是个地址嘛,把这个地址存下来的变量当然能当函数用了!”。小李逵似懂非懂不敢吭声了,但小史进问了,“这这这,这么复杂!我在我们代码里见过这样的,这都不能用F3一直看代码,还得过一会儿就找一下变量赋值的地方,难看死了”,小宝玉接话:“就是,隔壁小薛妹妹也不这么写代码,我们要这劳什子做什么。”坐在旁边办公的小贾政终于发话了:“你怎么老拿小林姑娘和小薛妹妹的代码跟小宋他们比,小宋他们条件分支有1w,小林他们才300,你要只有30个条件分支你连函数都不用封装我都能记住所有逻辑!还有小史进,看代码不方便,那要看你怎么看了,你要专注于框架流程,你就不要来回跳转,你要专注于两种策略具体的内容,那你就看两处具体的处理函数就行了,这叫关注点分离懂不懂,设计模式里这叫策略模式”。

小李逵:“奥,这就是策略模式啊”!

隔壁的小诸葛亮说,这个跟《设计模式》里说的不一样啊。确实不一样,也没必要一样,C语言有自己的思维模式,我们学习到其中怎样分离了关注点也就可以了,实现成与C++一模一样的形式也就落了无意义的炫技的窠臼。

一些概念我们统一一下:我们把 procStrategy 叫做接口,把 ProcStrategyA 叫做实现。

总结一下策略模式的要点。在软件配置阶段,根据开关状态的不同,我们给一个接口赋一个具体实现,在软件运行阶段,仅调用接口。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值