副作用与幂等

问题代码:

private final ConcurrentHashMap<String, List<Region>> store = new ConcurrentHashMap<>();

@Override
public List<Region> tree(boolean province) {
    String storeKey = "regions" + province;
    List<Region> regions = store.computeIfAbsent(storeKey, key -> baseMapper.tree(province));
    return ForestNodeMerger.merge(regions);
}

 引用变量 regions 实际是 store 里保存的值。而 ForestNodeMerger.merge 方法产生副作用,改变了store 的状态。因此该方法不是幂等的。

等价的例子:

private static HashMap<String, List<Integer>> hm = new HashMap<>();

public static void addNumbers() {
    ArrayList<Integer> list = new ArrayList<>();
    list.add(3);
    list.add(4);
    list.add(5);
    List<Integer> list1 = hm.computeIfAbsent("list", key -> list);
    list1.add(6);
    System.out.println(list1);
}

public static void main(String[] args) {
    addNumbers();
    addNumbers();
}

 输出结果为:

[3, 4, 5, 6]
[3, 4, 5, 6, 6]

解决方法

private final ConcurrentHashMap<String, List<Region>> store = new ConcurrentHashMap<>();

@Override
public List<Region> tree(boolean province) {
    String storeKey = "regions" + province;
    return store.computeIfAbsent(storeKey, key -> ForestNodeMerger.merge(baseMapper.tree(province)));
}

 将可能产生副作用的代码合并,只在最开始产生副作用。因此该方法是幂等的。

2333

猜你喜欢

转载自www.cnblogs.com/lemos/p/12262694.html