重构许多类似方法的代码

时间:2018-04-16 07:55:00

标签: java refactoring

您好我的代码中有许多类似的方法,如下所示,将来我可能会有更多。

sbt

上述方法是某种过滤器,它基于例如数据返回数据。书的类型,书的发行日期。

问题是,如果可以重构所有那种方法的代码吗?或者更好地遵循以上方案? 谢谢你的回答

3 个答案:

答案 0 :(得分:4)

您可以创建一个名为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);
}

答案 1 :(得分:0)

您的问题有多种解决方案。

对于getParticularBook()方法,您可以单独使用HashMap<String,Book>,这样您就不必每次都遍历所有书籍。只有在没有重复的情况下,这才有效。

对于getBooksDataOnRange()方法,您可以使用HashMap<Integer, ArrayList<Book>>整数作为年份,ArrayList将包含该年份发布的图书列表。如果内存是一个问题,你可以有一个HashMap<Integer, ArrayList<String>>,而不是存储书籍对象,你将存储书的名称。您可以从之前的HashMap中获取book对象。

对于getBooksDataOnType()方法,我猜实际要求是获取给定类型的所有书籍的数据。如果一本书可以有多种类型,我建议HashMap<String, ArrayList<String>>。如果没有,并且如果内存不是您的问题,那么您可以拥有HashMap<String, ArrayList<Book>>

以下是HashMap和ArrayList的Java Documentation链接。这将有助于您实施。

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

答案 2 :(得分:0)

有很多不同的选择。如果书籍与您的搜索匹配,基本思想是将书籍上的迭代与测试分开。

例如某种命令模式并传递比较两本书的方法:

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标准等。