迪米特法则:电子商务库存管理应用案例,并不属于过度设计

迪米特法则(Law of Demeter, LoD)是一种软件设计原则,它要求一个对象应该对其他对象有最少的了解,只与直接的朋友(即直接的依赖关系)交互。

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

欢迎 点赞,点赞,点赞。

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

历史热点文章

2. 迪米特法则设计图:

电子商务中库存服务如何遵守迪米特法则:

3. 迪米特法则解决什么:

迪米特法则解决了在复杂系统中对象之间不必要交互的问题,减少了系统的耦合度。

4.迪米特法则特点:

  • 最小化交互:类只与直接相关对象交互。
  • 提高模块化:降低了类之间的依赖,提高了系统的模块化。

5. 迪米特法则缺点:

  • 可能增加间接层:为了遵守迪米特法则,可能需要增加额外的间接层或中间类。
  • 过度封装:在一些情况下,可能会导致过度封装,影响代码的直观性。

6. 迪米特法则使用场景:

当系统中的对象之间存在复杂的交互关系,或者一个对象需要了解太多其他对象的内部细节时。

7. 迪米特法则案例

7.1 库存和订单处理案例

重构前:

java 复制代码
    // OrderService 直接与 Product 交互,违反了迪米特法则
    public class OrderService {
        public void placeOrder(Product product, int quantity) {
            if (product.getStock() >= quantity) {
                product.reduceStock(quantity);
                product.getSupplier().notifyStockLevel(); // 间接交互
                // 发送订单确认逻辑
            } else {
                // 发送缺货通知逻辑
            }
        }
    }

    public class Product {
        private int stock;
        private Supplier supplier;

        public int getStock() {
            return stock;
        }

        public void reduceStock(int quantity) {
            stock -= quantity;
        }

        public Supplier getSupplier() {
            return supplier;
        }
    }

    public class Supplier {
        public void notifyStockLevel() {
            // 库存水平通知逻辑
        }
    }

问题分析:

  1. 高耦合度OrderService 直接与 Product 类的多个方法交互,包括获取库存和减少库存,这增加了类之间的依赖。
  2. 低内聚性Product 类不仅管理自己的状态,还负责与 Supplier 交互,这违反了单一职责原则。
  3. 扩展性差 :当需要添加新的库存检查逻辑或供应商通知逻辑时,可能需要修改 OrderService 的代码,这限制了系统的扩展性。
  4. 代码重复 :如果系统中的其他部分需要进行库存检查或减少库存,可能会复制 OrderService 中的代码,导致代码重复。
  5. 测试困难 :直接依赖具体实现使得对 OrderService 进行单元测试变得复杂,因为它依赖于多个外部实体。

重构后:

java 复制代码
    // 库存服务接口,定义库存相关操作的契约
    public interface IInventoryService {
        boolean isStockSufficient(Product product, int quantity);
        void reduceStock(Product product, int quantity);
    }

    // 实现库存服务接口的具体类
    public class InventoryService implements IInventoryService {
        @Override
        public boolean isStockSufficient(Product product, int quantity) {
            // 检查库存是否充足
            return product.getStock() >= quantity;
        }

        @Override
        public void reduceStock(Product product, int quantity) {
            // 减少产品库存
            product.reduceStock(quantity);
        }
    }

    // 订单服务类,负责处理订单逻辑
    public class OrderService {
        private IInventoryService inventoryService;

        // 依赖注入库存服务
        public OrderService(IInventoryService inventoryService) {
            this.inventoryService = inventoryService;
        }

        // 下订单的方法
        public void placeOrder(Product product, int quantity) {
            if (inventoryService.isStockSufficient(product, quantity)) {
                inventoryService.reduceStock(product, quantity);
                sendOrderConfirmationEmail(product, quantity);
            } else {
                sendOutOfStockNotificationEmail(product);
            }
        }

        private void sendOrderConfirmationEmail(Product product, int quantity) {
            // 发送订单确认邮件逻辑
            // 这里用注释代替真实的邮件发送逻辑
            // EmailService.send("Order confirmed for " + product.getName());
        }

        private void sendOutOfStockNotificationEmail(Product product) {
            // 发送缺货通知邮件逻辑
            // 这里用注释代替真实的邮件发送逻辑
            // EmailService.send("Out of stock notification for " + product.getName());
        }
    }

    // 产品类,包含库存和供应商信息
    public class Product {
        private int stock;
        private String name;
        private Supplier supplier;

        public Product(String name, int stock, Supplier supplier) {
            this.name = name;
            this.stock = stock;
            this.supplier = supplier;
        }

        public int getStock() {
            return stock;
        }

        public void setStock(int stock) {
            this.stock = stock;
        }

        public void reduceStock(int quantity) {
            stock -= quantity;
            if (stock <= 10) {
                supplier.notifyLowStock(this);
            }
        }

        public String getName() {
            return name;
        }
    }

    // 供应商类,负责接收库存水平通知
    public class Supplier {
        public void notifyLowStock(Product product) {
            // 库存水平通知逻辑,可能涉及外部系统或服务 ,篇幅问题省略
        }
    }

    // 客户端代码,使用OrderService和InventoryService
    public class ECommerceClient {
        public static void main(String[] args) {
            Product product = new Product("Laptop", 5, new Supplier());
            IInventoryService inventoryService = new InventoryService();
            OrderService orderService = new OrderService(inventoryService);

            // 尝试下订单
            orderService.placeOrder(product, 3);
            // 尝试下超过库存的订单
            orderService.placeOrder(product, 10); 
        }
    }

