Java Functional Programming
阿新 • • 發佈:2020-07-13
Java Functional Programming
前提
前兩天看了Java的Functional介面,覺得很是好玩。然後今天在上TDD的課,然後有一個作業(等會聊),需求很簡單,覺得用普通的面向物件寫法沒有什麼進步,也覺得沒啥意思。
於是嘗試用Java寫類似於函數語言程式設計的方法去實現這個需求
需求
- 不超過8公里時每公里0.8元
- 超過8公里則每公里加收50%長途費
- 停車等待時加收每分鐘0.25元
是不是感覺很簡單,一會會就搞完了。我也是這麼感覺的,想一想最近看的Java原始碼,試一試函式式的搞法。
普通實現
這裡暫不關注測試,TDD是一定要先寫測試的.
public class Taxi { private static final double BASIC_UNIT_PRICE = 0.8; private static final int NORMAL_DISTANCE = 8; private static final double LONG_DISTANCE_UNIT_PRICE = BASIC_UNIT_PRICE * 0.5; private static final double WAIT_TIME_UNIT_PRICE = 0.25; // 需求一 private double getBasicFee(int distance) { return distance * BASIC_UNIT_PRICE; } //需求二 private double getLongDistanceFee(int distance) { return distance - NORMAL_DISTANCE <= 0 ? 0D : (distance - NORMAL_DISTANCE) * LONG_DISTANCE_UNIT_PRICE; } //需求三 private double getWaitTimeFee(int waitTime) { return waitTime * WAIT_TIME_UNIT_PRICE; } // 計算方法 public double calculate(int distance, int waitTime) { return getBasicFee(distance) + getLongDistanceFee(distance) + getWaitTimeFee(waitTime); } }
是不是很簡答,一眼就能看明。這麼做沒問題,但是想一想,你工作要一直寫這樣的程式碼是不是很無聊,對於個人成長來說這相當於沒成長呀。
這程式碼畢業生也能寫出來,工作兩年也寫這程式碼???
純函式式實現
public class Taxi { private static final double BASIC_UNIT_PRICE = 0.8; private static final int NORMAL_DISTANCE = 8; private static final double LONG_DISTANCE_UNIT_PRICE = BASIC_UNIT_PRICE * 0.5; private static final double WAIT_TIME_UNIT_PRICE = 0.25; // 需求一 private ToDoubleTripleIntFunction getBasicFee = (initValue, distance, any) -> initValue + distance * BASIC_UNIT_PRICE; // 需求二 private ToDoubleTripleIntFunction getLongDistanceFee = (initValue, distance, any) -> initValue + (distance - NORMAL_DISTANCE <= 0 ? 0D : (distance - NORMAL_DISTANCE) * LONG_DISTANCE_UNIT_PRICE); // 需求三 private ToDoubleTripleIntFunction getWaitTimeFee = (initValue, any, waitTime) -> initValue + waitTime * WAIT_TIME_UNIT_PRICE; public double calculate(int distance, int waitTime) { return getBasicFee .thenCompose(getLongDistanceFee) .thenCompose(getWaitTimeFee) .applyAsDouble(0D, distance, waitTime); } @FunctionalInterface private interface ToDoubleTripleIntFunction { double applyAsDouble(double f, int t, int u); default ToDoubleTripleIntFunction thenCompose(ToDoubleTripleIntFunction next) { return (double first, int second, int third) -> next.applyAsDouble(applyAsDouble(first, second, third), second, third); } }
是不是方法都是純函式,沒有一點副作用,寫起來是不是也很優雅。
需求裡的每個實現都是純函式的,我只關注我當前這一步的計算邏輯。具體的組裝放到了外邊。