显示的吸气剂 [英] Getters for Display

查看:121
本文介绍了显示的吸气剂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 getters / setters ,一般的想法是它们是邪恶的,应该避免。您应该让对象完成工作,并生成结果。



阅读材料:



为什么getter和setter方法是邪恶的



是吸气鬼和二传手设计不佳?看到相反的建议



为什么要使用getter和setter?



考虑到所有这些,假设我有一本Book class 看起来像这样:

  publc final Book {

private final String title;
私人最终名单<作者> listofAuthors;
private final int numberofpages;

//构造函数未包含在示例中。

//标题,listofAuthors和numberofpages的getter

public int numberofpagesleft(int pagesRead){
//确定剩余页数的代码
}

public boolean isWrittenBy(作者作者){
//用于确定图书是否包含作者的代码
}

}

如果我有一个 UI (例如 JavaFX 网页等等。)并希望我的课程灵活,包括 getters for title listofAuthors numberofpages for显示目的中断封装



示例:

  //库是List< Book>集合,作者是Author类的对象。 
for(Book book:library){
if(book.isWrittenBy(author){
System.out.println(你的集合中的书籍由+ author.toString()+编写) include:);
System.out.println(book.getTitle());
}
}

(b book):
/ b /返回一个Collections.unmodifiableList()。
if(book.getAuthors(){
//在我的库中构建一组作者的代码
}
}

问题:


  1. 在循环中调用 getTitle() getAuthors() b $ b 封装


  2. 如果上述问题的答案为是,我将如何显示本书如果 isWrittenBy()返回
    true ?我如何收集我图书馆中的所有作者?



解决方案

有一个难度对象的属性和对象的实现细节之间的差异。




  • 一本书有一个标题 - 这不是一个实现细节。

  • 一本书有作者 - 这不是一个实现细节。

  • 如何存储一本书的作者 - 这可以是一个实现细节。



Getters不是邪恶的,但你必须小心使用它们,因为它们可以暴露实施细节,限制你的实现的变化。

  class Book {
private ArrayList< Author> authors = new ArrayList<>();

public ArrayList< Author> getAuthors(){return authors; }
}

由于两个原因,上述情况很糟糕。首先,它向调用者返回一个可修改的集合,允许调用者更改集合。其次,它向调用者承诺返回的集合是 ArrayList

 书本= ...; 
ArrayList< Author> authors = book.getAuthors();

我们通过包装集合修复第一个问题:

  class Book {
private ArrayList< Author> authors = new ArrayList<>();

public List< Author> getAuthors(){
return Collection.unmodifiableList(authors);
}
}

预订= ...;
列表<作者> authors = book.getAuthors();

现在调用者无法修改集合,但他们仍然承诺集合是列表。如果我们发现我们想要将我们的作者存储为 Set (因为作者不会多次创作一本书),我们不能简单地更改内部存储。

  class Book {
private HashSet< Author> authors = new HashSet<>();

public List< Author> getAuthors(){
return Collection.unmodifiableList(authors); //错误 - 作者不是列表
}
}

我们会有收集作者到新的列表,或更改 getAuthors()的签名,但这会影响希望返回 List 的来电者。



相反,代码应返回集合。这不会公开 authors 存储的实现细节。

  class Book {
public Collection< Author> getAuthors(){
return Collection.unmodifiableCollection(authors);
}
}

注意:可能是作者的订购,首先列出主要作者。在这种情况下,您可能希望返回 List 以向调用者承诺数据实际上已被订购。在这种情况下, List 不是实现细节,而是接口契约的一部分。



所以, getTitle()打破封装?绝对不是。



getAuthors()打破封装?取决于它的回报,以及你的承诺。如果它返回 Collection ,则为no。如果它返回列表并且您不承诺订购结果,那么是。


I was researching on getters/setters, and the general idea is that they are evil and should be avoided. You should let the object do the work, and produce the result.

Reading Material:

Why getter and setter methods are evil

Are getters and setters poor design? Contradictory advice seen

Why use getters and setters?

With all that in mind, suppose I have a Book class that looked like this:

publc final Book{

    private final String title;
    private final List<Authors> listofAuthors;
    private final int numberofpages;

    //constructor not included in example.

    //getters for title, listofAuthors, and numberofpages

    public int numberofpagesleft(int pagesRead){
        //code to determine number of pages left
    }

    public boolean isWrittenBy(Author author){
        //code to determine if book contains author
    }

}

If I had a UI(ex. JavaFX, webpage, etc..) and wanted my class to be flexible, would including the getters for title, listofAuthors and numberofpages for display purposes break encapsulation?

Example:

//library is an List<Book> collection, and author is an object of the Author class.
for (Book book : library){
    if(book.isWrittenBy(author){
      System.out.println("Books in your collection written by " + author.toString() + " include:" );
      System.out.println(book.getTitle());
    }
}

or

for (Book book : library){
    //returns a Collections.unmodifiableList().
    if(book.getAuthors(){
        //code to build a set of authors in my library
    }
}

Questions:

  1. Is calling getTitle() or getAuthors() in the loop breaking encapsulation?

  2. If the answer to the above question is yes, how would I display the book if isWrittenBy() returns true? and How would I gather all the authors in my library?

解决方案

There is a difference between attributes of an object, and implementation details of an object.

  • A book has a title - that is not an implementation detail.
  • A book has authors - that is not an implementation detail.
  • How authors of a book are stored - this can be an implementation detail.

Getters are not evil, but you must use them carefully, since they can expose implementation details which restrict changes to your implementation.

class Book {
    private ArrayList<Author> authors = new ArrayList<>();

    public ArrayList<Author> getAuthors() { return authors; }
}

The above is bad, for two reasons. First, it returns a modifiable collection to the caller, allowing the caller to change the collection. Second, it promises the caller that the returned collection is an ArrayList.

Book book = ...;
ArrayList<Author> authors = book.getAuthors();

We fixing the first problem by wrapping the collection:

class Book {
    private ArrayList<Author> authors = new ArrayList<>();

    public List<Author> getAuthors() {
        return Collection.unmodifiableList(authors);
    }
}

Book book = ...;
List<Author> authors = book.getAuthors();

Now the caller can't modify the collection, but they are still promised the collection is a List. If we find we want to store our authors as a Set (because an author doesn't author a book more than once), we cannot simply change the internal storage.

class Book {
    private HashSet<Author> authors = new HashSet<>();

    public List<Author> getAuthors() {
        return Collection.unmodifiableList(authors); // ERROR - authors not a list
    }
}

We would have to collect the authors into a new List, or change the signature of the getAuthors(), but that would impact the callers who expected a List to be returned.

Instead, the code should simply return a Collection. This does not expose the implementation detail of the storage of authors.

class Book {
    public Collection<Author> getAuthors() {
        return Collection.unmodifiableCollection(authors);
    }
}

Note: it could be that the authors are ordered, with the primary author listed first. In that case, you may want to return a List to promise the caller that the data is, in fact, ordered. In that case, the List is not an implementation detail, but rather part of the interface contract.

So, does getTitle() break encapsulation? No. Absolutely not.

Does getAuthors() break encapsulation? Depends what it returns, and what you are promising. If it returns a Collection, then no. If it returns a List and you are not promising ordered results, then yes.

这篇关于显示的吸气剂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