微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 用于显示的Getters

我正在研究吸气剂/孵化器,一般的想法是它们是邪恶的,应该避免.您应该让对象完成工作,并生成结果.

阅读材料:

Why getter and setter methods are evil

Are getters and setters poor design? Contradictory advice seen

Why use getters and setters?

考虑到所有这些,假设我有一个看起来像这样的Book类:

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
    }

}

如果我有一个用户界面(例如JavaFX,网页等等),并希望我的课程变得灵活,那么包括标题的getter,listofAuthors和用于显示目的的numberofpages是否会打破封装?

例:

//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());
    }
}

要么

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

问题:

>在循环中调用getTitle()或getAuthors()
封装?
>如果上述问题的答案是肯定的,那么如果isWrittenBy()返回,我将如何显示该书
真正?我如何收集我图书馆的所有作者?

解决方法

对象的属性与对象的实现细节之间存在差异.

>一本书有一个标题 – 这不是一个实现细节.
>一本书有作者 – 这不是一个实现细节.
>如何存储图书的作者 – 这可以是一个实现细节.

吸气剂不是邪恶的,但您必须小心使用它们,因为它们可能会暴露实施细节,从而限制对实施的更改.

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

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

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

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

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

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

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

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

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

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

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

我们必须将作者收集到一个新列表中,或者更改getAuthors()的签名,但这会影响期望返回List的调用者.

相反,代码应该只返回一个Collection.这不会暴露作者存储的实现细节.

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

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

那么,getTitle()是否打破了封装?不,绝对不是.

getAuthors()是否会破坏封装?取决于它的回报,以及你所承诺的.如果它返回一个Collection,那么没有.如果它返回一个List并且你没有承诺有序的结果,那么是的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