封装和吸气剂

时间:2017-04-30 15:30:26

标签: java oop methods encapsulation getter

我正在阅读此article,了解为什么{% trans_default_domain 'FOSUserBundle' %} {% if error %} <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div> {% endif %} <form action="{{ path("fos_user_security_check") }}" method="post"> {% if csrf_token %} <input type="hidden" name="_csrf_token" value="{{ csrf_token }}" /> {% endif %} <label for="username">{{ 'security.login.username'|trans }}</label> <input type="text" id="username" name="_username" value="{{ last_username }}" required="required" /> <label for="password">{{ 'security.login.password'|trans }}</label> <input type="password" id="password" name="_password" required="required" /> <input type="checkbox" id="remember_me" name="_remember_me" value="on" /> <label for="remember_me">{{ 'security.login.remember_me'|trans }}</label> <input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}" /> </form> getter是邪恶的。文章并没有说永远使用它们,但是,它告诉你以限制这些方法的使用的方式思考,或者引用文章:< / p>

  

请勿提供完成工作所需的信息;问对象   有信息为你工作。

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

例如,您有一个Book类(使此示例仅限于保持其可读性)。

setters

如果我的GUI有一个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 } 来显示书名,而JTextField来显示作者列表,我将如何编写我的方法来做&#34;做好工作&#34 34;对我来说并显示结果?这是否需要JTable

4 个答案:

答案 0 :(得分:1)

以这种方式思考:Getters(公共函数)是私有属性的桥梁。

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

图书课程:

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
}
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 :(得分:1)

您可以创建三种类:

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

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

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

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

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

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

答案 2 :(得分:1)

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

如果您有Book,只需要Book显示自己!无论是使用JTextField还是JTable还是其他任何内容都无关紧要。根据您的要求,您可以这样做:

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

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

现在,如果Book内部更改,所有内容(包括Book的显示方式)都在Book本身,因此无需“追捕”对于使用Book的代码。

现在,对于这不是“干净”的答案,因为您正在将演示代码与“业务逻辑”混合在一起。值得注意的是,没有将表示与“业务逻辑”混合在一起的整个想法来自早期,当时我们仍然认为表示可能是“远程”到“业务对象”,其中“业务对象”可能是多个应用程序用于不同的事情。 IE浏览器。多层设计。 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()该组件到你想要显示书籍的任何摇摆容器。

答案 3 :(得分:0)

您是否在询问为您显示所有信息的方法?我不跟随。

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

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

List<Authors> 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.