摘要:行為參數(shù)化的好處在于我們可以把過濾的邏輯與應(yīng)用過濾的行為解耦。實(shí)戰(zhàn)第二章通過行為參數(shù)化傳遞代碼讀書筆記這是我第一篇文章,歡迎加入咖啡館的春天。
應(yīng)對不斷變化的需求
在實(shí)際的工作中我們會將現(xiàn)實(shí)問題抽象成對象并對其進(jìn)行處理,比如需要對一堆顏色和重量不同的蘋果進(jìn)行過濾分類。
1、蘋果實(shí)體類
public class Apple { // 顏色 private String color; // 重量 private Integer weight; // Getter and Setter }
2、過濾方法
public static Listfilter(List appleList, String color, int weight) { // 符合條件的蘋果集合 List result = new ArrayList<>(); for (Apple apple : appleList) { // 如果顏色和重量符合條件就存入 if (color.equalsIgnoreCase(apple.getColor()) && weight == apple.getWeight()) { result.add(apple); } } return result; }
通過定制過濾方法,比如后期蘋果可能會有其他的屬性,是否成熟、產(chǎn)地等。我們可以在過濾方法的入?yún)⒓由蠈?yīng)的屬性并在內(nèi)部進(jìn)行判斷。這就是通過修改過濾方法來 應(yīng)對不斷變化的需求。但這樣有其局限性,如果需求不斷地更改,那么就需要重寫很多相似的方法。這違背了
DRY(Don"t Repeat Yourself)
的軟件工程原則。
行為參數(shù)化我們其實(shí)可以通過標(biāo)準(zhǔn)建模來定義一個(gè)過濾接口,讓其比重寫很多次過濾方法更好地 應(yīng)對不斷變化的需求。
1、建立蘋果謂詞接口
// predicate:謂詞,即一個(gè)返回 boolean 值的接口 public interface ApplePredicate { boolean test(Apple apple); }
2、運(yùn)用策略模式思想來構(gòu)建具體算法(策略)實(shí)現(xiàn)
public class AppleColorPredicate implements ApplePredicate { @Override public boolean test(Apple apple) { // 選出綠色的蘋果 return "green".equalsIgnoreCase(apple.getColor()); } } public class AppleWeightPredicate implements ApplePredicate { @Override public boolean test(Apple apple) { // 選出重量大于1的蘋果 return 1 < apple.getWeight(); } }
策略模式作為一種軟件設(shè)計(jì)模式,指對象有某個(gè)行為,但是在不同的場景中,該行為有不同的實(shí)現(xiàn)算法。
定義了一族算法(業(yè)務(wù)規(guī)則);
封裝了每個(gè)算法;
這族的算法可互換代替(interchangeable)—— 策略模式 - 維基百科,自由的百科全書
我們可以將 AppleColorPredicate 和 AppleWeightPredicate 看作是 過濾方法 的不同行為,需要 過濾方法 接收 ApplePredicate 對象對蘋果進(jìn)行過濾。這就是 行為參數(shù)化:讓方法接收多種行為(或策略)作為參數(shù),并在內(nèi)部使用,來完成不同的行為。
1、修改過濾方法讓其能夠接收蘋果謂詞接口對象
public static Listfilter(List appleList, ApplePredicate applePredicate) { // 符合條件的蘋果集合 List result = new ArrayList<>(); for (Apple apple : appleList) { // 如果符合條件就存入 if (applePredicate.test(apple)) { result.add(apple); } } return result; }
2、調(diào)用過濾方法進(jìn)行過濾
public class Main { public static void main(String[] args) { ListappleList = new ArrayList<>(); Apple apple = new Apple(); apple.setColor("red"); apple.setWeight(1); appleList.add(apple); apple = new Apple(); apple.setColor("green"); apple.setWeight(2); appleList.add(apple); List result = filter(appleList, new AppleWeightPredicate()); } }
result 中就會只有重量大于1的蘋果集合了。行為參數(shù)化 的好處在于我們可以把過濾的邏輯 boolean test() 與應(yīng)用過濾的行為 public static List
然而按照以上方式使用 ApplePredicate 依然有一個(gè)問題,那就是我們還是得不斷地新增 ApplePredicate 的實(shí)現(xiàn)。本質(zhì)上只是把重寫過濾方法的代價(jià)轉(zhuǎn)移到了新增謂詞實(shí)現(xiàn)上。這個(gè)時(shí)候我們可以換一個(gè)思路出發(fā),使用 匿名類 來隨用隨建謂詞實(shí)現(xiàn)。
使用匿名類實(shí)現(xiàn)謂詞接口
Listresult = filter(appleList, new ApplePredicate() { @Override public boolean test(Apple apple) { // 選出綠蘋果且重量為2 return "green".equalsIgnoreCase(apple.getColor()) && 2 == apple.getWeight(); } });
現(xiàn)在,我們只需要每次去匿名實(shí)現(xiàn)謂詞接口就行,然而這樣的寫讓人覺得很臃腫,而且看起來很讓人費(fèi)解。接下來看看 Lambda 是怎么讓其變得簡潔又友好的。
通過 Lambda 簡化匿名實(shí)現(xiàn)
Listresult = filter(appleList, (Apple apple1) -> "green".equalsIgnoreCase(apple1.getColor()) && 2 == apple1.getWeight());
是不是簡潔得有點(diǎn)看不懂了?沒關(guān)系,先細(xì)細(xì)品味,下一章我們會詳細(xì)了解 Lambda。
我們還可以進(jìn)一步抽象。目前 ApplePredicate 還只適用于蘋果,而我想要其他對象進(jìn)行過濾呢?可以使用泛型來定義需要處理的對象。
1、修改 ApplePredicate 成 Predicate
public interface Predicate{ boolean test(T t); }
2、修改過濾方法
public staticList filter(List list, Predicate predicate) { // 符合條件的集合 List result = new ArrayList<>(); for (T t : list) { // 如果符合條件就存入 if (predicate.test(t)) { result.add(t); } } return result; }
這樣我們就能將過濾方法用在其他對象上了。下一章我們會更加深入地理解 Lambda 是什么,能干什么。
Java 8 實(shí)戰(zhàn) 第二章 通過行為參數(shù)化傳遞代碼 讀書筆記
這是我第一篇文章,歡迎加入咖啡館的春天(338147322)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/67606.html
摘要:但是到了第二天,他突然告訴你其實(shí)我還想找出所有重量超過克的蘋果?,F(xiàn)在,農(nóng)民要求需要篩選紅蘋果。那么,我們就可以根據(jù)條件創(chuàng)建一個(gè)類并且實(shí)現(xiàn)通過謂詞篩選紅蘋果并且是重蘋果酷,現(xiàn)在方法的行為已經(jīng)取決于通過對象來實(shí)現(xiàn)了。 通過行為參數(shù)化傳遞代碼 行為參數(shù)化 在《Java8實(shí)戰(zhàn)》第二章主要介紹的是通過行為參數(shù)化傳遞代碼,那么就來了解一下什么是行為參數(shù)化吧。 在軟件工程中,一個(gè)從所周知的問題就是,...
摘要:比如說,有個(gè)應(yīng)用程序是幫助果農(nóng)了解自己的庫存。果農(nóng)可能想有一個(gè)查找?guī)齑嬷兴芯G色蘋果的功能。又過了兩天,果農(nóng)又跑過來補(bǔ)充道要是我可以找出所有既是綠色,重量也超過克的蘋果,那就太棒了。此外,類似的新功能實(shí)現(xiàn)起來還應(yīng)該很簡單,而且易于長期維護(hù)。 1 需求說明 在軟件工程中,一個(gè)眾所周知的問題就是,不管你做什么,用戶的需求肯定會變。比如說,有個(gè)應(yīng)用程序是幫助果農(nóng)了解自己的庫存。果農(nóng)可能想有一...
摘要:自定義函數(shù)式接口我們在前面例子中實(shí)現(xiàn)的蘋果篩選接口就是一個(gè)函數(shù)式接口定義如下,正因?yàn)槿绱宋覀兛梢詫⒑Y選邏輯參數(shù)化,并應(yīng)用表達(dá)式僅包含一個(gè)抽象方法,依照定義可以將其視為一個(gè)函數(shù)式接口。 Lambda 表達(dá)式是 java 8th 給我們帶來的幾個(gè)重量級新特性之一,借用 lambda 表達(dá)式可以讓我們的程序設(shè)計(jì)更加簡潔。最近新的項(xiàng)目摒棄了 6th 版本,全面基于 8th 進(jìn)行開發(fā),本文將探討...
摘要:不存在則實(shí)例化一個(gè)新的對象并將它以指定的名稱存儲到指定的域范圍中。 什么是javaBean JavaBean就是一個(gè)普通的java類,也稱之為簡單java對象--POJO(Plain Ordinary Java Object),是Java程序設(shè)計(jì)中一種設(shè)計(jì)模式,是一種基于 Java 平臺的軟件組件思想 JavaBean遵循著特定的寫法,通常有以下的規(guī)則: 有無參的構(gòu)造函數(shù) 成...
摘要:新特性總覽標(biāo)簽本文主要介紹的新特性,包括表達(dá)式方法引用流默認(rèn)方法組合式異步編程新的時(shí)間,等等各個(gè)方面。還有對應(yīng)的和類型的函數(shù)連接字符串廣義的歸約匯總起始值,映射方法,二元結(jié)合二元結(jié)合。使用并行流時(shí)要注意避免共享可變狀態(tài)。 Java8新特性總覽 標(biāo)簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達(dá)式、方法引用、流(Stream API)、默認(rèn)方...
閱讀 962·2021-10-13 09:39
閱讀 1571·2021-10-11 10:57
閱讀 2665·2019-08-26 13:53
閱讀 2641·2019-08-26 12:23
閱讀 3768·2019-08-23 18:30
閱讀 3828·2019-08-23 18:08
閱讀 2591·2019-08-23 18:04
閱讀 3018·2019-08-23 16:28