函数的命令和查询分裂

选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。

函数的命令和查询分裂

上一节,我们知道了什么是命令,以及什么是查询。今天我们继续前面的例子,来试着将一个功能太多的函数进行命令和查询的分离。

/**
 * 查询函数(用于设置值并返回)
 *
 */	
function configure(values) {
	var config = { docRoot: '/somewhere' };
 	var key;
 	for (key in values) {
 		config[key] = values[key];
 	}
 	return config;
}

/**
 * 命令函数(用与验证config的docRoot)
 *
 */
function validateDocRoot(config) {
	var fs = require('fs');
	var stat;
 	stat = fs.statSync(config.docRoot);
	if (!stat.isDirectory()) {
		throw new Error('Is not valid');
 	}
}

/**
 * 命令函数(用于验证config的其他值)
 *
 */
function validateSomethingElse(config){ ... }

好了,这样我们就将一个复杂的configure()函数分离称为了三个简单的函数,且每个函数或者是命令函数或者是查询函数,这样我就方便对每个函数进行测试。

注意:前面我们说过命令函数属于setter和查询函数属于getter,而新抽象出来的configure()函数即包含了对config对象的设置值,又返回了一个config对象,那么它到底是命令函数查询呢?

我的一个简单判断就是,因为这个函数有返回值,所以把它当做查询来进行测试。

 

测试代码

有了命令和查询的分离以后,我就可以对这些简单的命令和查询函数进行测试了.

describe('validate value1', ()=>{
	it('accept the correct value',function(){
		//expect something
	});
	it('accept the incorrect value',function(){
		//expect something
	});
});

这里我们的configure()有点小问题就是缺少了验证,因此需要重构一下:

/**
 * 此函数接收一个散列对象,要么返回一个有效的配置对象要么抛出一个错误
 *
 */
function configure(values) {
	var config = { docRoot: '/somewhere' };
 	var key;
 	for (key in values) {
 		config[key] = values[key];
 	}
 	validateDocRoot(config);
	validateSomethingElse(config);
 	return config;
}

顺便提一点,在上一个版本的验证函数中,我们看到如果抛出错误,函数返回的是一个undefined而有了命令和查询分离以后,这个返回undefined的奇怪逻辑也不需要了。

 

以上函数算是初步进行了分离,但是存在的一个问题是,configure()的测试需要依赖验证函数,可以尝试做一些抽象,比如:

var fields = {
 	docRoot: { validator: validateDocRoot, default: '/somewhere'},
	somethingElse: { validator: validateSomethingElse}
}
function configure(values) {
	var config = {};
	for (var key in fields) {
 		if (typeof values[key] !== 'undefined') {
			fields[key].validator(values[key]);
			config[key] = values[key];
		}else {
 			config[key] = fields[key].default;
 		}
 	}
	return config;
}

这个函数有几个优点,验证函数可以方便的测试,对象赋值的时候可以进行验证,且数据都在一个中央位置。

当然这个函数也存在缺陷,至于到底存在什么问题呢?我们下一节进行分析。

版权声明:著作权归作者所有。

相关推荐

Sql Server使用查询语句更新数据

Sql Server支持在一个sql语句里使用查询的数据更新表。简单更新简单的使用一个表的数据更新另一个表。UPDATE    table_a  SET    table_a.col1=table_b.col1 FROM    table_b  WHERE table_

Linux uname命令的示例(系统管理命令)

说明打印系统相关信息,包括内核版本号、硬件架构、主机名称和操作系统类型等。语法uname [OPTION]... 常用选项-a,--all:显示全部的信息;-m,--machine:显示机器类型;-n,-nodename:显示在网络上的主机名称;-r,--release:显示操作系统的发行编号;-s,--sysname:显示操作系统名称;-v:显示操作系统的版本;-p,--process

Docker MySQL备份和恢复数据库命令

这两个命令用于对正在运行的Docker MySQL容器做备份和恢复备份Docker MySQLdocker exec CONTAINER /usr/bin/mysqldump -u username --password=xxx DATABASE > backup.sql 从sql文

Git重命名本地和远程分支

1、在本地新建分支git branch -m old_branch new_branch 2、unset-upstream新分支git branch --unset-upstream new_branch 这是为了避免新分支还会使用旧分支名push到远程服务器。3、关联新分支到远程服务器git push --

shell命令在原文件查找和替换字符串

sed在文件直接替换字符串最简单的是使用sed,如sed -i -e 's/abc/XYZ/g' myfile.txt-i[SUFFIX], --in-place[=SUFFIX]表示就地编辑,如果后面提供了后缀,则会把原文件以提供的后缀做备份。-e script, --expression=script指定执行编辑的脚本,这里使用了替换表达式。表达式格式为s/被替换文本/新的文本/gperl也可

vim查找替换字符串命令

vim使用 :s(substitute)命令来做字符串替换,格式如下::s/<查找文本>/<替换新的文本>/<flags>替换的几种情况::s/foo/bar/ 替换当前行第一个 foo为 bar:s/foo/bar/g 替换当前行所有 foo为 bar:n,$s/foo/bar/ 替换第 n 行开始到最后一行中每一行的第一个 foo为 bar:n,$

查询Redis数据库的数量

redis数据库的数量是固定的,可以在redis.conf查询到redis数据库的数量。使用grep命令:$ cat redis.conf | grep databasesdatabases 16当然,也可以在redis-cli上查询数据库的数量:127.0.0.1:6379> CONFIG GET databases1) "databases"2) "16"使用config get dat