美文网首页程序员CrazyMark
函数式编程最佳实践

函数式编程最佳实践

作者: Crazy丶Mark | 来源:发表于2020-11-17 13:36 被阅读0次

别人说烂了的stream api不就不想赘述了,我想和大家分享一下如何用函数式编程来简化我们的开发,想说点不一样的东西

简化事务

对于事务而言,应该粒度越小越好,并且读写逻辑应该分开,只在写的逻辑上执行事务,可以用函数式编程来简化抽去写逻辑这一步

@Service
public class TransactionService {
    @Transactional
    public void process(ThrowExceptionRunnable runnable){
        try {
            runnable.run();
        }catch (Exception e){
            new RuntimeException(e);
        }
    }
}

//使用方式
public void regist(String username){
        User user = userService.findByUserName(username);
    if(user != null) return;
    
    //执行事务 注册用户 开通余额账号
    transactionService.process(() -> {
        userService.save(new User(username));
        balanceService.save(new Balance(username));
    });
}

赋予方法重试能力

    public static void retryFunction(ThrowExceptionRunnable runnable, int time) {
        while (true) {
            try {
                runnable.run();
                return;
            } catch (Exception e) {
                time--;
                if (time <= 0) throw new RuntimeException(e);
            }
        }
    }
    public static <T, R> R retryFunction(ThrowExceptionFunction<T, R> function, T t, int time) {
        while (true) {
            try {
                return function.apply(t);
            } catch (Exception e) {
                time--;
                if (time <= 0) throw new RuntimeException(e);
            }
        }
    }
    public static <T, U, R> R retryFunction(ThrowExceptionBiFunction<T, U, R> function, T t, U u, int time) {
        while (true) {
            try {
                return function.apply(t, u);
            } catch (Exception e) {
                time--;
                if (time <= 0) throw new RuntimeException(e);
            }
        }
    }
        public static void main(String[] args) {
            //http调用,失败会重试3次
        retryFunction(()->http.call(),3);
            //把数字1转成数字 失败会重试三次
            String s = retryFunction(String::valueOf, 1, 3);
            String ss = retryFunction(i -> String.valueOf(i), 1, 3);
    }

赋予函数缓存能力

public static <T, R> R cacheFunction(Function<T, R> function, T t, Map<T, R> cache) {
    R r = cache.get(t);
    if (r != null) return r;
    R result = function.apply(t);
    cache.put(t,result);
    return result;
}

public static void main(String[] args) {
        Map<String,User> cache = new HashMap<Integer, Integer>();
        String username = "张三";
            //不走缓存
        cacheFunction(u -> userService.findByUserName(u),username,cache);
            //走缓存
        cacheFunction(u -> userService.findByUserName(u),username,cache);
    }

赋予函数报错返回默认值能力

    public static <T, R> R computeOrGetDefault(ThrowExceptionFunction<T, R> function, T t, R r) {
        try {
            return function.apply(t);
        } catch (Exception e) {
            return r;
        }
    }
    public static <R> R computeOrGetDefault(ThrowExceptionSupplier<R> supplier,R r){
        try {
            return supplier.get();
        } catch (Exception e) {
            return r;
        }
    }

        public static void main(String[] args) {
            //返回0
            computeOrGetDefault(i -> {
            if (i < 0) throw new RuntimeException();
            else return i;
        }, -1, 0);
            //返回5
        computeOrGetDefault(i -> {
            if (i < 0) throw new RuntimeException();
            else return i;
        },5,0);
    }

赋予函数处理异常的能力

    public static <T, R> R computeAndDealException(ThrowExceptionFunction<T, R> function, T t, Function<Exception, R> dealFunc) {
        try {
            return function.apply(t);
        } catch (Exception e) {
            return dealFunc.apply(e);
        }
    }

    public static <T, U, R> R computeAndDealException(ThrowExceptionBiFunction<T,U, R> function, T t, U u,Function<Exception, R> dealFunc) {
        try {
            return function.apply(t,u);
        } catch (Exception e) {
            return dealFunc.apply(e);
        }
    }

    public static <R> R computeAndDealException(ThrowExceptionSupplier<R> supplier, Function<Exception, R> dealFunc) {
        try {
            return supplier.get();
        } catch (Exception e) {
            return dealFunc.apply(e);
        }
    }