解决的问题:

  1. 解耦合 :通过引入 IInventoryService 接口,OrderService 现在只依赖于库存服务的抽象,而不是具体的 Product 类。
  2. 高内聚性Product 类现在只负责管理自己的状态,而库存检查和减少库存的逻辑由 InventoryService 处理,符合单一职责原则。
  3. 扩展性增强 :新增或修改库存逻辑时,只需实现或修改 IInventoryService 的具体实现类,无需更改 OrderService
  4. 减少代码重复 :库存检查和减少库存的逻辑现在集中在 InventoryService 中,可以在多个地方重用,减少了代码重复。
  5. 易于测试OrderServiceInventoryService 可以独立测试,因为它们之间的依赖是通过接口定义的,可以轻松地使用模拟对象进行测试。
  6. 清晰的职责划分 :每个类和接口都有明确的职责,OrderService 处理订单逻辑,InventoryService 处理库存逻辑,Product 管理产品状态。
  7. 更好的维护性:由于系统更加模块化,维护和更新特定部分的代码变得更加容易,因为对系统的其他部分的影响最小。

7.2 课程管理系统

重构前:

java 复制代码
public class Professor {
    private String name;

    public Professor(String name) {
        this.name = name;
    }

    public void submitGrades(Student student, Course course, double grade) {
        course.getEnrolledStudents().add(student);
        student.addGrade(course, grade);
        System.out.println("Grade submitted by " + name);
    }
}

public class Course {
    private List<Student> enrolledStudents;

    public void addStudent(Student student) {
        enrolledStudents.add(student);
    }

    public List<Student> getEnrolledStudents() {
        return enrolledStudents;
    }
}

public class Student {
    private List<Grade> grades;

    public void addGrade(Course course, double grade) {
        grades.add(new Grade(course, grade));
    }
}

public class Grade {
    private Course course;
    private double grade;

    public Grade(Course course, double grade) {
        this.course = course;
        this.grade = grade;
    }
}

分析问题:

  1. 违反迪米特法则Professor 类直接与 StudentCourse 的具体实现交互。
  2. 高耦合度Professor 类与 CourseStudent 类的内部状态紧密耦合。
  3. 低内聚性Course 类不仅管理课程信息,还管理学生注册和成绩记录。

重构后:

Java 复制代码
// 教授类,只负责教授相关逻辑
public class Professor {
    private String name;

    public Professor(String name) {
        this.name = name;
    }

    public void submitGrade(CourseGradeService courseGradeService, Course course, double grade) {
        courseGradeService.recordGrade(course, grade);
        System.out.println("Grade submitted by " + name);
    }
}

// 课程成绩服务,负责处理成绩记录逻辑
public class CourseGradeService {
    public void recordGrade(Course course, double grade) {
        course.addGrade(grade);
    }
}

// 课程类,只负责课程相关逻辑
public class Course {
    private List<Double> grades;

    public void addGrade(double grade) {
        grades.add(grade);
    }
}

// 学生类保持不变,只关注学生自己的成绩
public class Student {
    private List<Grade> grades;

    public void addGrade(Course course, double grade) {
        grades.add(new Grade(course, grade));
    }
}

// 成绩类保持不变
public class Grade {
    private Course course;
    private double grade;

    public Grade(Course course, double grade) {
        this.course = course;
        this.grade = grade;
    }
}

// 客户端代码
public class UniversityClient {
    public static void main(String[] args) {
        Professor professor = new Professor("Dr. Smith");
        Course course = new Course();
        CourseGradeService courseGradeService = new CourseGradeService();

        professor.submitGrade(courseGradeService, course, 92.5);
    }
}

解决的问题:

  1. 遵守迪米特法则Professor 类现在只与 CourseGradeService 交互,而不是直接与 CourseStudent 交互。
  2. 降低耦合度 :通过引入 CourseGradeServiceProfessor 类不再依赖于 Course 类的内部实现。
  3. 提高内聚性Course 类现在只关注课程和成绩管理,而 Professor 类只关注教授的行为。
  4. 增强扩展性 :新增或修改成绩记录逻辑时,只需在 CourseGradeService 中进行,不影响其他类。
  5. 简化测试 :可以独立测试 CourseGradeService 的行为,而不需要依赖 ProfessorCourse 类。

8. 参考开源框架:

在现代的电子商务平台中,如Magento或Shopify,通常会遵循迪米特法则来设计库存和订单服务。

9. 总结:

通过应用迪米特法则,电子商务平台的库存管理和订单服务变得更加清晰和解耦。这不仅提高了代码的可维护性,也使得新增功能或修改现有逻辑变得更加容易。迪米特法则是构建低耦合、高内聚系统的有效工具之一。

历史热点文章

相关推荐
罗政13 分钟前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
Karoku06615 分钟前
【网站架构部署与优化】web服务与http协议
linux·运维·服务器·数据库·http·架构
架构文摘JGWZ44 分钟前
Java 23 的12 个新特性!!
java·开发语言·学习
拾光师2 小时前
spring获取当前request
java·后端·spring
aPurpleBerry2 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j
我是苏苏2 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
xujinwei_gingko2 小时前
Spring IOC容器Bean对象管理-Java Config方式
java·spring
2301_789985942 小时前
Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
java·开发语言·学习
IT学长编程2 小时前
计算机毕业设计 教师科研信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·毕业设计·springboot·毕业论文·计算机毕业设计选题·计算机毕业设计开题报告·教师科研管理系统
m0_571957582 小时前
Java | Leetcode Java题解之第406题根据身高重建队列
java·leetcode·题解