我在读这篇文章,了解为什么getter和setters邪恶。本文没有说过 不要 使用它们,而是告诉您以限制使用这些方法的方式进行思考,或者引用该文章:
getter
setters
不要要求您进行工作所需的信息;询问具有信息的对象为您完成工作。
当您需要在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的那些时间之一吗?
JTextField
JTable
Allen Holub的文章(您提到的那篇文章)是完全正确的,至少在进行面向对象时,您不应该索要数据。不,显示事物不是打开对象的有效借口。
如果您有个Book,则要求Book使其显示!它不应该不管是否使用一个JTextField或JTable或什么的。当然,根据您的要求,您可以执行以下操作:
Book
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()将该组件简单地放置到想要在其中显示书的任何回转容器中。
add()