最少知识原则(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原则为构建健壮、可持续的软件系统提供了坚实的基础。

历史热点文章

相关推荐
卷无止境6 分钟前
终端里的AI辅助,一场正在发生的编程效率变革
后端·python
程序员爱钓鱼10 分钟前
Go 编程实战:Map——使用 Key-Value 管理键值数据
后端·rust·go
程序员爱钓鱼1 小时前
Rust Trait Object详解:dyn Trait与动态分发
后端·面试·rust
chuan.bai6 小时前
Java RAG 实战(第 11 篇):RAG 知识工作台网页
java·开发语言·人工智能
0x538 小时前
网站通信(一)
java
To_OC8 小时前
Next.js + Redis 构建笔记系统:Redis Hash 实战与性能优化
redis·后端·next.js
Terra.K8 小时前
Java异常学习[特殊字符]
java·开发语言·学习
葡萄城技术团队10 小时前
InfluxDB 2\.x 深度解析:核心架构、Flux 函数与制造业落地指南(三)
java·开发语言·架构
Super 含10 小时前
Android 启动优化(五):线程、GC 与 IO 为什么会拖慢启动?
java·服务器·数据库
counting money10 小时前
Java IO流详解:从InputStream到文件操作实战
java·开发语言·python