迪米特法则
迪米特法则 (Law of Demeter, LoD)
迪米特法则(Law of Demeter, LoD),也被称为最少知识原则(Principle of Least Knowledge),是面向对象设计中的一条重要原则。它的核心思想是:一个对象应该对其他对象有尽可能少的了解。具体来说,一个对象只应该与它直接交互的对象交流,而不应该依赖于间接关系的对象。
1. 原则解释
迪米特法则规定,每一个对象都应该对其他对象有最少的了解,只与直接的朋友进行交流,而不依赖于陌生人。这一原则可以用以下规则来描述:
- 一个对象应该只调用它直接持有的对象的方法。
- 一个对象不应该调用返回其他对象的方法链上的方法。
- 一个对象不应该调用全局变量的方法。
遵循这一原则有以下好处:
- 降低耦合度:减少对象之间的依赖关系,提高系统的模块化程度。
- 提高系统的可维护性:当系统发生变化时,修改的影响范围较小,降低了维护成本。
- 增强代码的可读性:每个对象的职责更加明确,代码更易于理解。
2. 违反迪米特法则的例子
假设我们有一个电商系统,其中有一个客户类 Customer
和一个订单类 Order
,订单类包含了支付信息类 PaymentInfo
。在没有遵循迪米特法则的设计中,我们可能会看到如下代码:
public class PaymentInfo {
private String creditCardNumber;
private String billingAddress;
// getter 和 setter 方法
}
public class Order {
private PaymentInfo paymentInfo;
public PaymentInfo getPaymentInfo() {
return paymentInfo;
}
public void setPaymentInfo(PaymentInfo paymentInfo) {
this.paymentInfo = paymentInfo;
}
}
public class Customer {
private Order order;
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
public class Main {
public static void main(String[] args) {
Customer customer = new Customer();
Order order = customer.getOrder();
String billingAddress = order.getPaymentInfo().getBillingAddress();
System.out.println("Customer billing address: " + billingAddress);
}
}
在这个例子中,Main
类通过 customer
对象调用 getOrder()
方法获取 Order
对象,然后通过 Order
对象调用 getPaymentInfo()
方法获取 PaymentInfo
对象,最后获取账单地址。这违反了迪米特法则,因为 Main
类对 Order
和 PaymentInfo
都有过多的了解。
3. 遵循迪米特法则的改进
为了遵循迪米特法则,我们可以引入一个中介方法,使得 Main
类只与 Customer
类直接交互,而不依赖于 Order
和 PaymentInfo
的内部结构。
public class PaymentInfo {
private String creditCardNumber;
private String billingAddress;
// getter 和 setter 方法
}
public class Order {
private PaymentInfo paymentInfo;
public PaymentInfo getPaymentInfo() {
return paymentInfo;
}
public void setPaymentInfo(PaymentInfo paymentInfo) {
this.paymentInfo = paymentInfo;
}
}
public class Customer {
private Order order;
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
// 中介方法,遵循迪米特法则
public String getBillingAddress() {
return order.getPaymentInfo().getBillingAddress();
}
}
public class Main {
public static void main(String[] args) {
Customer customer = new Customer();
String billingAddress = customer.getBillingAddress();
System.out.println("Customer billing address: " + billingAddress);
}
}
在这个改进后的设计中,Main
类通过 Customer
类的 getBillingAddress()
方法获取账单地址,而不再直接与 Order
和 PaymentInfo
类交互。这使得 Main
类对 Order
和 PaymentInfo
的内部结构了解最小化,遵循了迪米特法则。
4. 具体使用示例
让我们来看一个更复杂的例子,展示如何在实际开发中遵循迪米特法则。
// 用户类
public class User {
private String name;
private Wallet wallet;
public User(String name, Wallet wallet) {
this.name = name;
this.wallet = wallet;
}
public String getName() {
return name;
}
public Wallet getWallet() {
return wallet;
}
// 中介方法,获取用户余额
public double getBalance() {
return wallet.getBalance();
}
}
// 钱包类
public class Wallet {
private double balance;
public Wallet(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
// 主类
public class Main {
public static void main(String[] args) {
Wallet wallet = new Wallet(1000.0);
User user = new User("Alice", wallet);
double balance = user.getBalance();
System.out.println(user.getName() + " has a balance of " + balance);
}
}
在这个例子中,Main
类通过 User
类的 getBalance()
方法获取用户余额,而不直接访问 Wallet
类。这遵循了迪米特法则,使得 Main
类对 Wallet
类的了解最小化,增强了系统的模块化和可维护性。
5. 总结
迪米特法则是面向对象设计中的基本原则之一,通过确保对象之间的低耦合,可以提高系统的模块化程度和可维护性。在实际开发中,遵循迪米特法则有助于我们设计出高质量的代码,使系统更加稳定和易于扩展。
希望这个博客对你有所帮助。如果你有任何问题或需要进一步的例子,请随时告诉我!
原文地址:https://blog.csdn.net/qq_42798343/article/details/140422338
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!