封装和吸气剂

我正在读这篇关于为什么gettersetters是邪恶的文章。 文章并没有说永远不会使用它们,但是,它告诉你以限制这些方法的使用的方式思考,或引用文章:

不要求您提供完成工作所需的信息; 请询问有信息的对象为您完成工作。

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

举个例子,你有一个Book类(限制这个例子以保持它的可读性)。

 public final class Book { private String title; //Authors is class with the attributes authorFirstname, authorLastname private List listofAuthors; public Book(String title, List listofAuthors) { //initialization } //other methods that do work } 

如果我有一个具有JTextField以显示书名的GUI和一个显示作者列表的JTable ,我将如何编写我的方法来为我“完成工作”并显示结果? 这是否需要getter

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

如果你有一Book ,只要求Book显示! 无论是使用JTextField还是JTable JTextField无关紧要。 当然,根据您的要求,您可以:

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

对象定位的重点当然是您尝试本地化更改(尽可能限制到一个类)。 唯一的方法是将依赖于相同内容的function本地化到(最好)同一个类中。 也称为增加“凝聚力”。

所以现在,如果Book internals发生了变化,所有的东西,包括Book的显示方式都在Book本身,所以没有必要“寻找”使用Book代码。

现在,对于这不是“干净”的答案,因为您将表示代码与“业务逻辑”混合在一起。 值得注意的是,没有将表示与“业务逻辑”混合在一起的整个想法来自早期,当时我们仍然认为表示可能“远离”“业务对象”,其中“业务对象”可能是多个应用程序用于不同的事情。 IE浏览器。 多层设计。 YAGNI 。 大多数情况下,没有真正的理由在单个应用程序中具有人为的技术边界。 如果Book知道它是GUI应用程序的一部分,并且有真正的好处(可维护性),则不会造成任何伤害。

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

 public final class Book { private final String title; private final List 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()到你想要显示书籍的任何摇摆容器中。

可以这样想:Getters(公共函数)是私有属性的桥梁。

我将为您编写一个使用OOP修改TextField的简单示例。

书类:

 public final class Book { private String title; //Authors is class with the attributes authorFirstname, authorLastname private List listofAuthors; public Book(String title, List listofAuthors) { //initialization } public String getTitle() { return this.title; } } 

GUI:

 author1 = new Author("jhon"); author 2 = new Author("alsojhon"); list = new ArrayList(); list.add(author1); list.add(author2) b = new Book("stack",list); JTextField field; field.setText(b.getTitle()); 

您可以创建三种类:

  1. 实体,表示业务概念并且只有一个唯一ID的类,例如具有Id用户名的Client类。 它通常是一个可变类。 你应该拥有所有业务逻辑。 你不应该用getter和setter打开他的数据。

  2. 值对象,表示业务概念但没有唯一ID的类,如Email类。 它通常是一个不可变的类。 你应该拥有所有业务逻辑。

  3. 数据结构(DTO的种类),只保存数据的类,没有行为,也许你有setter和getter来访问这些数据。

如果我没有加密器,如果需要访问所有客户端数据,我该怎么办? 那么,您应该将客户端转换为DTO。 你可以使用像Orika这样的框架。 或者,您可以在Client类中创建一个方法来询问信息(中介模式)。

我喜欢第二种选择,但它意味着更多的工作:

 class Client{ private String name; ... public void publishInfo(ClientInfo c){ c.setName(name); ... } } class ClientInfo{ private String name; //GETTERS //SETTERS } 

您是否在询问有关显示所有信息的方法? 我没跟着。

如果这就是你要问的,这是我的建议:不要在课程中写入窗口代码。 它不会很干净。 使用该方法创建一个新类(是的,getter是必要的,它们使OOP更容易,但这是有偏见的)。

如果我想遍历列表,我做的是创建一个StringBuilder,以及一个for循环,它添加了作者的名字。 然后,让该方法返回作者列表。

 List a; StringBuilder d = new StringBuilder(); for (int i = 0; i < a.size(); i++) { d.append(a.get(i).getName() + ", "); } return d.toString(); //It's just sudo code, but still.