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

迪米特法则(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. 总结:

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

历史热点文章

相关推荐
Java编程爱好者6 分钟前
OpenClaw跟Skills、MCP、RAG和Agent有什么关系?
后端
写bug的小屁孩6 分钟前
Langfuse 查询慢到崩溃?我用二级缓存 + 预热架构把响应时间干到 4ms
架构
Roc.Chang8 分钟前
Rust 入门 - RustRover 新建项目时四种项目模板对比
开发语言·后端·rust
直有两条腿8 分钟前
【Spring Boot】原理
java·spring boot·后端
一只叫煤球的猫10 分钟前
用这个框架彻底摆脱Controller,从此专注业务——ArcRoute
java·spring·开源
SunnyDays101113 分钟前
Java 如何根据模板高效生成Word文档
java·根据模板生成word文档·生成word文档
攀岩巨峰的程序猿15 分钟前
代码开发过程中涉及到bean的copy方法梳理
java
TDengine (老段)16 分钟前
煤机设备每天 TB 级数据,天地奔牛用 TDengine 把查询提速到“秒级”
大数据·运维·数据库·struts·架构·时序数据库·tdengine
golang学习记18 分钟前
IDEA 2026.1 EAP 5 发布:K2模式更强了!
java·ide·intellij-idea
xuansec20 分钟前
【JavaEE安全】Java反序列化深度剖析:核心原理、利用链构造与安全风险管控
java·安全·java-ee