[设计模式] 设计原则

来源:互联网 发布:java 函数 和类 编辑:程序博客网 时间:2024/06/11 17:28

前言:学习设计模式,不仅仅在OO语言中使用,还要考虑其在C语言中实施的方式,

         打破语言和环境的藩篱。

 

基本的设计原则包括:

1. 封装变化

2. 针对接口编程,而不是针对实现编程

 

*封装变化的好处有:

有利于实现代码的最小改动和最少编译

有利于代码重构和优化

 

例如《深入浅出设计模式》中,每种duck的行为细节各有不同,有的会飞,

有的不会,发声也不尽相同,如果都放到duck类中,继承和重新实现的工作

量很大。而且不是鸭子,也有能飞的。所以,按照封装变化原则,行为类应该

独立于Duck类进行设计。Duck类可以委托行为类处理行为相关的事务。

 

当有新一种类型的Duck出现时,我们只需要extends一个新的duck类文件,如果

有未知行为,再多实现一个接口行为类文件。别的文件无需改动。

 

思考:如果用C去设计和实现Duck,如何达到最小改动和隔离?

 

//模拟Duck类

typedef struct _Duck
{
char name[MAX_NAME_SIZE];
pfnSwim swim;
pfnFlyBehavior flyBehavior;
pfnQuackBehavior quackBehavior;
pfnDisplay display;
}Duck;

 

//创建Duck实例

static Duck *createDuck(char *name,
                        int nameLen,
                        pfnSwim swimFunc,
                        pfnFlyBehavior flyFunc,
                        pfnQuackBehavior quackFunc,
                        pfnDisplay displayFunc);

 

//Duck行为对应的函数

void defaultSwim(void);
void defaultDisplay(void);
void flyWithWings(void);
void flyNoWay(void);
void flyRocketPower(void);
void quackNosound(void);
void normalQuack(void);
void normalQuack1(void);

 

将duck基本属性定义到Duck结构中,duck行为定义为函数指针,

在创建时初始化。每个行为定义为一个函数接口。

 

问:和一般做法相比,会有什么好处呢?

答:减少了代码总量,易于扩展新的行为。

      鸭子的行为可以单独定义到一个文件中。

      如果不用回调,直接调用行为,也不是不可以,比较分散。

      这样模拟OO,代码更容易理解。

 

BTW, Brew中使用的接口, 也是一种有效的方式来隔离变化. 例如创建一组行为

接口, IBehavior, 通过调用IBehavior_Fly(...), IBehavior_Quake(...)的方式,

效果也一样, IBehavior指针可以定义到Duck类中. 和上面的实现相比, 好处是,

不会因为Duck行为的不断增加而在结构中添加更多的回调函数指针.

 

*针对接口编程,又称之为针对超类型编程。

按照上述C代码思路,实际上已经针对接口编程。

 

原创粉丝点击