多种不同结果的返回模式
探讨个问题哈,我现在再做一个 HTML 校验工具,先将 HMTL 源码解析成 DOM 树,
其间可能遇到语法错误,为了发现更多的错误,会跳到下一个分界点继续解析;
然后将解析得到的 DOM 树返回给 lint 工具继续进行进一步的语法、语义解析。
其过程是:
1var dom = parse(html){cap(err); return dom;};
2var lintErr = lint(dom){return err;};
最终需要将 parse 和 lint 的错误收集到一起反馈给服务端。
请问,parse 有什么好的方式来返回解析时错误信息?
之前先是将 parse 设计成了函数式,但是我觉得下面这种返回方式很不好:
1return {
2 dom: dom,
3 err: err
4};
另外一种思路
HTMLParser 设计成独立的类(而不是上面的函数方式)
1var HTMLParser = function(){
2 var err = [];
3 this.parse = function(html){
4 var dom = {};
5
6 err.push(new Error("this is not error."));
7 err.push(new Error("err is not error."));
8
9 return dom;
10 };
11 this.getErrors = function(){
12 return err;
13 };
14};
15
16function main(html){
17 var parser = new HTMLParser();
18 var dom = parser.parse(html);
19 var err = parser.getErrors();
20 var result = HTMLint(dom);
21
22 // concat array to err.
23 Array.prototype.push.apply(err, result);
24
25 return err;
26};
貌似这种方式比上面的稍好一点,不过我又不想为此将原本很简单的函数式改成
对象式。
外部数据存储
1var Console = (function(){
2 var _err = [];
3 function log(err){
4 _err.push(err);
5 }
6 function getErr(){
7 return _err;
8 }
9
10 return {
11 log: log,
12 getErrors: getErr
13 };
14});
15var HTMLParse = function(){
16 Console.log(new Error("syntax error."));
17 Console.log(new Error("parse error"));
18
19 return dom;
20};
21var HTMLint = function(dom){
22 var err = [];
23 err.push(new Error("lint error."));
24 err.push(new Error("lint error."));
25 return err;
26};
27function main(html){
28 var dom = HTMLParse(html);
29 var parseErr = Console.getErrors();
30 var lintErr = HTMLint(dom);
31
32 Array.prototype.push.apply(parseErr, lintErr);
33
34 return parseErr;
35}
对于只有一个实例(或运行一次)的情况,第三方独立的 console 是合适的。
但是一旦需要多个实例(或运行多次,每次Parse的结果都各自独立,
每个html的parse和lint的错误结果各自拼接一起,但是不是所有的html的parse+lint错误结果拼接在一起)
的情况,还是将解析异常信息和解析器本身绑定在一起(比如类)的方式比较合适。
上面的文字有点绕,表达式:
err0 = parseError0 + lintError0;
err1 = parseError1 + lintError1;
err0 和 err1 是各自独立的,实例化多个第三方独立的有专用的Console,不如用类的方式好了。
寻求指教
对于这种需要返回多种不同数据的函数式,
如果你有其他的方案,欢迎回帖、回邮,或回博交流指导 :)
更新 (2013)
事件机制可能是最好的选择:
1parser.on("error", function(err){
2});
Tags: 设计模式
Published on 2011-06-08