自從 Java8 支持 lambda 表達式, 代碼中的 lambda 就處處都是。 但大可能是濫用。java
lambda 表達式用於表達簡短的邏輯(能夠看作 C 語言的內聯函數)很是清晰,但用來表達比較長的業務邏輯,就與其設計初衷背道而馳了。
redis
以下所示,三層嵌套 lambda 表達式,暈了沒有 ?ide
如何解開這些結呢 ? 一步步來。函數
首先, allImageIds.forEach 是一個明顯的 Stream-add 模式,能夠使用 stream.map 來表達:ui
List<CompletableFuture<String>> completableFutureList = allImageIds.stream().map(imageId -> buildCompletableFuture(imageId, comId, newGroup)).collect(Collectors.toList()); private CompletableFuture<String> buildCompletableFuture(String imageId, String comId, int newGroup) { CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { String lockKey = String.format("%s%s%s", comId, newGroup, imageId); return redisLock.call(lockKey, () -> { return dealWith(comId, newGroup, imageId); }); }, executorService); return future; }
這樣,就解耦了一層。this
接下來,CompletableFuture.supplyAsync 須要提供一個 Supplier
private CompletableFuture<String> buildCompletableFuture(String imageId, String comId, int newGroup) { Supplier<String> futureSupplier = () -> { String lockKey = String.format("%s%s%s", comId, newGroup, imageId); return redisLock.call(lockKey, () -> { return dealWith(comId, newGroup, imageId); }); }; CompletableFuture<String> future = CompletableFuture.supplyAsync(futureSupplier, executorService); return future; }
這樣,咱們又讓結構清晰了一些。code
最後,咱們把 redisLock.call 裏面的 lambda 表達式分離出來。 這個 lambda 表達式表明的是 ValueLockCallback 接口。 能夠把這個表達式變成一個內部類(還原) ImageIdValueCallback :orm
private CompletableFuture<String> buildCompletableFuture(String imageId, String comId, int newGroup) { Supplier<String> futureSupplier = () -> { String lockKey = String.format("%s%s%s", comId, newGroup, imageId); return redisLock.call(lockKey, new ImageIdValueCallback(imageId, comId, newGroup)); }; CompletableFuture<String> future = CompletableFuture.supplyAsync(futureSupplier, executorService); return future; } class ImageIdValueCallback implements ValueLockCallback<String> { private String imageId; private String comId; private int newGroup; public ImageIdValueCallback(String imageId, String comId, int newGroup) { this.imageId = imageId; this.comId = comId; this.newGroup = newGroup; } @Override public String execute() { return dealWith(comId, newGroup, imageId); // dealWith 是 redisLock.call 裏面的 lambda 表達式裏的代碼塊。 } }
這樣,是否是清晰不少了 ?blog