在一般情況下,如果你看到一個很常見的模式在你的代碼重複,經常是爲了減少重複的機會。第一步是查看您的代碼並確定實際差異。您有:
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()
中更改)。
至於清晰,你可以作爲羅希特耆那教的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;
}
爲了讓您的兩個現有的功能,如果這是必要的,你可以使用類似上述的東西作爲私人效用方法,由兩個公共方法調用。
謝謝你的答覆。我真笨。這樣一個簡單的答案:) – user2879175