迪米特法则:最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。英文简写为: LoD.(节选自百度百科)
迪米特法则的做法观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高。一个类应该对其他对象保持最少的了解。通俗来讲,就是一个类对自己依赖的类知道的越少越好。因为类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
迪米特法则好处减少对象之间的耦合性
实例class ISystem { close(){ throw "Abstract methods cannot be used"; } } class System extends ISystem{ saveCurrentTask(){ console.log("saveCurrentTask") } closeService(){ console.log("closeService") } closeScreen(){ console.log("closeScreen") } closePower(){ console.log("closePower") } close(){ this.saveCurrentTask(); this.closeService(); this.closeScreen(); this.closePower(); } } class IContainer{ sendCloseCommand(){ throw "Abstract methods cannot be used"; } } class Container extends IContainer{ constructor(){ super() this.system = new System(); } sendCloseCommand(){ this.system.close(); } } class Person extends IContainer{ constructor(){ super(); this.container = new Container(); } clickCloseButton(){ this.container.sendCloseCommand(); } } let person = new Person(); person.clickCloseButton();
上面代码中Container作为媒介,其调用类不知道其内部是如何实现,用户去触发按钮,Container把消息通知给计算机,计算机去执行相对应的命令。
组合/聚合复用原则聚合(Aggregation)表示一种弱的‘拥有'关系,体现的是A对象可以包含B对象但B对象不是A对象的一部分。
合成(Composition)则是一种强的'拥有'关系,体现了严格的部分和整体关系,部分和整体的生命周期一样。
组合/聚合:是通过获得其他对象的引用,在运行时刻动态定义的,也就是在一个对象中保存其他对象的属性,这种方式要求对象有良好定义的接口,并且这个接口也不经常发生改变,而且对象只能通过接口来访问,这样我们并不破坏封装性,所以只要类型一致,运行时还可以通过一个对象替换另外一个对象。
优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上,这样类和类继承层次会保持较小规模,而且不太可能增长为不可控制的庞然大物。
组合/聚合复用原则好处新的实现较为容易,因为超类的大部分功能可通过继承关系自动进入子类;
修改或扩展继承而来的实现较为容易。
实例function mix(...mixins) { class Mix {} for (let mixin of mixins) { copyProperties(Mix, mixin); copyProperties(Mix.prototype, mixin.prototype); } return Mix; } function copyProperties(target, source) { for (let key of Reflect.ownKeys(source)) { if ( key !== "constructor"&& key !== "prototype"&& key !== "name") { let desc = Object.getOwnPropertyDescriptor(source, key); Object.defineProperty(target, key, desc); } } } class Savings { saveMoney(){ console.log("存钱"); } withdrawMoney(){ console.log("取钱"); } } class Credit { overdraft(){ console.log("透支") } } const CarMin = mix(Savings,Credit); class UserCar extends CarMin { constructor(num,carUserName){ super(); console.log() this.carNum = num; this.carUserName = carUserName; } getCarNum(){ return this.carNum; } getCarUserName(){ return this.carUserName; } } let myCar = new UserCar(123456798,"Aaron"); console.log(myCar.getCarNum()); console.log(myCar.getCarUserName()); myCar.saveMoney(); myCar.withdrawMoney(); myCar.overdraft();
总结这些原则在设计模式中体现的淋淋尽致,设计模式就是实现了这些原则,从而达到了代码复用、增强了系统的扩展性。所以设计模式被很多人奉为经典。我们可以通过好好的研究设计模式,来慢慢的体会这些设计原则。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》