目录
前言
设计模式是软件工程中的一种通用解决方案,而反模式则是指在软件开发过程中经常遇到的不良实践或错误决策。UML(统一建模语言)是一种用于软件工程的图形化语言,帮助开发者描述系统的设计和架构。在使用UML进行系统建模时,也存在一些常见的误用案例。
反模式:过度细化类图
误用描述: 过度细化类图指的是在一个类图中包含了过多的细节,使得类图变得复杂且难以理解。这通常发生在试图将所有实现细节都放入类图中的时候。
案例一:假设正在设计一个简单的博客系统
// 过度细化的类图示例
public class BlogPost {
private String title;
private String content;
private Date publishDate;
private User author;
private List<Comment> comments;
private int likeCount;
private boolean isPublished;
public BlogPost(String title, String content, User author) {
this.title = title;
this.content = content;
this.author = author;
this.isPublished = false;
}
// 以下是不必要的细节
public void setPublishDate(Date date) { this.publishDate = date; }
public Date getPublishDate() { return publishDate; }
public void addComment(Comment comment) { comments.add(comment); }
public List<Comment> getComments() { return Collections.unmodifiableList(comments); }
public void incrementLikeCount() { likeCount++; }
public int getLikeCount() { return likeCount; }
public void publish() { isPublished = true; }
public boolean isPublished() { return isPublished; }
}
UML 类图 (简化版):
+----------------+
| BlogPost |
+----------------+
| -title: String |
| -content: String|
| -author: User |
+----------------+
| +BlogPost(title, content, author) |
| +publish() : void |
| +isPublished() : boolean |
+----------------+
注:上文展示一个博客文章的简化类图。原始的代码包含了很多细节,如发表日期、评论列表、点赞数等,这些在高层次的设计阶段并不是必要的。通过去除这些细节,我们可以更清晰地看到博客文章的核心属性和行为,例如标题、内容和作者信息,以及发布状态的方法。
如何避免此类反模式
- 关注高层次的设计:在设计初期,专注于系统的高层次结构而不是具体的实现细节。
- 逐步细化:随着项目的进展,逐步添加更多的细节到类图中。
- 分离关注点:如果发现某个类承担了太多责任,考虑将其拆分为多个更小、更专注的类。
案例二:假设要设计一个简单的在线购物车系统
// 过度细化的类图示例
public class ShoppingCart {
private List<Item> items;
private double totalPrice;
private boolean isCheckoutCompleted;
private PaymentMethod paymentMethod;
private ShippingAddress shippingAddress;
private String orderNumber;
public ShoppingCart() {
this.items = new ArrayList<>();
this.totalPrice = 0.0;
this.isCheckoutCompleted = false;
this.paymentMethod = null;
this.shippingAddress = null;
this.orderNumber = "";
}
public void addItem(Item item) {
items.add(item);
totalPrice += item.getPrice();
}
public void removeItem(Item item) {
items.remove(item);
totalPrice -= item.getPrice();
}
public void completeCheckout(PaymentMethod paymentMethod, ShippingAddress address) {
this.paymentMethod = paymentMethod;
this.shippingAddress = address;
isCheckoutCompleted = true;
orderNumber = generateOrderNumber();
}
private String generateOrderNumber() {
// 生成订单号的逻辑
return "ORDER-" + new Date().getTime();
}
public double getTotalPrice() {
return totalPrice;
}
public boolean isCheckoutCompleted() {
return isCheckoutCompleted;
}
}
UML 类图 (过度细化版本):
+----------------------+
| ShoppingCart |
+----------------------+
| -items: List<Item> |
| -totalPrice: double |
| -isCheckoutCompleted: boolean|
| -paymentMethod: PaymentMethod|
| -shippingAddress: ShippingAddress|
| -orderNumber: String |
+----------------------+
| +ShoppingCart() |
| +addItem(Item): void |
| +removeItem(Item): void |
| +completeCheckout(PaymentMethod, ShippingAddress): void |
| +generateOrderNumber(): String|
| +getTotalPrice(): double |
| +isCheckoutCompleted(): boolean|
+----------------------+
改进后的设计
改进后代码:
public class ShoppingCart {
private List<Item> items;
public ShoppingCart() {
this.items = new ArrayList<>();
}
public void addItem(Item item) {
items.add(item);
}
public void removeItem(Item item) {
items.remove(item);
}
public void checkout(CheckoutService checkoutService) {
checkoutService.completeCheckout(this);
}
}
interface CheckoutService {
void completeCheckout(ShoppingCart cart);
}
class SimpleCheckoutService implements CheckoutService {
@Override
public void completeCheckout(ShoppingCart cart) {
// 完成结账的具体逻辑
}
}
UML 类图 (改进版本):
+----------------------+
| ShoppingCart |
+----------------------+
| -items: List<Item> |
+----------------------+
| +ShoppingCart() |
| +addItem(Item): void |
| +removeItem(Item): void|
| +checkout(CheckoutService): void|
+----------------------+
+----------------------------+
| CheckoutService (接口) |
+----------------------------+
| -completeCheckout(ShoppingCart): void|
+----------------------------+
+------------------------------------+
| SimpleCheckoutService (实现) |
+------------------------------------+
| +completeCheckout(ShoppingCart): void|
+------------------------------------+
注: 在这个改进后的设计中,将购物车的职责限制为管理商品项,并引入CheckoutService
接口来处理结账过程。这样做的好处是:
- 购物车类变得更加简单,只关注于添加和移除商品。
- 结账的具体逻辑被移到了
CheckoutService
中,使得购物车类图更加简洁。 SimpleCheckoutService
实现了CheckoutService
接口,负责完成结账的实际工作。