java中通過行為參數(shù)化傳遞代碼方案
行為參數(shù)化:它意味著拿出一個代碼塊,把它準(zhǔn)備好但是不執(zhí)行,可以推遲該代碼塊的執(zhí)行,比如將代碼塊作為參數(shù),需要的時候再內(nèi)部執(zhí)行。
下面我來通過例子來描述什么是行為參數(shù)化:
現(xiàn)在來寫一個有關(guān)篩選蘋果的demo,現(xiàn)在農(nóng)民伯伯想要篩選紅色的蘋果,可以這樣來做:
方案一
public static List<Apple> filterGreenApples(List<Apple> inventory){ List<Apple> result = new ArrayList<>(); for (Apple apple : inventory) { if ("green".equals(apple.getColor())){ result.add(apple); } } return result; }
現(xiàn)在有一個問題,當(dāng)農(nóng)民伯伯改變了主意,它還要篩選紅色的蘋果,我們是不是還要寫一個以“red”為篩選條件的方法呢?是這些方法有很多重復(fù)的內(nèi)容,這就非常冗余。
方案二
我們可以做一層抽象,將總是變化的東西抽出來,這里經(jīng)常變的是顏色,我們當(dāng)然可以把顏色抽出來作為一個參數(shù)傳到篩選的方法里面:
public static List<Apple> filterColorApples(List<Apple> inventory,String color){ List<Apple> result = new ArrayList<>(); for (Apple apple : inventory) { if (color.equals(apple.getColor())){ result.add(apple); } } return result; }
這樣即使農(nóng)民伯伯要求五彩斑斕的黑色蘋果,也可以篩選出來,但是如果農(nóng)民伯伯還要篩選重量小于150g的蘋果,那還要寫有關(guān)重量的方法來進(jìn)行篩選,這期間有很多重復(fù)的代碼,如果要去除冗余,我們可再做一層抽象,將蘋果抽象出來。
方案三
public interface ApplePredicate { Boolean test(Apple apple); }
public class AppleRedColorPredicate implements ApplePredicate { @Override public Boolean test(Apple apple) { return "red".equals(apple.getColor()); } }
這樣再進(jìn)行篩選紅色的蘋果
public static List<Apple> filterRedColorApples(List<Apple> inventory,ApplePredicate predicate){ List<Apple> result = new ArrayList<>(); for (Apple apple : inventory) { if (predicate.test(apple)){ result.add(apple); } } return result; }
這樣的代碼就非常的靈活了,如果想要綠色代碼,就創(chuàng)建一個AppleGeenColorPredicate類,如果想要重量大于150g的蘋果,也是類似,創(chuàng)建一個AppleWeightPredicate類即可。
這其實就是行為參數(shù)化,讓方法來接收多種行為做參數(shù),并在內(nèi)部使用,來完成不同的行為。
但是有些遺憾的是,filterRedColorApples方法只能接受對象,我們其實是將代碼包裹在了ApplePredicate對象里面,每次還是需要創(chuàng)建好多的類來完成功能。我們可以通過匿名內(nèi)部類來實現(xiàn)該功能。
方案四
public static void main(String[] args) { List<Apple> apples = Arrays.asList(new Apple("red", 100), new Apple("green", 200)); List<Apple> redColorApple = filterColorApples(apples, new ApplePredicate() { @Override public Boolean test(Apple apple) { return "red".equals(apple.getColor()); } }); }
我們還可以使用上面的方法,通過傳一個匿名內(nèi)部類來實現(xiàn)我們的功能,這樣就不用寫好多的實現(xiàn)類了,大大簡化了代碼~,但是還有一個缺點,就是匿名內(nèi)部類看起來比較啰嗦,并且也不太好理解,我們可以使用java8的新特性–λ表達(dá)式。
方案五
public static void main(String[] args) { List<Apple> apples = Arrays.asList(new Apple("red", 100), new Apple("green", 200)); List<Apple> redColorApple = filterColorApples(apples, (Apple a) -> "red".equals(a.getColor())); }
這樣看起來就簡單多了,直接傳一個lambda就OK了。
但是還有一個問題,萬一農(nóng)品伯伯想要再進(jìn)行香蕉的篩選怎么辦?我們可以使用泛型來實現(xiàn),
方案六
public static <T> List<T> filter(List<T> list, Predicate<T> predicate) { List<T> result = new ArrayList<>(); for (T t : list) { if (predicate.test(t)) { result.add(t); } } return result; } List<Apple> redColorApple = filterColorApples(apples, (Apple a) -> "red".equals(a.getColor()));
這樣來起來就更加的靈活了。
總結(jié):
以上幾個例子依次展示了如何做好抽象,完成更靈活的代碼,也展示了由變量到接口到匿名類到lambda表達(dá)式的演進(jìn),這都是慢慢演化過來的,最主要的還是要明白最初的寫法,在優(yōu)秀的代碼也是站在最初的思路上進(jìn)行優(yōu)化的。
到此這篇關(guān)于java中通過行為參數(shù)化傳遞代碼方案的文章就介紹到這了,更多相關(guān)java傳遞代碼方案內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 如何實現(xiàn)POST(x-www-form-urlencoded)請求
這篇文章主要介紹了Java 實現(xiàn)POST(x-www-form-urlencoded)請求,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10深入理解Netty?FastThreadLocal優(yōu)缺點及實現(xiàn)邏輯
本文以線上詭異問題為切入點,通過對比JDK ThreadLocal和Netty FastThreadLocal實現(xiàn)邏輯以及優(yōu)缺點,并深入解讀源碼,由淺入深理解Netty FastThreadLocal2023-10-10java 基礎(chǔ)之JavaBean屬性命名規(guī)范問題
這篇文章主要介紹了java 基礎(chǔ)之JavaBean屬性命名規(guī)范問題的相關(guān)資料,需要的朋友可以參考下2017-05-05一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要
yBatis的底層操作封裝了JDBC的API,MyBatis的工作原理以及核心流程與JDBC的使用步驟一脈相承,MyBatis的核心對象(SqlSession,Executor)與JDBC的核心對象(Connection,Statement)相互對應(yīng)2021-06-06Java8新特性之精簡的JRE詳解_動力節(jié)點Java學(xué)院整理
這篇文章主要介紹了Java8新特性之精簡的JRE詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06java實現(xiàn)大數(shù)加法(BigDecimal)的實例代碼
之前寫過用vector、string實現(xiàn)大數(shù)加法,現(xiàn)在用java的BigDecimal類,代碼簡單很多。但是在online-judge上,java的代碼運行時間和內(nèi)存大得多2013-10-10