本文仅表达前端的一些设计技巧,如果您在查阅js技术,请忽略此文!
前端开发经常会遇到这样的场景:
当满足一定条件时,需要弹出一个模态框,以便接收用户的输入。然后根据不同的输入,进行不用的操作。
(ps:这类场景太常见了)
看了很多人的js代码,我发现大多数人的设计是这样的:
modalModule{
……//其他代码。
cancel(){
closeModal();
}
ok(){
handle(inputResult);
closeModal();
}
}
parentModule{
if(condition){
call modalModule;
}
}
这样设计,两个模块有严重的耦合:
我们虽然写了一个modal模块,可是这个模块好像是专门为parent模块设计的。因为怎么处理结果,是完全取决于parent模块的业务需求的! 显然这样一个被量身打造的“专用模块”,几乎无法被重用。
遗憾的是,我看到过很多这样设计的代码——想象一下,整个项目有大量类似的modal模块,(类似是因为这些模块中 打开模态框,关闭,确认等的这些代码 完全一样,唯一不同的就是handle),造成这种局面的原因,我想,无非就是公司的员工习惯了先复制一个已实现的模块,然后修修改改,下次又复制粘贴,修修改改... ...
接下来,我们来换一种设计:
(不要想着用全局变量来解决这种耦合,或发送事件来告诉parentModule,这样效率低了。依赖全局或消息,也是一种耦合!先想一下,在访问服务器端我们都用的回调,可不可把模态交互设计成回调模式,让handle(inputResult)这部分在parentModule中执行呢?下面就是这样的设计!)
modalModule{
……//其他代码。
cancel(){
Promise.reject();
closeModal();
}
ok(){
Promise.resolve(inputResult);
closeModal();
}
return Promise;
}
parentModule{
if(condition){
call modalModule .then(res=>handle(res));
}
}
这样设计可以发现,modalModule就是一个通用的模块了,绿色部分就是回调,表示对返回用户输入结果的一个承诺(promise),至于怎么处理这个结果就和它无关了——modalModule变得简单单一了。
另外parentModule的功能更集中了,更方便阅读理解了,从而更已维护了。
(ps:在angular1中$q就是用来做回调的,angular2中Promise对象也是做回调的。。)
(多运用这种设计,自己感受,领悟它的好处吧!)