最少知识原则(LKP) :构建低耦合系统的秘诀

最少知识原则,也称为迪米特法则(Law of Demeter, LoD),是一种软件设计原则,它指导我们减少对象之间的交互,使得每个对象只需与其直接的合作伙伴通信,而不必关心合作伙伴的内部细节。

肖哥弹架构 跟大家"弹弹" 代码设计技巧,需要代码关注

欢迎 点赞,点赞,点赞。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章

2. 最少知识原则设计图:

最少知识原则鼓励开发者在设计系统时,限制对象之间的依赖关系,只暴露必要的接口,从而降低系统的耦合度。

学生系统最少知识原则图

电商最少知识原则图

3. 最少知识原则解决什么:

LKP原则解决了过度耦合的问题,过度耦合会导致代码难以维护和扩展。

4. 最少知识原则特点:

  • 最小化依赖:只依赖于直接需要的接口或方法。
  • 提高模块化:通过限制依赖,提高系统的模块化程度。
  • 增强可维护性:降低了修改一个对象可能对其他对象造成的影响。

5. 最少知识原则缺点:

  • 可能增加间接性:为了遵循LKP,可能需要增加额外的中间层或代理。
  • 过度应用可能导致复杂性:在某些情况下,严格遵循LKP可能会使系统设计变得复杂。

6. 最少知识原则使用场景:

当面临需要降低系统组件之间耦合度的场景时,LKP原则尤其有用。

7. 最少知识原则案例

7.1 学生系统案例

考虑一个学生信息系统,需要处理学生、课程和成绩等信息。

重构前:

java 复制代码
public class Student {
    public void submitHomework(Homework homework, Course course) {
        course.submit(homework);
    }
}

public class Course {
    public void submit(Homework homework) {
        // 提交作业的逻辑
    }
}

重构后:

java 复制代码
public interface ICourseService {
    void submitHomework(Homework homework);
}

public class Student {
    private ICourseService courseService;

    public Student(ICourseService courseService) {
        this.courseService = courseService;
    }

    public void submitHomework(Homework homework) {
        courseService.submitHomework(homework);
    }
}

public class CourseService implements ICourseService {
    public void submitHomework(Homework homework) {
        // 提交作业的逻辑
    }
}

最少知识原则如何通过引入服务层(ICourseService)来降低学生类(Student)与课程类(Course)之间的耦合

7.1 电子商务案例

重构前:

java 复制代码
public class CartService {
    private ProductService productService;

    public CartService(ProductService productService) {
        this.productService = productService;
    }

    public void addToCart(int productId, int quantity) {
        Product product = productService.getProductById(productId);
        // 直接使用ProductService中的方法添加到购物车
    }

    public Cart getCartDetails() {
        // 直接使用ProductService中的方法获取购物车详情
        return new Cart();
    }
}

重构后:

java 复制代码
public interface ProductService {
    ProductDetails getProductDetails(int productId);
}

public class CartService {
    private ProductService productService;

    public CartService(ProductService productService) {
        this.productService = productService;
    }

    public void addToCart(int productId, int quantity) {
        ProductDetails productDetails = productService.getProductDetails(productId);
        // 使用ProductDetails信息添加到购物车
    }

    public Cart getCartDetails() {
        // 使用ProductService提供的产品详情获取购物车详情
        return new Cart();
    }
}

public class ProductServiceClient implements ProductService {
    @Override
    public ProductDetails getProductDetails(int productId) {
        // 实现获取产品详情的逻辑
        return new ProductDetails();
    }
}

通过应用最少知识原则,CartService 不再直接依赖于 ProductService 的具体实现,而是依赖于一个 ProductService 接口。这样,如果将来需要更换 ProductService 的实现,或者在不同的上下文中使用不同的产品服务,我们可以轻松地通过实现不同的 ProductService 接口来满足需求,而不需要修改 CartService 的代码。这提高了系统的灵活性和可维护性。

8.最少知识原则与迪米特法则区别

  1. 定义
    • 迪米特法则(LoD) :主要关注于类之间的交互,特别是方法调用的约束。
    • 最少知识原则(LKP) :作为SOLID原则的补充,强调减少类之间的直接依赖,特别是避免直接访问其他类的内部结构。
  2. 关注点
    • LoD:更侧重于方法调用的约束,即一个对象应该只与其直接的合作伙伴交互,不应对其他对象的内部细节有过多的了解。
    • LKP:更侧重于减少依赖,强调一个类应该对其他类的内部实现一无所知,只通过必要的接口进行交互。
  3. 应用层面
    • LoD:通常用于指导类的设计和方法调用,避免类之间的过度耦合。
    • LKP:不仅用于类的设计,还可以用来指导模块、服务和组件之间的交互,强调整体架构的解耦。
  4. 实现方式
    • LoD:通过限制方法调用的深度和广度来实现,例如,不调用参数对象的非公开方法。
    • LKP:通过抽象、接口和中间层来实现,确保类之间的交互只通过定义良好的接口进行。
  5. 目标
    • LoD:目标是降低类之间的耦合度,使得每个类更加独立,更容易维护和测试。
    • LKP:目标是构建一个低耦合、高内聚的系统,提高系统的可维护性、可扩展性和可测试性。

9. 参考开源框架:

许多现代软件框架和库,如Spring和Hibernate,通过提供松耦合的组件和服务,遵循最少知识原则来设计。

10. 总结:

最少知识原则是提高软件设计质量的重要原则之一。通过限制对象之间的交互,它有助于构建更加模块化、灵活和易于维护的系统。虽然在某些情况下可能需要权衡设计简洁性和遵循LKP的程度,但总体而言,LKP原则为构建健壮、可持续的软件系统提供了坚实的基础。

历史热点文章

相关推荐
源码12155 分钟前
ASP.NET MVC宠物商城系统
后端·asp.net·宠物
Ai 编码助手1 小时前
Go语言 实现将中文转化为拼音
开发语言·后端·golang
hummhumm1 小时前
第 12 章 - Go语言 方法
java·开发语言·javascript·后端·python·sql·golang
hummhumm1 小时前
第 8 章 - Go语言 数组与切片
java·开发语言·javascript·python·sql·golang·database
尼克_张1 小时前
tomcat配合geoserver安装及使用
java·tomcat
杜杜的man1 小时前
【go从零单排】Directories、Temporary Files and Directories目录和临时目录、临时文件
开发语言·后端·golang
wywcool1 小时前
JVM学习之路(5)垃圾回收
java·jvm·后端·学习
-seventy-2 小时前
Java Web 工程全貌
java
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ2 小时前
idea 删除本地分支后,弹窗 delete tracked brank
java·ide·intellij-idea
言慢行善2 小时前
idea出现的问题
java·ide·intellij-idea