加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 用于显示的Getters

发布时间:2020-12-15 04:40:46 所属栏目:Java 来源:网络整理
导读:我正在研究吸气剂/孵化器,一般的想法是它们是邪恶的,应该避免.您应该让对象完成工作,并生成结果. 阅读材料: Why getter and setter methods are evil Are getters and setters poor design? Contradictory advice seen Why use getters and setters? 考虑到
我正在研究吸气剂/孵化器,一般的想法是它们是邪恶的,应该避免.您应该让对象完成工作,并生成结果.

阅读材料:

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并且你没有承诺有序的结果,那么是的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读