Java進(jìn)階高手讀書筆記1-行為參數(shù)化-創(chuàng)新互聯(lián)

閱讀完《Java進(jìn)階高手》第一章以及第二章;對書中知識進(jìn)行復(fù)盤整理;主要記錄:通過行為參數(shù)化傳遞代碼

成都創(chuàng)新互聯(lián)是一家專業(yè)的成都網(wǎng)站建設(shè)公司,我們專注成都網(wǎng)站設(shè)計、成都做網(wǎng)站、網(wǎng)絡(luò)營銷、企業(yè)網(wǎng)站建設(shè),賣友情鏈接1元廣告為企業(yè)客戶提供一站式建站解決方案,能帶給客戶新的互聯(lián)網(wǎng)理念。從網(wǎng)站結(jié)構(gòu)的規(guī)劃UI設(shè)計到用戶體驗提高,創(chuàng)新互聯(lián)力求做到盡善盡美。

文章目錄
  • 一、行為參數(shù)化
  • 二、具體的業(yè)務(wù)場景
    • 1.初試牛刀:篩選綠蘋果
    • 2.再展身手:把顏色作為參數(shù)
    • 3.第三次嘗試:對你能想到的每個屬性做篩選
    • 4.行為參數(shù)化


正文內(nèi)容:

一、行為參數(shù)化
  • 在之前的認(rèn)知概念里面,筆者對于參數(shù)的理解就是:在Java方法將要運(yùn)行時,方法需要外部提供數(shù)據(jù),然后對數(shù)據(jù)進(jìn)行處理,此時的這個需求數(shù)據(jù)就是參數(shù)。這種數(shù)據(jù)類型的參數(shù),可以是具體的類,也可以是具體的類屬性。從Java類角度分析,Java類包括成員變量,成員方法以及其他內(nèi)容,此時的參數(shù)就是Java類中的成員變量;但是隨著業(yè)務(wù)邏輯的復(fù)雜化,需要我們處理的數(shù)據(jù)可能也是需要提前處理好才可以,簡單地說就是為了讓代碼更加貼合實際生活,更加簡潔,讓代碼具有更高的擴(kuò)展性與可讀性,我們需要對代碼進(jìn)行優(yōu)化處理
  • 現(xiàn)在引入行為參數(shù)化概念,行為是指Java類中的方法,將行為參數(shù)化是指我們將具體的對數(shù)據(jù)操作的業(yè)務(wù)邏輯進(jìn)行抽取將其抽象為參數(shù),然后通過形參的方式傳遞給方法,讓方法具有簡潔性以及高可讀性,高擴(kuò)展性
  • 行為參數(shù)化與策略模式類似,都是可以幫助開發(fā)者處理頻繁需求變更的軟件開發(fā)模式
二、具體的業(yè)務(wù)場景
  • 有個應(yīng)用程序是幫助農(nóng)民了解自己的庫存。這位農(nóng)民可能想要一個查找?guī)齑嬷兴芯G色蘋果的功能。但到了第二天,他可能會告訴你:其實我還需要找出重量超過150克的蘋果。過了兩天,農(nóng)民又跑過來告訴你:要是可以找到既是綠色,重量又超過150克的蘋果那就太棒了。你要如何應(yīng)對這樣的不斷變化的需求?理想狀態(tài)下應(yīng)該將自己的工作量降到最小。此時,類似的新功能實現(xiàn)起來還應(yīng)該很簡單,而且易于長期維護(hù)
1.初試牛刀:篩選綠蘋果

具體的代碼如下所示:

public class Apple {private Integer weight;

   private Color color;
   
   public Integer getWeight() {   return weight;
   }

   public void setWeight(Integer weight) {   this.weight = weight;
   }
   
   public Color getColor() {   return color;
   }

   public void setColor(Color color) {   this.color = color;
   }
}
enum Color {RED, GREEN
}
public class Filter {public static ListfilterGreenApple(Listinventory) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if (GREEN.equals(apple.getColor())) {result.add(apple);
            }
        }
        return result;
    }
}

我們現(xiàn)在使用枚舉類把蘋果的顏色進(jìn)行描述,然后將蘋果抽象化為Apple類,包含顏色與重量的屬性,最后構(gòu)造過濾類,在過濾類里面給出具體的過濾綠色蘋果的方法filterGreenApple;如果現(xiàn)在需求變了,農(nóng)民需要過濾紅色蘋果,那么我們就需要將filterGreenApple方法復(fù)制一份,將方法名改為filterRedApple并且將里面的GREEN顏色改為RED;這個樣子確實解決了問題,但是很明顯,重復(fù)代碼很多,并不是一個好的解決方法;一個好的解決方法是我們編寫類似代碼后,盡量對其進(jìn)行抽象化

2.再展身手:把顏色作為參數(shù)

在上一版代碼中,我們復(fù)制filterGreenApple方法完成對紅色蘋果的過濾,重復(fù)了filterGreenApple中大量代碼,怎樣避免這種問題的發(fā)生呢?好的解決方式是將顏色進(jìn)行參數(shù)化,把顏色作為參數(shù)傳遞給過濾的方法,這樣子就靈活適應(yīng)變化了

  • 在Filter類里面添加方法filterApple
    具體代碼如下:
public static ListfilterApple(Listinventory,Color color) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if (color.equals(apple.getColor())) {result.add(apple);
            }
        }
        return result;
    }

