[英]Refactoring the code of many similar methods
嗨,我的代码中有很多类似的方法,如下所示,也许将来还会有更多类似的方法。
public void getParticularBook(String nameOfBook){
String bookDetails = "";
Iterator<Book> iterator = allBooks.iterator();
while(iterator.hasNext()) {
Book b = iterator.next();
if(b.getTitle().equalsIgnoreCase(nameOfBook)){
bookDetails = b.toString();
}
}
System.out.println(bookDetails);
}
public void getBooksDataOnRange(int from, int to){
String bookDetails = "";
Iterator<Book> iterator = allBooks.iterator();
while(iterator.hasNext()) {
Book b = iterator.next();
if(b.getIssueYear() >= from && b.getIssueYear() <= to){
bookDetails = b.toString();
}
}
if(bookDetails.isEmpty()){
System.out.println("No books in range of: " + from + "-" + to);
}
System.out.println(bookDetails);
}
public void getBooksDataOnType(String type){
String bookDetails = "";
Iterator<Book> iterator = allBooks.iterator();
while(iterator.hasNext()) {
Book b = iterator.next();
if(b.getType().equalsIgnoreCase(type)){
bookDetails = b.toString();
}
}
if(bookDetails.isEmpty()){
System.out.println("No books of type: " + type);
}
System.out.println(bookDetails);
}
上面的方法是某种过滤器,其基于例如书的类型,书的发行日期返回数据。
问题是,是否可以重构所有这种方法的代码? 还是更好地遵循上述方案? 感谢您的回答
您可以创建一个名为getBooksWithPredicate
的方法:
public static void getBooksWithPredicate(Predicate<Book> predicate, String errorMessage) {
String bookDetails = "";
Iterator<Book> iterator = allBooks.iterator();
while(iterator.hasNext()) {
Book b = iterator.next();
if(predicate.test(b)){
bookDetails = b.toString();
}
}
if(bookDetails.isEmpty()){
System.out.println(errorMessage);
}
System.out.println(bookDetails);
}
这基本上是所显示的所有三种方法的概括。 然后可以通过调用此方法来实现这三种方法:
public void getParticularBook(String nameOfBook){
getBooksWithPredicate(b -> b.getTitle().equalsIgnoreCase(nameOfBook), "");
}
public void getBooksDataOnRange(int from, int to){
getBooksWithPredicate(b -> b.getIssueYear() >= from && b.getIssueYear() <= to, "No books in range of: " + from + "-" + to);
}
public void getBooksDataOnType(String type){
getBooksWithPredicate(b -> b.getType().equalsIgnoreCase(type), "No books of type: " + type);
}
您的问题有多种解决方案。
对于getParticularBook()
方法,您可以有一个单独的HashMap<String,Book>
,因此您不必每次都遍历所有书籍。 仅在没有重复项的情况下才有效。
对于getBooksDataOnRange()
方法,您可以具有HashMap<Integer, ArrayList<Book>>
,其中整数将是年份,而ArrayList将包含该年出版的书籍列表。 如果这里有内存问题,则可以使用HashMap<Integer, ArrayList<String>>
,在该目录中将存储书籍的名称,而不是存储书籍对象。 您可以从以前的HashMap获取book对象。
对于getBooksDataOnType()
方法,我想实际的要求是获取给定类型的所有书籍的数据。 如果一本书可以具有多种类型HashMap<String, ArrayList<String>>
在这里我建议使用HashMap<String, ArrayList<String>>
。 如果不是这样,并且如果内存不是您的问题,则可以为此使用HashMap<String, ArrayList<Book>>
。
这是指向HashMap和ArrayList的Java文档链接。 这将对您的实施有所帮助。
HashMap: https : //docs.oracle.com/javase/8/docs/api/java/util/HashMap.html
ArrayList: https : //docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html
有很多不同的选择可以做到这一点。 基本思想是,如果一本书与您的搜索匹配,则将书中的迭代与测试分开。
例如某种命令模式并传递比较两本书的方法:
public void getBooks(Book testAgainst, Comparator<Book> comparator){
iterate
comparator.compare(bookFromIterator, testAgainst);
print result if matches
}
然后,您可以将不同的比较器传递给该方法-例如标题比较器,年份比较器等。
另一种(也是一种更好的)方法是查看Hibernate如何查询数据。 创建类似“ BookSearchCriteria”类的内容。 就像是:
class BookSearchCriteria {
int fromYear;
int toYear;
String title;
public boolean matches(Book book){
... test for title, test for year etc...
}
}
您的方法将变为:
public void getBooks(BookSearchCriteria criteria){
iterator
....
if(criteria.matches(book)) then do stuff
}
这将是一个更好的示例,因为您可以通过多种方式扩展该条件-例如组合属性,使其成为AND或OR条件等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.