利用函数指针实现高内聚、低耦合
2011-08-29 18:59
281 查看
作为c的初学者,如果写一个求四边形的周长的函数的话,我倾向于像下面这样书写:
//计算四边形的周长
#include <stdio.h>
#define RECTANGLE 0 //长方形
#define SQUARE 1 //正方形
//多边形
struct polygon{
int type;
int length;
int width;
};
int get_circumference(struct polygon pygn)
{
if(pygn.type == RECTANGLE)
{
return 2 * (pygn.length + pygn.width);
}
else if(pygn.type == SQUARE)
{
return 4 * pygn.width;
}
else
{
//todo
}
}
int main(void)
{
struct polygon pygn_rec, pygn_squ;
pygn_rec.type = RECTANGLE;
pygn_rec.width = 6;
pygn_rec.length = 10;
pygn_squ.type = SQUARE;
pygn_squ.width = 6;
printf("get cir rec is: %d\n", get_circumference(pygn_rec));
printf("get cir squ is: %d\n", get_circumference(pygn_squ));
return 0;
}
今天,看了<linux c编程一站式学习>的“函数类型和函数指针”(http://learn.akae.cn/media/ch23s08.html)后,又学到了一种更好的方式:
//计算四边形的周长
#include <stdio.h>
#define RECTANGLE 0 //长方形
#define SQUARE 1 //正方形
//多边形
struct polygon{
int type;
int length;
int width;
};
int get_rectangle_cir(struct polygon pygn)
{
return 2 * (pygn.length + pygn.width);
}
int get_square_cir(struct polygon pygn)
{
return 4 * pygn.width;
}
int (* get_circumference[])(struct polygon pygn) = {get_rectangle_cir, get_square_cir};
#define get_cir(pygn) get_circumference[pygn.type](pygn)
int main(void)
{
struct polygon pygn_rec, pygn_squ;
pygn_rec.type = RECTANGLE;
pygn_rec.width = 6;
pygn_rec.length = 10;
pygn_squ.type = SQUARE;
pygn_squ.width = 6;
printf("get cir rec is: %d\n", get_cir(pygn_rec));
printf("get cir squ is: %d\n", get_cir(pygn_squ));
return 0;
}
当调用get_cir(pygn)时,用类型字段pygn.type做索引,从指针数组get_circumference中取出相应的函数指针来调用,
也可以达到if ... else ...的效果,但相比之下这种实现更好,每个函数都只做一件事情,
而不必用if ... else ...兼顾好几件事情,比如get_rectangle_cir和get_square_cir各做各的,
互相独立,而不必把它们的代码都耦合到一个函数中。
“低耦合,高内聚”(Low Coupling, High Cohesion)是程序设计的一条基本原则,
这样可以更好地复用现有代码,使代码更容易维护。如果类型字段pygn.type又多了一种取值,
只需要添加一组新的函数,修改函数指针数组,原有的函数仍然可以不加改动地复用。
//计算四边形的周长
#include <stdio.h>
#define RECTANGLE 0 //长方形
#define SQUARE 1 //正方形
//多边形
struct polygon{
int type;
int length;
int width;
};
int get_circumference(struct polygon pygn)
{
if(pygn.type == RECTANGLE)
{
return 2 * (pygn.length + pygn.width);
}
else if(pygn.type == SQUARE)
{
return 4 * pygn.width;
}
else
{
//todo
}
}
int main(void)
{
struct polygon pygn_rec, pygn_squ;
pygn_rec.type = RECTANGLE;
pygn_rec.width = 6;
pygn_rec.length = 10;
pygn_squ.type = SQUARE;
pygn_squ.width = 6;
printf("get cir rec is: %d\n", get_circumference(pygn_rec));
printf("get cir squ is: %d\n", get_circumference(pygn_squ));
return 0;
}
今天,看了<linux c编程一站式学习>的“函数类型和函数指针”(http://learn.akae.cn/media/ch23s08.html)后,又学到了一种更好的方式:
//计算四边形的周长
#include <stdio.h>
#define RECTANGLE 0 //长方形
#define SQUARE 1 //正方形
//多边形
struct polygon{
int type;
int length;
int width;
};
int get_rectangle_cir(struct polygon pygn)
{
return 2 * (pygn.length + pygn.width);
}
int get_square_cir(struct polygon pygn)
{
return 4 * pygn.width;
}
int (* get_circumference[])(struct polygon pygn) = {get_rectangle_cir, get_square_cir};
#define get_cir(pygn) get_circumference[pygn.type](pygn)
int main(void)
{
struct polygon pygn_rec, pygn_squ;
pygn_rec.type = RECTANGLE;
pygn_rec.width = 6;
pygn_rec.length = 10;
pygn_squ.type = SQUARE;
pygn_squ.width = 6;
printf("get cir rec is: %d\n", get_cir(pygn_rec));
printf("get cir squ is: %d\n", get_cir(pygn_squ));
return 0;
}
当调用get_cir(pygn)时,用类型字段pygn.type做索引,从指针数组get_circumference中取出相应的函数指针来调用,
也可以达到if ... else ...的效果,但相比之下这种实现更好,每个函数都只做一件事情,
而不必用if ... else ...兼顾好几件事情,比如get_rectangle_cir和get_square_cir各做各的,
互相独立,而不必把它们的代码都耦合到一个函数中。
“低耦合,高内聚”(Low Coupling, High Cohesion)是程序设计的一条基本原则,
这样可以更好地复用现有代码,使代码更容易维护。如果类型字段pygn.type又多了一种取值,
只需要添加一组新的函数,修改函数指针数组,原有的函数仍然可以不加改动地复用。
相关文章推荐
- 高内聚与低耦合实现小记
- 利用函数指针实现父类函数调用子类函数
- 利用函数指针实现多级排序
- 利用C语言中的函数指针实现c++中的虚函数
- 本文是笔者根据数据库编程经验,利用C++语言的模板、继承、授权、多态等面向对象特性,借鉴命令模式,实现了对象在关系数据中的存储,降低应用系统与数据库之间的耦合,提高开发效率。
- 利用ODI实现SOA中业务流和数据流的松耦合
- Angular2 ElementRef 实现低耦合高内聚 视图应用分离
- 利用函数指针实现动态库的动态调用——函数指针正向调用法
- 利用动态创建自动化接口实现VB的函数指针调用
- 利用动态创建自动化接口实现VB的函数指针调用
- 利用ODI实现SOA中业务流和数据流的松耦合
- 介绍一下我利用Url重写实现的松耦合框架
- 利用Visual C++实现系统托盘程序(2)
- 利用ST提供的USB例程实现USB IAP功能
- 利用inotify和rsync实现数据同步
- Android利用云盘实现手机上传功能
- spring boot 项目利用Jenkins实现自动化部署的教程详解
- Server 2012之利用DFS实现资源共享的高可用
- golang利用组合实现继承