阅读材料:
Why getter and setter methods are evil
Are getters and setters poor design? Contradictory advice seen
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 举报,一经查实,本站将立刻删除。