前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面向对象设计原则-迪米特法则示例

面向对象设计原则-迪米特法则示例

原创
作者头像
堕落飞鸟
发布2023-05-05 14:49:41
1950
发布2023-05-05 14:49:41
举报
文章被收录于专栏:飞鸟的专栏

假设有一个图书馆系统,其中包含了三个类:Book(书籍)、Library(图书馆)和User(用户)。其中,Book类表示一本书籍,包含了书名、作者等信息;Library类表示一个图书馆,包含了图书馆的名称、地址等信息,同时还有添加书籍、借出书籍等方法;User类表示一个用户,包含了用户的姓名、电话等信息,同时还有借书、还书等方法。下面给出相应的Java代码:

代码语言:javascript
复制
public class Book {
    private String title;
    private String author;
    private String publisher;
    
    public Book(String title, String author, String publisher) {
        this.title = title;
        this.author = author;
        this.publisher = publisher;
    }
    
    // 省略其他方法和属性的定义
}

public class Library {
    private String name;
    private String address;
    private List<Book> books;
    
    public Library(String name, String address) {
        this.name = name;
        this.address = address;
        this.books = new ArrayList<>();
    }
    
    public void addBook(Book book) {
        books.add(book);
    }
    
    public void lendBook(Book book, User user) {
        // 省略借出书籍的具体实现
    }
    
    // 省略其他方法和属性的定义
}

public class User {
    private String name;
    private String phone;
    private List<Book> borrowedBooks;
    
    public User(String name, String phone) {
        this.name = name;
        this.phone = phone;
        this.borrowedBooks = new ArrayList<>();
    }
    
    public void borrowBook(Book book, Library library) {
        // 省略借书的具体实现
    }
    
    public void returnBook(Book book, Library library) {
        // 省略还书的具体实现
    }
    
    // 省略其他方法和属性的定义
}

在上述代码中,Book、Library和User三个类之间的关系比较紧密,它们之间的交互比较频繁,没有遵守迪米特法则。下面对该系统进行重构,使用迪米特法则来设计系统。

首先,我们需要引入一个中间对象,来封装Book和User之间的交互。假设该中间对象命名为Borrow,表示借书记录。Borrow对象包含了借书日期、还书日期等信息。同时,Borrow对象还有一个引用Book对象和User对象,用于表示这本书是由哪个用户借阅的。下面给出Borrow类的定义:

代码语言:javascript
复制
typescriptCopy codepublic class Borrow {
    private Date borrowDate;
    private Date returnDate;
    private Book book;
    private User user;
    
    public Borrow(Book book, User user) {
        this.book = book;
        this.user = user;
        this.borrowDate = new Date();
    }
    
    public void returnBook() {
        this.returnDate = new Date();
        // 省略还书后的其他处理
    }
    
    // 省略其他方法和属性的定义
}

在上述代码中,Borrow类作为一个中间对象,负责封装Book和User之间的交互。通过引入Borrow类,Book和User之间的交互就变成了间接交互,而不是直接交互。

接下来,我们需要修改Library和User类,使其通过Borrow对象来进行交互。具体地,Library类在借出书籍时,创建一个新的Borrow对象,将这本书和用户信息保存在Borrow对象中。而User类在借书时,先通过Library对象获取这本书的信息,然后创建一个新的Borrow对象,将这本书和用户信息保存在Borrow对象中。下面给出相应的代码:

代码语言:javascript
复制
typescriptCopy codepublic class Library {
    private String name;
    private String address;
    private List<Book> books;
    private List<Borrow> borrows;
    
    public Library(String name, String address) {
        this.name = name;
        this.address = address;
        this.books = new ArrayList<>();
        this.borrows = new ArrayList<>();
    }
    
    public void addBook(Book book) {
        books.add(book);
    }
    
    public void lendBook(Book book, User user) {
        // 检查这本书是否可借
        if (!books.contains(book)) {
            throw new IllegalArgumentException("该图书馆没有这本书!");
        }
        for (Borrow borrow : borrows) {
            if (borrow.getBook().equals(book) && borrow.getReturnDate() == null) {
                throw new IllegalArgumentException("这本书已经被借走了!");
            }
        }
        // 创建一个新的借书记录
        Borrow borrow = new Borrow(book, user);
        borrows.add(borrow);
    }
    
    // 省略其他方法和属性的定义
}

public class User {
    private String name;
    private String phone;
    private List<Borrow> borrows;
    
    public User(String name, String phone) {
        this.name = name;
        this.phone = phone;
        this.borrows = new ArrayList<>();
    }
    
    public void borrowBook(Book book, Library library) {
        library.lendBook(book, this);
    }
    
    public void returnBook(Book book, Library library) {
        for (Borrow borrow : borrows){
        if (borrow.getBook().equals(book) && borrow.getReturnDate() == null) {
                borrow.returnBook();
                return;
            }
        }
        throw new IllegalArgumentException("你没有借过这本书!");
    }
    
    // 省略其他方法和属性的定义
}

在上述代码中,Library类的lendBook方法会创建一个新的Borrow对象,将这本书和用户信息保存在Borrow对象中,并将Borrow对象保存到borrows列表中。而User类的borrowBook方法会调用Library类的lendBook方法来借书,然后创建一个新的Borrow对象,将这本书和用户信息保存在Borrow对象中,并将Borrow对象保存到borrows列表中。User类的returnBook方法会遍历borrows列表,查找用户借阅的这本书对应的Borrow对象,并调用Borrow对象的returnBook方法来还书。

通过引入Borrow对象,Book和User之间的交互变成了间接交互,而不是直接交互。这样可以降低类之间的耦合度,提高系统的灵活性和扩展性。此外,Borrow对象还可以承担其他职责,例如记录借书日期和还书日期等信息,方便图书馆管理借阅记录。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档