JavaScript可不可采用面向组合的设计方式

从设计思想上谈谈继承本身的问题

假如现在有不同品牌的车,每辆车都有drive、music、addOil这三个方法。

class Car{


  constructor(id) {


    this.id = id;


  }


  drive(){


    console.log("wuwuwu!");


  }


  music(){


    console.log("lalala!")


  }


  addOil(){


    console.log("哦哟!")


  }


}


class otherCar extends Car{}

现在可以实现车的功能,并且以此去扩展不同的车。

但是问题来了,新能源汽车也是车,但是它并不需要addOil(加油)。

如果让新能源汽车的类继承Car的话,也是有问题的,俗称"大猩猩和香蕉"的问题。大猩猩手里有香蕉,但是我现在明明只需要香蕉,却拿到了一只大猩猩。也就是说加油这个方法,我现在是不需要的,但是由于继承的原因,也给到子类了。

继承的最大问题在于:无法决定继承哪些属性,所有属性都得继承。

当然你可能会说,可以再创建一个父类啊,把加油的方法给去掉,但是这也是有问题的,一方面父类是无法描述所有子类的细节情况的,为了不同的子类特性去增加不同的父类, 代码势必会大量重复,另一方面一旦子类有所变动,父类也要进行相应的更新, 代码的耦合性太高,维护性不好。

那如何来解决继承的诸多问题呢?

用组合,这也是当今编程语法发展的趋势,比如golang完全采用的是面向组合的设计方式。

顾名思义,面向组合就是先设计一系列零件,然后将这些零件进行拼装,来形成不同的实例或者类。

function drive(){


  console.log("wuwuwu!");


}


function music(){


  console.log("lalala!")


}


function addOil(){


  console.log("哦哟!")


}






let car = compose(drive, music, addOil);


let newEnergyCar = compose(drive, music);

代码干净,复用性也很好。这就是面向组合的设计方式。

posted @ 2022-04-06 23:52  szmtjs10  阅读(16)  评论(0编辑  收藏  举报