小编典典

封装和吸气剂

java

我在读这篇文章,了解为什么gettersetters邪恶。本文没有说过 不要
使用它们,而是告诉您以限制使用这些方法的方式进行思考,或者引用该文章:

不要要求您进行工作所需的信息;询问具有信息的对象为您完成工作。

当您需要在GUI中显示数据但没有getter方法时会发生什么?本文简要介绍了这一点,但并不完整。它提到将JComponent传递给类,但是如果您要进行GUI更改,则可能需要进行很多工作才能修复。

例如,您有一个Book类(限制此示例以使其易于阅读)。

public final class Book {

    private String title;
    //Authors is class with the attributes authorFirstname, authorLastname
    private List<Author> listofAuthors;


    public Book(String title, List<Author> listofAuthors)
    {
        //initialization
    }

    //other methods that do work
}

如果我有一个GUI,该GUI
JTextField可以显示书名和一个JTable显示作者列表,那么我将如何编写方法为我“完成工作”并显示结果?这getter是需要a的那些时间之一吗?


阅读 212

收藏
2020-11-01

共1个答案

小编典典

Allen Holub的文章(您提到的那篇文章)是完全正确的,至少在进行面向对象时,您不应该索要数据。不,显示事物不是打开对象的有效借口。

如果您有个Book,则要求Book使其显示!它不应该不管是否使用一个JTextFieldJTable或什么的。当然,根据您的要求,您可以执行以下操作:

public final class Book {
    ...
    JComponent display() {
        ...
    }
}

当然,面向对象的要点是您要尝试本地化更改(尽可能限制为一类)。唯一的方法是将依赖于相同事物的功能本地化(最好是)相同的类。也称为增加“内聚力”。

因此,现在,如果Book内部结构发生变化,则所有内容(包括如何Book显示)都在其Book本身内,因此无需“搜寻”使用的代码Book

现在,答案是“干净”的,因为您正在将演示代码与“业务逻辑”混合在一起。可能有趣的是,不将演示文稿与“业务逻辑”混合在一起的整个想法来自早期,那时我们仍然认为演示文稿可能是“远程”到“业务对象”的,而“业务对象”可能是由多个应用程序用于不同的事物。就是
多层设计。YAGNI。大多数时候,没有真正的理由在单个应用程序中具有人为的技术界限。只要Book知道它是GUI应用程序的一部分,就不会造成任何危害,并且拥有真正的好处(可维护性)。

编辑:这是`display()方法的详细显示方式,其中显示了标题和作者(Swing的伪代码):

public final class Book {
    private final String title;
    private final List<Author> authors;
    ...
    public JComponent display() {
        JPanel bookPanel = new JPanel();
        bookPanel.add(new JLabel(title));
        JList authorsList = new JList(); // Or similar
        for (Author author: authors) {
            authorsList.add(author.display());
        }
        bookPanel.add(authorsList);
        return bookPanel;
    }
}

然后,您可以add()将该组件简单地放置到想要在其中显示书的任何回转容器中。

2020-11-01