Table-Driven Design 表驱动设计
注:本文所有代码来自 http://www.codeproject.com/Articles/42732/Table-driven-Approach
在许多程序中,经常需要处理那些拥有种种色色不同特性的实体,最直接的思路是用case语句或者if-else语句处理这些不同的实体。然而,如果这类实体的数量若足够庞大,将会产生大量代码,臃肿并难以整理和维护。
先通过一对实例感受一下:
// A text adventure game
if(strcmpi(command, "north") == ) {
if(cur_location->north)
GoToLocation(cur_location->north);
else
Print("Cannot go there");
}
else if(strcmpi(command, "east") == ) {
if(cur_location->east)
GoToLocation(cur_location->east);
else
Print("Cannot go there");
}
else if(strcmpi(command, "south") == ) {
if(cur_location->south)
GoToLocation(cur_location->south);
else
Print("Cannot go there");
}
else if(strcmpi(command, "west") == ) {
if(cur_location->west)
GoToLocation(cur_location->west);
else
Print("Cannot go there");
}
相同功能的其他代码:
enum SIDE {SIDE_NORTH = , SIDE_EAST, SIDE_SOUTH, SIDE_WEST};
struct COMMAND {
const char * name;
SIDE side;
};
static const COMMAND commands[] = {
{"north", SIDE_NORTH},
{"east", SIDE_EAST},
{"south", SIDE_SOUTH},
{"west", SIDE_WEST},
};
for(int i = ; i < NUM_OF(commands); i++)
if(strcmpi(commands[i].name, command) == ) {
SIDE d = commands[i].side;
if(cur_location->sides[d])
GoToLocation(cur_location->sides[d]);
else
Print("Cannot go there");
}
从上面两段代码我们可以看出,第二段将实体从条件语句中分离出来,使得程序框架更加清晰;为了增加command names,现在只需要在一处修改代码。当数据量足够大时,可以分很方便地增添、删减或者替换,非常有利于维护。
正式定义前,再用一对代码来加强理解。(举例来自书籍《Refactoring》,Martin Fowler)
// calculating the price for renting a movie
double result = ;
switch(movieType) {
case Movie.REGULAR:
result += ;
if(daysRented > )
result += (daysRented - ) * 1.5;
break; case Movie.NEW_RELEASE:
result += daysRented * ;
break; case Movie.CHILDRENS:
result += 1.5;
if(daysRented > )
result += (daysRented - ) * 1.5;
break;
}
使用数组后的优化解决方案:
enum MovieType {Regular = , NewRelease = , Childrens = };
// Regular NewRelease Childrens
const double initialCharge[] = {, , 1.5};
const double initialDays[] = {, , };
const double multiplier[] = {1.5, , 1.5};
double price = initialCharge[movie_type];
if(daysRented > initialDays[movie_type])
price += (daysRented - initialDays[movie_type]) * multiplier[movie_type];
以上举例能非常明显的展现出表驱动设计的优点:Table-Driven代码更快、更短、更容易维护!
如果使用表驱动来整理在之前博客中写到的迷宫问题,代码最少可以简短200行!学到的太晚了!
在此给出Table-Driven Design定义:
表驱动设计是软件开发工程中的一种方法,通过从程序代码中分离的控制变量以及参数并将其存储在外部表格中的处理来简化、概括程序。主要目的在于将控制变量从程序逻辑中脱离以及着重于构建程序的模块化框架,来减轻因变更数据产生的管理工作量。
人类是智慧的,代码是伟大的!如同现实世界一样,计算机世界也有着太多东西值得我们去探索和发现!
加油吧!少年们!
大三上
2016/11/15 上午
Table-Driven Design 表驱动设计的更多相关文章
- DDD(Domain-Driven Design) 领域驱动设计
DDD(Domain-Driven Design) 领域驱动设计 1. DDD(Domain-Driven Design)是什么? DDD是Eric Evans在2003年出版的<领域驱动设计: ...
- csharp: Domain-Driven Design(领域驱动设计)
http://dddsample.sourceforge.net/ https://github.com/citerus/dddsample-core http://dddsamplenet.code ...
- (翻译)领域驱动设计实现-Implementing Domain Driven Design
简介 Implementing Domain Driven Design 领域驱动设计实现 A practical guide for implementing the Domain Driven D ...
- 领域驱动设计(DDD:Domain-Driven Design) 介绍
Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...
- 领域驱动设计(DDD:Domain-Driven Design) 转摘自:http://www.jdon.com/ddd.html
Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...
- 领域驱动设计(DDD:Domain-Driven Design)
领域驱动设计(DDD:Domain-Driven Design) Eric Evans的"Domain-Driven Design领域驱动设计"简称DDD,Evans DDD是一套 ...
- 领域驱动设计(DDD)实践之路(一)
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/gk-Hb84Dt7JqBRVkMqM7Eg 作者:张文博 领域驱动设计(Domain Dr ...
- DDD领域驱动设计落地实践(十分钟看完,半小时落地)
一.引子 不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野.该思想源于2003年 Eric Evans编写的"Domain-Driven Design领域驱动设计"简称DDD ...
- Java开发架构篇《初识领域驱动设计DDD落地》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 DDD(Domain-Driven Design 领域驱动设计)是由Eric Eva ...
随机推荐
- 状压dp2
2018年全国多校算法寒假训练营练习比赛(第二场) https://www.nowcoder.com/acm/contest/74/F 上一篇状压dp例题由于每个位置都含有一个非负数,所以不需要判断能 ...
- hdu 5182 结构体排序
BC # 32 : 打 BC 的时候没看全三个关键字,WA 了五发,花了近一小时,问了一下才发现少看一个条件,于是顺利给跪. 题意:给出若干城市的两次空气质量,首先按空气质量差排序,若相等则按第二次排 ...
- mysql 常用linux命令
★ 数据导出命令 D:\Program Files\MySQL\MySQL Server 5.6.39\bin 导出: mysqldump -u root -p cela_sub > D:/d ...
- 实习第二天-java参数传递-精华在文章最后2句话
对于基本类型的传递,我们很容易理解,而对于对象,总让人感觉是按引用传递,看下面的程序: public class ObjectRef { //基本类型的参数传递 public static void ...
- smarty学习——变量
变量的处理对于模板来说是比较重要的. Smarty有几种不同类型的变量. 变量 的类型取决于它的前缀是什么符号(或者被什么符号包围) Smarty的变量可以直接被输出或者作为函数属性和修饰符(modi ...
- hadoop 配置文件简析
文件名称 格式 描述 hadoop-env.sh bash脚本 记录hadoop要用的环境变量 core- ...
- 添加mysamba
一. 复制/home/tingpan/openwrt/barrier_breaker/feeds/luci/applications文件夹下的luci-samba文件,将文件中的内容samba改为my ...
- sql 防注入 维基百科
http://zh.wikipedia.org/wiki/SQL%E8%B3%87%E6%96%99%E9%9A%B1%E7%A2%BC%E6%94%BB%E6%93%8A SQL攻击(SQL inj ...
- git: fatal: Could not read from remote repository
This is probably an Intellij problem. Your key are managed natively by ssh, and Intellij has it's ow ...
- bzoj4236 JOIJOI
Description JOIOJI桑是JOI君的叔叔.“JOIOJI”这个名字是由“J.O.I”三个字母各两个构成的. 最近,JOIOJI桑有了一个孩子.JOIOJI桑想让自己孩子的名字和自己一样由 ...