为了方便日常开发,我们经常会封装一些常用的组件,方便系统中各个模块使用,但是引用的地方多了,由于每个模块可能有自己的特殊使用场景,使用过程中可能出现一些不可预料的问题,今天我们来学习利用面向对象中多态的思想来更好的封装一个组件。
多态通俗点来说,就是给不同的对象发送同一个消息,这些对象会根据这个消息分别给出不同的反馈。
下面用代码来简单描述下这一过程:
var makeSound = function (animal) {
animal.sound()
}
var Duck = function(){}
Duck.prototype.sound = function() {
console.log('嘎嘎嘎')
}
var Dog = function(){}
Dog.prototype.sound = function() {
console.log('汪汪汪')
}
makeSound(new Dog)
makeSound(new Dock)
对于这个例子来说,只要对象自带sound()方法,可以表明自己的“身份”,我们永远不需要改动makeSound()方法。
如果不使用多态,许多人先入为主的做法可能是在makeSound方法中使用if..else..来维护不同的动物,类似:
if (animal instanceof Duck) {
console.log('嘎嘎嘎')
}
从封装的角度来说,我们所希望的肯定是能适配更多的情况,而不是出现一种新情况就来修改封装的组件本身,后者很明显会导致更多不可预期的错误,因为组件应用的很多,随意改动任何一行代码都可能导致其他组件异常。
现在要封装一个目录树组件,最基础的功能就是目录树的展示,通过前期的调研,了解到不同模块需要对目录树返回的数据进行过滤,有的模块需要展示不同的层级,有的模块需要过滤特定条件下的目录树节点,下面我们按照多态的思想,将可变的部分封装一下,从而对封装的组件进行完善。
tree组件:
app:
上述代码只是一个大致思路,部分代码不是很完整,但是不影响阅读,如此实现,每个使用tree组件的地方都可以定义自己的过滤方法,如果不定义,则默认返回所有节点。同理比如点击数节点希望返回某些信息也可以利用此方法。
总的来说,组件不做任何的“决策”,引用组件的模块通过传入定制化方法或参数来实现自己的需求。
以上。