:本文所有代码来自 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. Python编码——常见的编码设置

    1.查看自己电脑的python的编码设置 # -*- coding: utf8 -*- import sys, locale """ locale.getpreferre ...

  2. jQuery插件制作方法详解

        jQuery插件制作方法详解   jquery插件给我的感觉清一色的清洁,简单.如Jtip,要使用它的功能,只需要在你的元素的class上加 上Jtip,并引入jtip.js及其样式即可以了. ...

  3. 防范SQL注入漏洞攻击

    原理:通过拼sql语句,在输入框里输入' ; SHOW TABLES;注入这样的代码, 防范:你把全部的特殊符号都过滤掉(如单引号,双引号),自然就不会被注入 使用mysql_real_escape_ ...

  4. 【转】每天一个linux命令(3):pwd命令

    原文网址:http://www.cnblogs.com/peida/archive/2012/10/24/2737730.html Linux中用 pwd 命令来查看”当前工作目录“的完整路径. 简单 ...

  5. .csv 和 .xls 的区别

    .csv 和 .xls 的区别 .csv .xls 较为通用,易导入至各式表格.资料库等 Microsoft excel的专用档案 文本档案,用记事本就可以打开 二进位档案,只有用excel才能打开 ...

  6. netty异步

    通俗理解:http://lingnanlu.github.io/2016/08/16/netty-asyc-callback 异步的小demo:https://blog.csdn.net/coder_ ...

  7. webpack 基本使用

    1. 创建webpack-test文件夹 2. npm初始化 3. 安装webpack 4. 使用webpack打包 hello.js 是需要打包的文件  hello.bundle.js 是打包完以后 ...

  8. js的模块化规范

    js的模块化规范常见的有:AMD,CMD,commonJS,UMD,es6 前期在没有模块化的时候,js文件十分庞大,于是就按功能抽离划分为多个js文件. 但是在html页面通过script的方式加载 ...

  9. Microsoft Dynamics CRM 4.0导入组织(Import Organization)时间过长的原因总结

    952934    How to move the Microsoft Dynamics CRM 4.0 deployment http://support.microsoft.com/default ...

  10. wsdl详解

    <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http:// ...