敲碎时间的人的个人专栏
上一篇

函数的命令和查询分裂

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

函数的命令和查询分裂

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

/**
 * 查询函数(用于设置值并返回)
 *
 */	
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;
}

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

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

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

X

欢迎加群学习交流

联系我们