前言
这里先插一点题外话,在C语言中,实现封装、继承、隐藏、多态等等特性,是完全没有问题的。但是在使用过程中,必定是不如自带这些特性的语言方便好用的,比如C \java等。
一旦要通过C语言来实现各种设计模式,必定会在严谨地维护类层次上造成非常繁琐和臃肿的代码。这是因为C /java等自带一套面向对象的工具,而C语言要在代码设计中,不断地根据实际情况来创造面向对象的工具。
因此对于文章的内容,请大家主要关注、体会设计模式本身,更多地去考虑程序的可扩展性和可维护性。
文章本身是希望向C语言爱好者普及设计模式的知识,在所有的程序设计中,本意都是尽可能地简单易懂。因此抛开设计模式的本意去讨论程序的代码实现优劣,是没有任何意义的。
希望大家可以针对设计模式方面给文章提出一些改进的建议,本人可以保证,对于无恶意、有针对性的建议,一定会吸收接纳、及时改正。
接下来是文章的正文部分。
模式动机
完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务。
在软件开发中也常常遇到类似的情况,实现某一个功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,也能够方便地增加新的解决途径。
简单来说,策略模式就是用统一的方法接口分别对不同类型的数据进行访问。
场景案例
场景:现在我们想用pc看一部电影,但是影片本身有多种播放格式。比如rmvb要rmvb格式的方法,avi要avi的方法,mpeg要mpeg的方法。
传统代码实现
...
void main()
{
...
if (movie == avi)
{..._/avi影片的播放策略
}
else if (movie == rmvb)
{..._/rmvb影片的播放策略
}
else if
...
}
在上面的代码实现中,把所有的功能代码全部集中在一个函数里面完成了,随着分支的扩展,整个函数会越来越臃肿,非常难以维护。我们应该把每个分枝的实现抽离出来,封装在函数里面实现。
改进代码实现1:
...
void main()
{
if (movie == avi)
{play_avi_movie();//avi影片的播放策略
}
else if (movie == rmvb)
{play_rmvb_movie();//rmvb影片的播放策略
}
else if
...
}
在上面的代码实现中,我们通过把分支代码封装起来,减少了主函数的复杂性。但是从更高的一层的抽象看,主函数其实不关心各种分支情况。它希望的是,在进行必要的配置工作以后,直接调用某一个函数接口就能完成功能。
因此,我们应该把各个分支函数抽离出来,统一用某个函数接口来表示。只要在程序中进行完配置工作以后,那么主函数接下来就能直接调用该函数接口。
改进代码实现2:
void (*play_movie)();void set_movie(char movie)
{if(movie == avi){play_movie = play_avi_movie;}else if(movie == rmvb){play_movie = play_rmvb_movie;}else if...
}void main()
{
...
set_movie();
...
play_movie();
...
}
这就是c语言中的策略模式,重点在于分离各个分支的实现函数,主程序只需要通过唯一的接口,就能完成相应功能,提高了程序的可维护性和扩展性。
声明:
本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。