:本文所有代码来自 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 表驱动设计的更多相关文章

  1. DDD(Domain-Driven Design) 领域驱动设计

    DDD(Domain-Driven Design) 领域驱动设计 1. DDD(Domain-Driven Design)是什么? DDD是Eric Evans在2003年出版的<领域驱动设计: ...

  2. csharp: Domain-Driven Design(领域驱动设计)

    http://dddsample.sourceforge.net/ https://github.com/citerus/dddsample-core http://dddsamplenet.code ...

  3. (翻译)领域驱动设计实现-Implementing Domain Driven Design

    简介 Implementing Domain Driven Design 领域驱动设计实现 A practical guide for implementing the Domain Driven D ...

  4. 领域驱动设计(DDD:Domain-Driven Design) 介绍

    Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...

  5. 领域驱动设计(DDD:Domain-Driven Design) 转摘自:http://www.jdon.com/ddd.html

    Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...

  6. 领域驱动设计(DDD:Domain-Driven Design)

    领域驱动设计(DDD:Domain-Driven Design) Eric Evans的"Domain-Driven Design领域驱动设计"简称DDD,Evans DDD是一套 ...

  7. 领域驱动设计(DDD)实践之路(一)

    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/gk-Hb84Dt7JqBRVkMqM7Eg  作者:张文博 领域驱动设计(Domain Dr ...

  8. DDD领域驱动设计落地实践(十分钟看完,半小时落地)

    一.引子 不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野.该思想源于2003年 Eric Evans编写的"Domain-Driven Design领域驱动设计"简称DDD ...

  9. Java开发架构篇《初识领域驱动设计DDD落地》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 DDD(Domain-Driven Design 领域驱动设计)是由Eric Eva ...

随机推荐

  1. HTML图片热区map area的用法

    <area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: < ...

  2. SQL 存储过程入门(五)

    好久没来博客园留下点东西,忙到找工作,最近把工作落实了. 最近公司的业务都是存储过程开发,发现去维护起来相当困难. 由于是维护项目,产品很久前都发布了,然而有一些修改,让我们去修改现在的逻辑,去看懂人 ...

  3. binlog cache size设置是否合理判断

    二进制日志是写操作是,首先写入二进制日志缓冲(binlog_cache)然后commit,再从binlog_cache写入到binlog文件,默认大小为32K,而binlog_cache是sessio ...

  4. 针对 FastAdmin 2018-01-19 号的升级 SQL (废)

    FastAdmin 在 2018-01-19 升级增加了以下功能. 新增前台会员模块和API会员模块 新增后台会员管理.会员规则和会员分组管理 新增短信发送的行为事件 新增前台Token.短信.日志模 ...

  5. 2019第1周日-MQ选型要点

    用消息中间件犹如小马过河,选择合适的才最重要,这需要贴合自身的业务需求,技术服务于业务.具体在选择上可从下面功能.性能.可靠性和可用性.运维管理.社区和生态.团队技术栈等维度来进行筛选. 具体技术选型 ...

  6. 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境

    1.资源准备 最近,在VmwareStation 10虚拟机上,基于CentOS5.4安装Oracle 11g RAC,并把过程记录下来.刚开始时,是基于CentOS 6.4安装Oracle 11g ...

  7. php curl伪造来源ip和refer实例代码

    php curl伪造来源ip和来路refer实例代码1: //随机IP function Rand_IP(){ $ip2id= round(rand(600000, 2550000) / 10000) ...

  8. Spring Cloud 入门 之 Hystrix 篇(四)

    原文地址:Spring Cloud 入门 之 Hystrix 篇(四) 博客地址:http://www.extlight.com 一.前言 在微服务应用中,服务存在一定的依赖关系,如果某个目标服务调用 ...

  9. 【数据库】Eclipse连接MySQL数据库

    我的环境:MySQL:mysql-essential-5.1.51-win32 jdbc驱动:我已经上传到csdn上一个:http://download.csdn.net/detail/paulwin ...

  10. CentOS6.5 搭建在线yum源

    CentOS6.5 搭建在线yum源 发布时间:  2017-04-21 浏览次数:  611 下载次数:  1  问题描述 尽管有很多的免费镜像提供yum源服务,但是还是有必要建立自己的yum服务器 ...