信息专家原则:电子商务订单管理系统的实践(架构师篇)

信息专家原则是GRASP(General Responsibility Assignment Software Principles)原则之一,它建议将处理特定数据的责任分配给最了解这些数据的类。这有助于提高代码的内聚性和降低耦合度。
肖哥弹架构 跟大家“弹弹” 代码设计技巧,需要代码关注
欢迎 点赞,点赞,点赞。
关注公号Solomon肖哥弹架构获取更多精彩内容
历史热点文章
- 依赖倒置原则:支付网关设计应用案例
- Holder模式(Holder Pattern):公司员工权限管理系统实战案例分析
- 一个项目代码讲清楚DO/PO/BO/AO/E/DTO/DAO/ POJO/VO
- 写代码总被Dis:5个项目案例带你掌握SOLID技巧,代码有架构风格
- 里氏替换原则在金融交易系统中的实践,再不懂你咬我
2. 信息专家设计图:
信息专家原则鼓励开发者将数据和处理数据的方法封装在同一个类中,使得每个类都成为其数据的“专家”。

Order
类代表订单,包含订单编号、用户、商品项列表,以及下单、添加商品项和计算总价的方法。Customer
类代表用户,包含用户编号、名字和姓氏,以及获取全名的方法。OrderItem
类代表订单中的商品项,包含产品和数量,以及计算商品总价的方法。Product
类代表产品,包含产品编号、名称和价格。Inventory
类代表库存服务,负责检查产品的可用性。PaymentProcessor
类代表支付处理器,负责处理订单的支付。OrderService
类代表订单服务,使用充血模型中的Order
类来提交订单。
3. 信息专家解决什么:
此原则解决了数据和行为分离的问题,避免了在系统中不必要的数据传递和复杂性。
- 数据类:
public class Book {
private String title;
private double price;
// 仅包含基本的getter和setter方法
}
public class Order {
private List<Book> books;
private double totalAmount;
// 仅包含基本的getter和setter方法
}
- 业务逻辑类:
public class OrderService {
public void calculateTotalAmount(Order order) {
double total = 0;
for (Book book : order.getBooks()) {
total += book.getPrice();
}
order.setTotalAmount(total);
}
}
在这个例子中,Order
类和 Book
类仅包含数据,而没有封装任何行为。所有与订单相关的业务逻辑,如计算总金额,都放在了 OrderService
类中。这导致了数据和行为的分离。
- 高耦合度:
OrderService
类需要直接访问Order
和Book
的内部状态。 - 低内聚性:
Order
和Book
类缺乏与它们数据相关的业务逻辑。 - 维护困难:任何与订单或书籍相关的业务逻辑更改都需要在
OrderService
中进行,这可能会影响到其他部分的代码。
案例说明
"数据和行为分离"问题的一个常见例子是在多层架构的应用中,业务逻辑和数据模型被错误地分开在不同的层或类中,导致代码难以维护和扩展。下面我将通过一个具体例子说明这个问题。
4. 信息专家特点:
- 数据封装:将数据和处理数据的方法封装在同一个类中。
- 高内聚性:类具有高内聚性,每个类都专注于处理自己的数据。
- 低耦合度:类之间的耦合度降低,因为每个类都管理自己的数据。
5. 信息专家缺点:
- 过度封装:在某些情况下,可能会导致过度封装,使得类过于复杂。
- 职责不明确:在一些复杂的系统中,职责的划分可能不够明确。
6. 信息专家使用场景:
当系统中的类需要处理特定数据时,应考虑应用信息专家原则。
7. 信息专家案例
7.1 订单案例
考虑一个电子商务平台的订单管理系统,需要处理订单数据和相关业务逻辑。
实现前(违反信息专家原则):
public class Order {
private String orderId;
private double totalAmount;
private List<OrderItem> items;
private Customer customer;
private PaymentMethod paymentMethod;
// 仅包含基本的getter和setter方法
}
public class OrderService {
private List<Order> orders;
public void processOrderPayment(Order order) {
// 处理订单支付逻辑
// 可能包括验证支付方法、计算总金额等
}
}
实现后(遵循信息专家原则):
public class Order {
private String orderId;
private List<OrderItem> items;
private Customer customer;
private PaymentMethod paymentMethod;
private OrderStatus status;
public Order(String orderId, Customer customer, PaymentMethod paymentMethod) {
this.orderId = orderId;
this.customer = customer;
this.paymentMethod = paymentMethod;
this.status = OrderStatus.PENDING;
this.items = new ArrayList<>();
}
public void addItem(OrderItem item) {
items.add(item);
updateTotalAmount();
}
private void updateTotalAmount() {
double total = items.stream().mapToDouble(OrderItem::getTotalPrice).sum();
// 更新订单总金额逻辑
}
public void processPayment() {
if (paymentMethod.isValid()) {
paymentMethod.charge(getTotalAmount());
status = OrderStatus.COMPLETED;
} else {
status = OrderStatus.FAILED;
}
}
public double getTotalAmount() {
return items.stream().mapToDouble(OrderItem::getTotalPrice).sum();
}
public OrderStatus getStatus() {
return status;
}
// 其他与订单相关的业务逻辑
}
public class OrderItem {
private Product product;
private int quantity;
private double price;
public double getTotalPrice() {
return price * quantity;
}
// 其他与订单项相关的业务逻辑
}
public class Customer {
private String customerId;
private String name;
private String email;
// 客户相关业务逻辑
}
public class PaymentMethod {
private String paymentDetails;
public boolean isValid() {
// 验证支付方法逻辑
return true;
}
public void charge(double amount) {
// 处理支付逻辑
}
// 其他与支付方法相关的业务逻辑
}
public class OrderService {
private List<Order> orders;
public void placeOrder(Order order) {
orders.add(order);
order.processPayment();
}
public void cancelOrder(Order order) {
order.setStatus(OrderStatus.CANCELED);
}
}
public enum OrderStatus {
PENDING, COMPLETED, CANCELED, FAILED
}
8、信息专家原则和充血模型两者区别:
信息专家原则:
- 定义:信息专家原则是GRASP原则之一,它建议将处理特定数据的责任分配给最了解这些数据的类。
- 目的:该原则的目的是确保每个类都封装了与其数据相关的所有业务逻辑,从而提高代码的内聚性和可维护性。
- 应用:信息专家原则通常应用于类级别的设计,强调将数据和行为封装在同一个类中。
- 关注点:该原则关注的是数据的封装和相关行为的封装,确保类对其数据拥有完整的控制权。
充血模型:
- 定义:充血模型是一种软件设计模式,其中领域对象包含业务逻辑和状态管理,而不仅仅是数据和访问器。
- 目的:充血模型的目的是创建一个高度模块化和可维护的系统,其中领域对象负责自己的行为和状态。
- 应用:充血模型通常应用于整个系统的架构设计,强调领域对象的自足性和业务逻辑的封装。
- 关注点:该模型关注的是将业务逻辑封装在领域对象内部,使得领域对象能够独立地执行其业务规则。
区别:
- 设计层面:
- 信息专家原则更侧重于类级别的设计,强调数据和行为的封装。
- 充血模型更侧重于系统架构层面,强调整个系统的模块化和领域对象的自足性。
- 设计哲学:
- 信息专家原则是一种设计原则,强调数据和行为的封装,使得类成为其数据的“专家”。
- 充血模型是一种设计模式,强调领域对象的完整性和自足性,使得领域对象能够独立地执行业务逻辑。
- 实现方式:
- 信息专家原则的实现通常涉及到将相关的数据和行为封装在同一个类中。
- 充血模型的实现涉及到将业务逻辑和状态管理封装在领域对象内部,使得领域对象能够独立地执行其业务规则。
- 目的:
- 信息专家原则的目的是提高代码的内聚性和可维护性。
- 充血模型的目的是创建一个高度模块化和可维护的系统,使得领域对象能够独立地执行业务逻辑。
9. 参考开源框架:
许多领域驱动设计(DDD)框架,如Axon Framework和Apache Isis,都遵循信息专家原则来组织代码。
10. 总结:
信息专家原则是GRASP原则中的一个重要组成部分,它通过将数据和行为封装在同一个类中,提高了代码的内聚性和可维护性。遵循信息专家原则有助于创建一个清晰、直观的系统结构,简化了数据管理。虽然在某些情况下可能需要权衡封装的程度,但总体而言,信息专家原则为构建健壮、可维护的软件系统提供了坚实的基础。
转载自:https://juejin.cn/post/7395866920895643700