职责链模式在js中典型的应用场景是事件冒泡. 将所有子节点和父节点连成一条链,并沿着这条链传递事件,直到有一个节点能够处理它为止. 职责链模式是消除过多的if else语句的神器.
拿最近做的一个需求来举例, 有个文件上传的功能, 提供了控件,html5, flash, 表单上传这4种上传方式. 根据它们的优先级以及浏览器支持情况来判断当前选择哪种上传方式. 在我进行改造之前,它的伪代码大概是这样:
当然实际的代码远不只这么多,其中还包括了各种控件初始化,容错等情况。有天我需要屏蔽掉flash,看起来是很简单的需求,但难度实际跟在心脏旁边拆掉一根毛线血管类似.
如果试试职责链模式呢, 看看事情将变得多简单:
第一步先改写之前的after函数,使得返回一个对象时阻断职责链的传递,而返回null时继续传递请求。
接下来把每种控件的创建方式都包裹在各自的函数中, 确保没有逻辑交叉和相互污染.
最后用职责链把它们串起来:
可以预见,某天我又需要屏蔽掉flash, 那时的我只需要改动这一行代码. 改成:
组合代替继承
很多时候我们在设计程序的时候,会遇到使用组合还是继承的问题. 通常来讲, 使用组合更灵活轻巧. 还是拿之前文件上传来举例.
我定义了一个超类Upload, 衍生出4个子类.
Plugin_Upload, Html5_Upload, Flash_Upload以及Form_Upload.
Plugin_Upload会继承父类,得到Upload的大部分功能, 然后对控件上传的一些特性进行个性定制. 比如其它3种上传方式都是选择文件后便开始上传. 而控件上传在开始上传之前会经过一轮文件扫描.
第一种做法是Plugin_Upload继承Upload, 然后重写它的start_upload方法.
用更轻的组合方式, 可以直接给原来的start_upload函数装饰上扫描功能, 甚至不需要衍生一个额外的子类.
您可能感兴趣的文章: