需要帮助减少重复代码

时间:2014-03-25 17:00:50

标签: java duplication

我是初学者,讲师告诉我减少这两个功能中的重复代码。这是一个图书馆。我想我还需要一个方法来检查数组。我需要的是我需要使用的一些建议/原则。我会自己写这个方法。谢谢!     getBooks()返回存储Books的ArrayList。

public List<Book> getAvailableBooks() {
    List<Book> result = new ArrayList<Book>();
    for (int i = 0; i < this.getBooks().size(); i++) {
        if (this.getBooks().get(i).getPerson() == null) {
            result.add(this.getBooks().get(i));
        }
    }
    return result;
}

public List<Book> getUnavailableBooks() {
    List<Book> result = new ArrayList<Book>();
    for (int i = 0; i < this.getBooks().size(); i++) {
        if (this.getBooks().get(i).getPerson() != null) {
            result.add(this.getBooks().get(i));
        }
    }
    return result;
}

5 个答案:

答案 0 :(得分:2)

您已经有两种方法。你不能再增加一个来减少。

但是你可以有一种方法而不是两种方法。 e.g。

public List<Book> getBooks(boolean available) {

现在您有一种方法,您可以告诉它您是否需要可用或不可用的书籍。

答案 1 :(得分:1)

传入一个应该指示

的布尔参数
(this.getBooks().get(i).getPerson() == null)

应该评估,并添加条件来检查。即该表达式应该返回true还是false。

答案 2 :(得分:1)

这里有一些建议:

  • 使用增强型for循环而不是索引循环。这样可以避免在每种方法中使用this.getBooks().get(i)两次。

  • 不可用的图书+可用图书=图书总数。使用此公式可避免在这两种方法中编写所有代码。您可能希望使用Set<Book>代替List<Book>,以便更轻松地使用它。 [提示:设定差异]。

  • 此外,我不会在这些方法中执行null检查,而是仅在isAvailable()类中添加方法Book,这将返回{{ 1}}如果可用,则为true

答案 3 :(得分:1)

在一般情况下,如果您在代码中看到一个非常常见的模式,则通常有机会减少重复。第一步是查看您的代码并确定实际差异。你有:

public List<Book> getAvailableBooks() {
    List<Book> result = new ArrayList<Book>();
    for (int i = 0; i < this.getBooks().size(); i++) {
        if (this.getBooks().get(i).getPerson() == null) {
            result.add(this.getBooks().get(i));
        }
    }
    return result;
}

public List<Book> getUnavailableBooks() {
    List<Book> result = new ArrayList<Book>();
    for (int i = 0; i < this.getBooks().size(); i++) {
        if (this.getBooks().get(i).getPerson() != null) {
            result.add(this.getBooks().get(i));
        }
    }
    return result;
}

忽略方法名称,让我们进行逐行比较。这样做,我们可以发现差异:

if (this.getBooks().get(i).getPerson() == null) {
// vs:
if (this.getBooks().get(i).getPerson() != null) {

唯一的区别是==!=;条件是倒置的。在确定差异之后,下一步是查看是否可以参数化行为,以便逻辑本身完全相同,并且仅取决于少数外部变量的值。在这种情况下,我们可以看到这样的转变:

a == x    =>    (a == x) == true
a != x    =>    (a == x) == false
both:     =>    (a == x) == <variable>

所以我们可以将这两行等同起来:

boolean available = true;
if ((this.getBooks().get(i).getPerson() == null) == available) {
// vs:
boolean available = false;
if ((this.getBooks().get(i).getPerson() == null) == available) {

现在逻辑是等价的,我们只需更改available即可在两者之间进行选择。把它作为方法参数,瞧!

public List<Book> getBooksByAvailability (bool available) {
    List<Book> result = new ArrayList<Book>();
    for (int i = 0; i < this.getBooks().size(); i++) {
        if ((this.getBooks().get(i).getPerson() == null) == available) {
            result.add(this.getBooks().get(i));
        }
    }
    return result;
}

请注意,解决此问题的另一种方法是使“可用性”本身成为图书的属性。例如,如果将可用性测试移动到新方法Book.isAvailable(),则解决方案会变得更加明显:

public List<Book> getBooksByAvailability (bool available) {
    List<Book> result = new ArrayList<Book>();
    for (int i = 0; i < this.getBooks().size(); i++) {
        if (this.getBooks().get(i).isAvailable() == available) {
            result.add(this.getBooks().get(i));
        }
    }
    return result;
}

这还有一个额外的好处,就是让你在不修改其他任何地方的代码的情况下改变“可用性”的内部定义(例如,如果将来你认为getPerson() == null不足以说明“可用性” ,你只需要在Book.isAvailable())中更改它。

至于清晰度,你可以像Rohit Jain在this answer中提到的那样,切换到增强的for循环以提高可读性,例如:

public List<Book> getBooksByAvailability (bool available) {
    List<Book> result = new ArrayList<Book>();
    for (Book book : this.getBooks()) {
        if (book.isAvailable() == available) {
            result.add(book);
        }
    }
    return result;
}

要保留两个现有功能,如果有必要,您可以使用类似上面的内容作为私有效用方法,由两个公共方法调用。

答案 4 :(得分:0)

如果您不想更改方法签名,我认为您不能比现有的更好。您可以将循环重写为foreach,并可能执行列表的替换。肮脏的解决方案,但讲师可能会接受它。

public List<Book> getAvailableBooks() {
    Set<Book> result = new HashSet<>(getBooks());
    result.removeAll(getUnavailableBooks());
    return new ArrayList<Book>(result);
}

public List<Book> getUnavailableBooks() {
    List<Book> result = new ArrayList<Book>();
    for (Book b: getBooks()) {
        if (b.getPerson() != null) {
            result.add(b);
        }
    }
    return result;
}

可能不是最快的解决方案,但很短暂