你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

c语言中的策略模式

[复制链接]
gaosmile 发布时间:2020-5-29 12:14
前言+

1 n+ M9 b9 I( K$ C" g
这里先插一点题外话,在C语言中,实现封装、继承、隐藏、多态等等特性,是完全没有问题的。但是在使用过程中,必定是不如自带这些特性的语言方便好用的,比如C++\java等。7 ?5 l8 w2 \: E
一旦要通过C语言来实现各种设计模式,必定会在严谨地维护类层次上造成非常繁琐和臃肿的代码。这是因为C++/java等自带一套面向对象的工具,而C语言要在代码设计中,不断地根据实际情况来创造面向对象的工具。
因此对于文章的内容,请大家主要关注、体会设计模式本身,更多地去考虑程序的可扩展性和可维护性。
文章本身是希望向C语言爱好者普及设计模式的知识,在所有的程序设计中,本意都是尽可能地简单易懂。因此抛开设计模式的本意去讨论程序的代码实现优劣,是没有任何意义的。之前发表的c语言面向对象系列文章确实参考了网上很多资料和书籍,也借鉴了其中一些案例。但是代码确实是自己完整实现的,并复制粘贴在菜鸟 C 在线工具进行验证了(http://c.runoob.com/compile/11)。今后类似借鉴、抄袭等等话题不想再次和大家争论,容易伤和气。毕竟只是希望大家能从我的文章有所收获而已,不喜欢直接左上角关闭就好。
鉴于之前有部分读者过于关注程序本身的功能性,更有甚者仅因为某一两方面见解不同就口出恶言。唯恐这样下去只会把技术的圈子搞臭。因此以后的c语言设计模式将不再给出具体实现,只讲解模式动机和设计思路。
希望大家可以针对设计模式方面给文章提出一些改进的建议,本人可以保证,对于无恶意、有针对性的建议,一定会吸收接纳、及时改正。
接下来是文章的正文部分。
模式动机
完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务。
在软件开发中也常常遇到类似的情况,实现某一个功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,也能够方便地增加新的解决途径。
简单来说,策略模式就是用统一的方法接口分别对不同类型的数据进行访问。
场景案例
场景:现在我们想用pc看一部电影,但是影片本身有多种播放格式。比如rmvb要rmvb格式的方法,avi要avi的方法,mpeg要mpeg的方法。
传统代码实现
...& p/ m6 V" T" ?; H) P
void main()  O3 f+ H& g  [
{
/ p: `$ I& ~5 Q; N( Y/ R...& A8 r) u+ D! C; s$ C3 F2 T5 ^$ O
if (movie == avi)
$ ^) X" U0 v# P% f8 {{9 L2 F, I: {+ o2 I9 a3 R
    ...//avi影片的播放策略$ |9 U- A- p( B7 u
}3 V; F2 O0 R) n# F1 E5 Z% o7 C7 U
else if (movie == rmvb)
2 i  K( L, A- V$ d{
9 a1 E  Z' n% }    ...//rmvb影片的播放策略* s$ ^( ^/ @: |4 [4 Y* Q/ Z) S: X$ Y
}
4 d' E7 S5 B9 A' ]* B9 t  a) T% Celse if8 J$ J$ T3 x6 [! _
...8 m1 H$ @$ c' B- D) x3 D0 E% R
}
7 {" \9 u2 M, V0 d
在上面的代码实现中,把所有的功能代码全部集中在一个函数里面完成了,随着分支的扩展,整个函数会越来越臃肿,非常难以维护。我们应该把每个分枝的实现抽离出来,封装在函数里面实现。
改进代码实现1:
...
  r1 K: i2 E; q6 A" z1 a5 Gvoid main()
6 V" T; |7 V2 R2 l- x8 k{
4 }, s! Y7 X4 {# H7 Tif (movie == avi)
. Z/ e9 T3 R6 }  p" U{
; c- u3 b5 X% o; O   play_avi_movie();//avi影片的播放策略' a% l( a8 d( Y6 p7 t
}
+ `) \- j( y) ]/ telse if (movie == rmvb)
* o$ |/ V5 D" L' Y- G: q. S/ B{1 M; ?2 b9 u3 _) F, a% i6 |2 |
   play_rmvb_movie();//rmvb影片的播放策略
/ l1 X+ v2 r$ x* m" X+ z}
) X* [/ H  L$ d/ ~7 F1 ?else if0 d# `  S8 o, k$ t$ F
...
1 \( i' W* y3 H}
# O. D2 F% E# ^" t# b1 g+ z
在上面的代码实现中,我们通过把分支代码封装起来,减少了主函数的复杂性。但是从更高的一层的抽象看,主函数其实不关心各种分支情况。它希望的是,在进行必要的配置工作以后,直接调用某一个函数接口就能完成功能。
因此,我们应该把各个分支函数抽离出来,统一用某个函数接口来表示。只要在程序中进行完配置工作以后,那么主函数接下来就能直接调用该函数接口。
改进代码实现2:
void (*play_movie)();
/ z7 j$ v! z$ G( p7 s% \! b4 t: y" Z4 M3 ]  k  h( z! F% A
void set_movie(char movie)3 x* A: f8 ]4 u" H' L; X
{, J. b& ]3 q5 y4 `' v0 H: U
  if(movie == avi)
) h- |7 ?! ~/ v5 [  {
% Q& ?  k4 R9 Q( h    play_movie = play_avi_movie;
  O/ ^2 ]4 J0 i5 c+ T  }" ]: N2 f3 j) ^. S* I
  else if(movie == rmvb)
% B. x1 ~, Q+ |  {
' a+ Y; r0 T1 o) i4 C2 f    play_movie = play_rmvb_movie;) O$ z7 p' G% W# P) Z: I
  }
; T3 E4 Y8 A6 M  else if  i3 F- f5 [0 e+ ], C
  ...
9 s& R7 D. z* [8 |( R}" a& P/ E: S6 F' b9 _9 Q

! U7 Y9 W6 s. ^4 ~* dvoid main(); _3 v, G/ ~4 U
{  r- {9 M; |; l9 q" K
...7 L$ }+ u2 V  o: V
set_movie();9 f: B6 q5 ~# h; {
...9 ^% a) Z6 {4 x- s/ @5 s% i
play_movie();4 M; P) ^% |* o& T* h( T2 k' b
...  F+ v9 q; d  R# u/ p
}

" j% w$ y( ^5 P' j# q9 M! X
这就是c语言中的策略模式,重点在于分离各个分支的实现函数,主程序只需要通过唯一的接口,就能完成相应功能,提高了程序的可维护性和扩展性。
" y" d0 {5 D" l, D+ w- f
赞 收藏 评论0 发布时间:2020-5-29 12:14

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版