public static void main(String[] args) {
    //返回异常message的hashcode
    Integer integer = computeAndDealException(i -> {
        if (i < 0) throw new RuntimeException("不能小于0");
        else return i;
    }, -1, e -> e.getMessage().hashCode());
    System.out.println(integer);
  
}

赋予函数记录日志能力

public static <T, R> R logFunction(Function<T, R> function, T t, String logTitle) {
    long startTime = System.currentTimeMillis();
    log.info("[[title={}]],request={},requestTime={}", logTitle, t.toString(),          LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    R apply = function.apply(t);
    long endTime = System.currentTimeMillis();
    log.info("[[title={}]],response={},spendTime={}ms", logTitle, apply.toString(), endTime - startTime);
    return apply;
}

public static void main(String[] args) {
    logFunction(String::valueOf,"s","String.valueOf");
}

自定义函数接口

    @FunctionalInterface
    public interface ThrowExceptionFunction<T, R> {
        R apply(T t) throws Exception;
    }

    @FunctionalInterface
    public interface ThrowExceptionBiFunction<T, U, R> {
        R apply(T t, U u) throws Exception;
    }
    @FunctionalInterface
    public interface ThrowExceptionSupplier<T> {
        T get() throws Exception;
    }
    @FunctionalInterface
    public interface ThrowExceptionRunnable {
        void run() throws Exception;
    }

Q:为什么要自定义函数接口

A:自带的函数接口无法处理检查异常,遇见带检查异常的方法会报错

我哪些场景用到了?

链式取数

在翻译php代码的时候我们常常遇到如下情况

$s = a.b.c.d.e.f.g

然后翻译成java代码的时候是这样的

String s = a.getB().getC().getD().getE().getF().getG();

有啥问题?没有没有判空,只要中间有一层为空,那么就是NPE,要是去写判空逻辑的话,真是要了命了

这时我们就可以用上上面提到的骚操作了

代码改写

String s = computeOrGetDefault(()->a.getB().getC().getD().getE().getF().getG(),"");
事务
简单的降级操作(computeAndDealException)
接口重试
接口缓存
记录日志
。。。。。

相关文章

  • js函数式编程最佳实践 - 持续更新

    函数式编程最佳实践 学习文档 函数式编程术语 数组字串处理 创建 tags 创建表格 实现一个展示/收起功能 倾向...

  • 函数式编程最佳实践

    别人说烂了的stream api不就不想赘述了,我想和大家分享一下如何用函数式编程来简化我们的开发,想说点不一样的...

  • Python函数式编程

    在 Python 中使用函数式编程的最佳实践! 简 介 Python 是一种功能丰富的高级编程语言。它有通用的...

  • Python函数式编程最佳实践

    Python并非经典的FP(Functional Programming, 函数式编程)语言,用其原生的map/f...

  • Python函数式编程

    在 Python 中使用函数式编程的最佳实践! 简 介 Python 是一种功能丰富的高级编程语言。它有通用的标准...

  • RxSwift初探(1)

    一、前提:函数响应式编程思想 简单来说 函数响应式编程 = 函数式编程 + 响应式编程 (1)函数式 函数式编程是...

  • iOS 函数编程 & 链式编程

    函数式(链式)编程 函数式编程概念 函数式编程是种编程范式 函数式编程 Functional Programmin...

  • [摘]函数式编程

    JavaScript 中的函数式编程实践 起源 函数式编程思想的源头可以追溯到 20 世纪 30 年代,数学家阿隆...

  • jQuery编程的最佳实践

    jQuery编程的最佳实践 @(jquery)[jquery|最佳实践|编程规范] [TOC] 加载jQuery ...

  • 函数式编程(一)—— 前置知识

    为什么要学函数式编程? 什么是函数式编程?函数式编程和面向对象编程的不同对于函数式编程思维方式的理解: 函数式编程...

网友评论

    本文标题:函数式编程最佳实践

    本文链接:https://www.haomeiwen.com/subject/jbyxiktx.html