22 | 理论八:如何用迪米特法则(LOD)实现“高内聚、松耦合”?
该思维导图由 AI 生成,仅供参考
何为“高内聚、松耦合”?
- 深入了解
- 翻译
- 解释
- 总结
迪米特法则是一个重要的设计原则,旨在实现代码的“高内聚、松耦合”。文章首先介绍了“高内聚、松耦合”设计思想的重要性和实际应用,强调了高内聚有助于松耦合,而低内聚则会导致紧耦合。接着,文章详细解释了迪米特法则的理论描述,即每个模块(类)只应该了解与之关系密切的模块的有限知识,或者说每个模块只和自己的朋友“说话”,不和陌生人“说话”。迪米特法则的核心是避免直接依赖关系的类之间存在依赖,尽量只依赖必要的接口,以实现代码的松耦合。文章还提供了两个代码实战案例,以帮助读者更好地理解迪米特法则的应用。 第一个案例展示了如何根据迪米特法则重构代码,避免直接依赖关系的类之间存在依赖,以实现松耦合。通过对NetworkTransporter、HtmlDownloader和Document类的重构,读者可以清晰地了解如何应用迪米特法则来改善代码设计,提高代码的可维护性和可测试性。 第二个案例则展示了如何根据迪米特法则的后半部分原则,即“有依赖关系的类之间,尽量只依赖必要的接口”,来优化代码设计。文章通过拆分Serialization类为Serializer和Deserializer类,并引入接口的方式,解决了迪米特法则和高内聚原则之间的矛盾,使得代码更加灵活和可维护。 通过本文的学习,读者可以深入了解迪米特法则的原理和实际应用,从而在实际开发中实现“高内聚、松耦合”的代码设计目标。文章还提到了“高内聚、松耦合”“单一职责原则”“接口隔离原则”“基于接口而非实现编程”“迪米特法则”,这些设计原则之间的区别和联系,帮助读者更好地理解和应用这些原则。
《设计模式之美》,新⼈⾸单¥98
全部留言(126)
- 最新
- 精选
- 王大喵联系: “接口隔离原则”是客户端不应该被强迫依赖不需要的接口,和“迪米特法则”中的有限知识异曲同工,接口簇会更加“单一职责”实现方式“基于接口而非实现编程”,达到的目的是高内聚,松耦合。 区别: 1. 各种原则最终的目的是为了实现“高内聚、松耦合”。 2. 单一职责原则 主要是指导类和模块,避免大而全,提高内聚性。 3. 接口隔离和迪米特(最小知识)主要指导“松耦合”,解耦使用方的依赖。 4. 基于接口而非实现编程:主要是解耦接口和实现,是指导思想,提高扩展性。
作者回复: ������
2020-11-16214 - 提姆老师您好,请问一下Document的修改为什么会使用到Factory的方式去产生?我对这一步的修改没有很大的感受,我这里的认知是Document只是单纯对文件的操作,那是不是可以透过HtmlDownloader实现相关取得文件的接口,像是IDownloader之类的名称,并直接回传Document这个类(亦或者对此类做其它的延伸),未来也可以实现其它像是json等其他格式的downloader,不知道我这个想法是不是可行?
作者回复: 你的设计也可以的。设计本身没有最优解,合理、能自圆其说就可以了。总体上来讲,我这个例子是为了展示尽量减少类之间的耦合。
2020-07-0723 - 戒惜舍得相近的功能。 怎么算相近啊。学晕了。
作者回复: 咋这么能抬杠呢 你说我问你怎么相近 你能回答上来吗 这个也没法量化 设计模式不是算法 什么都能定量 更多的是教你思想 你自己去感受
2019-12-2723 - 大方方我想知道假如 Public class NetworkTransporter { // 省略属性和其他方法... public Byte[] send(HtmlRequest htmlRequest) { //... }} 中的send 方法,必须需要HtmelRequest 才能实现功能呢? 老师修改后,参数上看起来是不依赖外部对象了,但是在很多其他实际操作时,很有可能还是需要用到外部对象来解决问题。 这种情况是不是需要做类扩展,在扩展中再具体引用HtmlRequest ?
作者回复: “很有可能还是需要用到外部对象来解决问题”能举个例子吗? “ 这种情况是不是需要做类扩展,在扩展中再具体引用HtmlRequest” 也可以直接改这个类~,不过还是没太懂你的意思~
2020-06-292 - 斐波那契老师 我有一个问题:在项目开发中,我写了一个类A 里面定义了一个方法,后来又写了一个类B 发现在B里面要用到A里面定义的那个方法(基本上一模一样),但是A跟B本身是两个不相关的类 这个时候要怎么解决? PS:这个方法不能算作是工具类,只是一段数据集的处理逻辑 那是否是搞一个抽象类 然后让A和B继承这个抽象类 把那个方法写进抽象类里?
作者回复: 使用组合能不能解决复用问题呢
2019-12-292 - prowu一直有一个消息结构与程序内部数据结构取舍的问题:程序内部是否直接复用消息协议的结构?比如:通讯消息使用的是protobuf协议,那程序内部的逻辑是直接使用protobuf的数据结构,还是自己在定义一套结构体?如果直接使用protobuf协议,那程序就紧耦合于协议了(这边就是与protobuf绑在一起了),如果自己在定义一套结构体,那就要多一层协议与内部结构的转换。
作者回复: 这个也要具体问题具体分析 跟我们讲的vo bo很像
2019-12-282 - 知行合一目的都是实现高内聚低耦合,但是出发的角度不一样,单一职责是从自身提供的功能出发,迪米特法则是从关系出发,针对接口而非实现编程是使用者的角度,殊途同归。2019-12-239383
- 下雨天1.单一职责原则 适用对象:模块,类,接口 侧重点:高内聚,低耦合 思考角度:自身 2.接口隔离原则 适用对象:接口,函数 侧重点:低耦合 思考角度:调用者 3.基于接口而非实现编程 适用对象:接口,抽象类 侧重点:低耦合 思考角度:调用者 4.迪米特法则 适用对象:模块,类 侧重点:低耦合 思考角度:类关系2019-12-2512236
- Ken张云忠“高内聚、松耦合”“单一职责原则”“接口隔离原则”“基于接口而非实现编程”“迪米特法则”,它们之间的区别和联系吗? 区别: 高内聚、松耦合:是一个重要的设计思想,能够有效地提高代码的可读性和可维护性,缩小功能改动导致的代码改动范围. 单一职责原则:A class or module should have a single reponsibility.提供的功能上要单一. 接口隔离原则:Clients should not be forced to depend upon interfaces that they do not use.与外部关系上只依赖需要的抽象. 基于接口而非实现编程:Program to an interface, not an implementation.是一条比较抽象、泛化的设计思想,为了提高代码的灵活性/扩展性/可维护性. 迪米特法则:Each unit should have only limited knowledge about other units: only units “closely” related to the current unit. Or: Each unit should only talk to its friends; Don’t talk to strangers.每个单元只该依赖与它关系密切的单元,最少知道,只与关系密切的单一交互. 联系: 职责越单一越容易做到接口隔离,也越容易做到最少知道的迪米特法则. 基于抽象编程抽象的知识越顶层越脱离具体实现,相对知道的内容就越少,也容易实现迪米特法则. 接口隔离原则与迪米特法则都强调只依赖需要的部分,接口隔离原则是相对偏上层来说的,迪米特法则是相对偏具体实现来说的. 单一职责原则/接口隔离原则/基于接口而非实现编程/迪米特法则都以实现代码的"高内聚、松耦合"为目的,提高代码的可读性和可维护性,缩小功能改动导致的代码改动范围,降低风险.2019-12-2358
- 辣么大关于LoD,请记住一条:方法中不要使用ChainMethods。 坏的实践: Amount = customer.orders().last().totals().amount() 和 orders = customer.orders() lastOders = orders.last() totals = lastOders.totals() amount = totals.amount() 上面的例子中,chain中的方法改变会影响很多地方。这里注意区别建造者模式和pipeline管道,这两种的chain中的方法不易改变。 出现这样的代码,需要考虑可能是设计或实现出了问题。 LoD如何使用: 一个类C中的方法只能调用: 1、C中其他实例方法 2、它自己的参数方法 3、它创建对象的方法 4、不要调用全局变量(包括可变对象、可变单例) 例如: class HtmlDownloader{ Html html; public void downloadHtml(Transporter trans, String url){ if(checkUrl(url)){// ok 自己的实例方法 // return } rawData = trans.send(uri);// ok 参数对象的方法 Html html = createHtml(rawData); // ok 它创建的对象 html.save();// ok 它创建对象的方法 ) private boolean checkUrl(String url){ // check } } 参考: The Pragmatic Programmer 1st edition and 2nd edition2019-12-232441