現(xiàn)在解決了顏色篩選的問題,但是農(nóng)民又跑過來告訴你:要是可以區(qū)分蘋果的重量就太好了,重的蘋果一般是重量大于150克
對于我們來說,這不是問題,我們只需要重新寫一個過濾蘋果的方法就可以了,我們現(xiàn)在復(fù)制filterApple方法,然后把形參color改為weight,然后把篩選條件改為weight大于150就完成了
具體代碼如下所示:

public static ListfilterApple(Listinventory, Integer weight) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if (apple.getWeight() >weight) {result.add(apple);
            }
        }
        return result;
    }
  • 現(xiàn)在雖然解決了問題,但是代碼的重復(fù)度太高了,這違反了DRY(Don’t Repeat Yourself不要重復(fù)自己)軟件工程原則

-我們可以將重量和顏色都作為參數(shù)傳遞給方法,然后給一個標(biāo)記,根據(jù)標(biāo)記去判斷是通過顏色還是重量過濾蘋果

3.第三次嘗試:對你能想到的每個屬性做篩選

我們將所有的蘋果屬性結(jié)合起來,如下所示:

public static ListfilterApple(Listinventory,
 Color color, Integer weight, boolean flag) {Listresult = new ArrayList<>();
        for (Apple apple : inventory) {if ((flag && color.equals(apple.getColor())) ||
             (!flag && apple.getWeight() >weight)) {result.add(apple);
            }
        }
        return result;
    }

現(xiàn)在的問題確實已經(jīng)解決了,但是這個解決方案再差不過。首先客戶端看上去糟糕透了,true和false是什么意思?此外,這個解決方案無法應(yīng)對變化的需求,如果這位農(nóng)民要求你對蘋果的不同屬性進(jìn)行篩選,比如,大小,產(chǎn)地,形狀等,該怎樣處理?或者農(nóng)民要求組合屬性,做更復(fù)雜的查詢,比如綠色的重蘋果,又該怎么辦?如今的情況,我們需要一種更好的解決方式來告訴過濾方法

  • 現(xiàn)在就需要使用行為參數(shù)化的方式實現(xiàn)這種靈活性
4.行為參數(shù)化

一種可能的解決方式是對我們的選擇標(biāo)準(zhǔn)進(jìn)行建模:考慮的是蘋果,需要根據(jù)Apple的某些屬性(比如它是綠色的嗎?重量超過150克嗎?)來返回一個boolean值。我們把它稱為謂詞(即一個返回boolean值的函數(shù))。讓我們定義一個接口來對選擇標(biāo)準(zhǔn)建模:

public interface ApplePredicate {boolean test(Apple apple);
}

選擇蘋果的不同策略,可以將這些標(biāo)準(zhǔn)看作filter方法的不同行為。剛才做的這些和策略設(shè)計模式相關(guān),它讓我們定義一族算法,把它們封裝起來(稱為策略),然后再運(yùn)行的時候選擇一個算法。在則這里,算法族就是ApplePredicate,不同的策略就是AppleGreenColorPredicate和AppleHeavyWeightPredicate

public class AppleGreenColorPredicate implements ApplePredicate{@Override
    public boolean test(Apple apple) {return GREEN.equals(apple.getColor());
    }
}
public class AppleHeavyWeightPredicate implements ApplePredicate {@Override
    public boolean test(Apple apple) {return apple.getWeight() >150;
    }
}

但是,該怎么利用ApplePredicate的不同實現(xiàn)呢?我們需要filterApple方法接受ApplePredicate對象,對Apple做條件測試。這就是行為參數(shù)化:讓方法接受多種行為(策略)作為參數(shù),并在內(nèi)部使用,來完成不同行為

  • 這在軟件工程中有很大好處:現(xiàn)在我們把filterApple方法迭代集合的邏輯與你要應(yīng)用到集合中每個元素的行為區(qū)分開了

具體代碼如下:

public class Filter {public static ListfilterApple(Listinventory,ApplePredicate predicate){ArrayListresult = new ArrayList<>();
        for (Apple apple:inventory){if(predicate.test(apple)){result.add(apple);
            }
        }
        return result;
    }
}

在這個例子中,唯一重要的代碼是test方法的實現(xiàn),正是它定義了filterApple方法的新行為。但是現(xiàn)在有一個遺憾,由于filterApple方法只接受對象,所以我們必須把代碼包裹在ApplePredicate對象里。這種做法類似于內(nèi)聯(lián)“傳遞代碼”,因為我們通過實現(xiàn)一個test方法來傳遞布爾表達(dá)式值。再JDK8之后我們可以使用Lambda進(jìn)一步簡化代碼,這樣子我們就無須定義多個ApplePredicate實現(xiàn)類了,從而去掉不必要的代碼

具體代碼如下:

public class Main {public static void main(String[] args) {Listresult1 = Filter.filterApple(new ArrayList(), (apple) ->GREEN.equals(apple.getColor()));
        Listresult2 = Filter.filterApple(new ArrayList(), (apple) ->apple.getWeight() >150);
    }
}

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

當(dāng)前名稱:Java進(jìn)階高手讀書筆記1-行為參數(shù)化-創(chuàng)新互聯(lián)
當(dāng)前URL:http://muchs.cn/article40/ioheo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、手機(jī)網(wǎng)站建設(shè)網(wǎng)站改版、商城網(wǎng)站服務(wù)器托管、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化