迪米特法则(Law Of Demeter)

迪米特法则,也称最少知道原则(Principle of Least Knowledge)或者说接口隔离原则(Interface Segregation Principle,ISP),是一种面向对象设计的指导原则。它强调一个对象应该只和其直接相关的对象交互,而不应该和其他不直接相关的对象交互。具体来说,迪米特法则要求我们尽可能地减少对象之间的耦合性,让对象之间的关系保持简单和清晰。

迪米特法则是一个非常有用的设计原则,它可以有效地减少代码维护的工作量,提高代码的可读性、可维护性和健壮性。下面我们将详细介绍迪米特法则的核心思想、使用方法以及一些实际案例。

一、核心思想

迪米特法则的核心思想可以归纳为以下两点:

1. 最小暴露原则

对象应该只暴露其必要的最小接口,即只提供其直接需要的方法和属性,不应该暴露其不必要的细节和实现。

2. 对象间的松耦合

对象之间应该保持松耦合关系,即一个对象不应该过多地依赖其他对象的信息,而是应该通过接口来实现相互之间的通信和协作。

二、使用方法

为了遵守迪米特法则,我们可以采取以下几种方法:

1. 对象之间的通信应该通过接口来实现

一个对象应该只知道其直接相邻的对象,而不应该知道其他不直接相关的对象。可以通过接口来实现对象之间的间接通信。

2. 避免链式调用

链式调用会增加对象之间的耦合度,应该避免链式调用,让每个对象只负责完成自己的任务。

3. 采用代理模式

在一些复杂的情况下,为了遵守迪米特法则,我们可以采用代理模式来实现对象之间的通信,这样可以减少对象之间的直接依赖。

三、案例说明

1. 一个图书馆管理系统

我们来看一个简单的图书馆管理系统的例子,在该系统中包含了用户(User)、图书馆(Library)、图书(Book)三个类。从代码层面来看,我们可以将它们设计成如下的关系:

```

class User {

String name;

List borrowedBooks;

public User(String name) {

this.name = name;

this.borrowedBooks = new ArrayList<>();

}

public void borrowBook(Book book) {

if (book != null) {

borrowedBooks.add(book);

book.setBorrowedBy(this);

}

}

}

class Library {

List books;

public Library(List books) {

this.books = books;

}

public Book borrowBook(int index) {

if (index >= 0 && index < books.size()) {

Book book = books.get(index);

books.remove(index);

return book;

}

return null;

}

}

class Book {

String name;

User borrowedBy;

public Book(String name) {

this.name = name;

}

public void setBorrowedBy(User user) {

this.borrowedBy = user;

}

public User getBorrowedBy() {

return borrowedBy;

}

}

```

在这个设计中,Book类持有了User类的引用,而User类持有了Book类的引用。如果遵守迪米特法则,我们可以将其改成如下的设计:

```

class User {

String name;

List borrowedBooks;

public User(String name) {

this.name = name;

this.borrowedBooks = new ArrayList<>();

}

public void borrowBook(Book book) {

if (book != null) {

borrowedBooks.add(book);

book.setBorrowed(true);

}

}

}

class Library {

List books;

public Library(List books) {

this.books = books;

}

public Book borrowBook(int index) {

if (index >= 0 && index < books.size()) {

Book book = books.get(index);

books.remove(index);

book.setBorrowed(true);

return book;

}

return null;

}

}

class Book {

String name;

boolean borrowed;

public Book(String name) {

this.name = name;

this.borrowed = false;

}

public boolean isBorrowed() {

return borrowed;

}

public void setBorrowed(boolean borrowed) {

this.borrowed = borrowed;

}

}

```

在新的设计中,User和Library类不再持有Book类的引用,而是通过Book类的状态(isBorrowed())来判断它是否可借阅,从而实现了更低的耦合度。

2. 一个在线购物网站

再来看一个在线购物网站的例子,在该网站中包含了客户端(Client)、商品(Product)、购物车(Cart)以及支付系统(Payment)四个类。从代码层面来看,我们可以将它们设计成如下的关系:

```

class Client {

List boughtProducts;

Cart cart;

public Client() {

this.cart = new Cart();

}

public void addProductToCart(Product product) {

cart.addProduct(product);

}

public void buy() {

List products = cart.getProducts();

for (Product product : products) {

Payment payment = new Payment(product.getPrice());

payment.pay();

boughtProducts.add(product);

}

cart.clear();

}

}

class Product {

String name;

double price;

public Product(String name, double price) {

this.name = name;

this.price = price;

}

public double getPrice() {

return price;

}

}

class Cart {

List products;

public Cart() {

this.products = new ArrayList<>();

}

public void addProduct(Product product) {

products.add(product);

}

public List getProducts() {

return products;

}

public void clear() {

products.clear();

}

}

class Payment {

double amount;

public Payment(double amount) {

this.amount = amount;

}

public void pay() {

System.out.println("Amount " + amount + " paid");

}

}

```

在这个设计中,Client类持有了Cart类和Payment类的引用。如果遵守迪米特法则,我们可以将其改成如下的设计:

```

class Client {

List boughtProducts;

Cart cart;

public Client() {

this.cart = new Cart();

}

public void addProductToCart(Product product) {

cart.addProduct(product);

}

public void buy() {

List products = cart.getProducts();

for (Product product : products) {

Payment payment = new Payment(product.getPrice());

payment.pay();

boughtProducts.add(product);

}

cart.clear();

}

}

class Product {

    String name;

    double price;

 

    public Product(String name, double price) {

        this.name = name;

        this.price = price;

    }

 

    public double getPrice() {

        return price;

    }

}

 

class Cart {

    List products;

 

    public Cart() {

        this.products = new ArrayList<>();

    }

 

    public void addProduct(Product product) {

        products.add(product);

    }

 

    public List getProducts() {

        return products;

    }

 

    public void clear() {

        products.clear();

    }

 

    public void pay(double amount) {

        Payment payment = new Payment(amount);

        payment.pay();

    }

}

 

class Payment {

    double amount;

 

    public Payment(double amount) {

        this.amount = amount;

    }

 

    public void pay() {

        System.out.println("Amount " + amount + " paid");

    }

}

```

在新的设计中,Client类只和Cart类交互,Cart类只和Payment类交互,这样可以实现对象之间的松耦合,从而更加符合迪米特法则。

四、总结

迪米特法则是一个非常重要的设计原则,它可以帮助我们设计出更加健壮、可维护、可扩展的代码。我们应该时刻保持该原则的意识,尽可能地减少对象之间的耦合性,让对象之间的关系保持简单和清晰。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(42) 打赏

评论列表 共有 1 条评论

万事无关我 1年前 回复TA

马踏飞燕春正好,锣鼓喧天人欢笑。剪纸春联红艳艳,隽刻无限好心愿。爆竹烟花震天响,诉说快乐心欢畅。春节到来祝福忙,送君身旁君安康。春节快乐。

立即
投稿
发表
评论
返回
顶部