• Java Functional Programming


    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);
            }
        }
    
    

    是不是方法都是纯函数,没有一点副作用,写起来是不是也很优雅。
    需求里的每个实现都是纯函数的,我只关注我当前这一步的计算逻辑。具体的组装放到了外边。

  • 相关阅读:
    stm32 SPI DMA读取ADS8345数据
    Minigui3.0.12完美安装,折腾了一天。终于看到了
    qvfb2的安装,在ubuntu10.4上安装成功
    户口从杭州人才市场迁移到武汉万科魅力之城的过程
    禁止minigui 3.0的屏幕保护
    想穿越回到儿时记录那些幸福
    TIM2定时闪灯程序。。。
    关于minigui的皮肤控件无法显示问题
    插件框架内核的设计
    用“序列图”描述技术方案
  • 原文地址:https://www.cnblogs.com/qulianqing/p/13290207.html
Copyright © 2020-2023  润新知