java随记

坚持就是胜利!

 

优秀代码赏析

看开源的源代码,看到一个有意思的实现 。
/*
 * Copyright 2019 IBM All Rights Reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
package org.hyperledger.fabric.gateway;
import org.hyperledger.fabric.gateway.impl.AllCommitStrategy;
import org.hyperledger.fabric.gateway.impl.AnyCommitStrategy;
import org.hyperledger.fabric.gateway.impl.CommitHandlerImpl;
import org.hyperledger.fabric.gateway.impl.CommitStrategy;
import org.hyperledger.fabric.gateway.impl.NoOpCommitHandler;
import org.hyperledger.fabric.gateway.spi.CommitHandler;
import org.hyperledger.fabric.gateway.spi.CommitHandlerFactory;
import org.hyperledger.fabric.sdk.Peer;
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import java.util.Collection;
/**
 * Default commit handler implementations. Instances can be referenced directly or looked up by name, for example
 * {@code DefaultCommitHandlers.valueOf("NONE")}.
 */
public enum DefaultCommitHandlers implements CommitHandlerFactory {
    /**
     * Do not wait for any commit events to be received from peers after submitting a transaction.
     */
    NONE((transactionId, network) -> NoOpCommitHandler.INSTANCE),
    /**
     * Wait to receive commit events from all currently responding peers in the user's organization after submitting
     * a transaction.
     */
    MSPID_SCOPE_ALLFORTX((transactionId, network) -> {
        Collection<Peer> peers = getPeersForOrganization(network);
        CommitStrategy strategy = new AllCommitStrategy(peers);
        CommitHandler handler = new CommitHandlerImpl(transactionId, network, strategy);
        return handler;
    }),
    /**
     * Wait to receive commit events from all currently responding peers in the network after submitting a transaction.
     */
    NETWORK_SCOPE_ALLFORTX((transactionId, network) -> {
        Collection<Peer> peers = network.getChannel().getPeers();
        CommitStrategy strategy = new AllCommitStrategy(peers);
        CommitHandler handler = new CommitHandlerImpl(transactionId, network, strategy);
        return handler;
    }),
    /**
     * Wait to receive a commit event from any currently responding peer in the user's organization after submitting
     * a transaction.
     */
    MSPID_SCOPE_ANYFORTX((transactionId, network) -> {
        Collection<Peer> peers = getPeersForOrganization(network);
        CommitStrategy strategy = new AnyCommitStrategy(peers);
        CommitHandler handler = new CommitHandlerImpl(transactionId, network, strategy);
        return handler;
    }),
    /**
     * Wait to receive a commit event from any currently responding peer in the network after submitting a transaction.
     */
    NETWORK_SCOPE_ANYFORTX((transactionId, network) -> {
        Collection<Peer> peers = network.getChannel().getPeers();
        CommitStrategy strategy = new AnyCommitStrategy(peers);
        CommitHandler handler = new CommitHandlerImpl(transactionId, network, strategy);
        return handler;
    });
    private final CommitHandlerFactory factory;
    DefaultCommitHandlers(CommitHandlerFactory factory) {
        this.factory = factory;
    }
    private static Collection<Peer> getPeersForOrganization(Network network) {
        String mspId = network.getGateway().getIdentity().getMspId();
        try {
            return network.getChannel().getPeersForOrganization(mspId);
        } catch (InvalidArgumentException e) {
            // This should never happen as mspId should not be null
            throw new RuntimeException(e);
        }
    }

   //CommitHandlerFactory 接口定义 的方法,这里是其实现 
    public CommitHandler create(String transactionId, Network network) {
        return factory.create(transactionId, network);
    }
}

先看看enum类的构造函数
    DefaultCommitHandlers(CommitHandlerFactory factory) {
        this.factory = factory;
    }
需要一个 CommitHandlerFactory 是个接口,同时 enum类本身也实现了这个接口。
再来看调用过程 
CommitHandlerFactory commitHandlerFactory = DefaultCommitHandlers.MSPID_SCOPE_ALLFORTX;
这里会调用CommitHandlerFactory 构造函数,其传入参数是
(transactionId, network) -> {
        Collection<Peer> peers = network.getChannel().getPeers();
        CommitStrategy strategy = new AllCommitStrategy(peers);
        CommitHandler handler = new CommitHandlerImpl(transactionId, network, strategy);
        return handler;
    }
它是lamdba写法,看看构造函数需要一个 CommitHandlerFactory 接口,这个lamdba 函数其实就是CommitHandlerFactory 的实现。
这样MSPID_SCOPE_ALLFORTX 枚举类型就有了一个  CommitHandlerFactory实现类的引用。

再看create调用。
CommitHandler commitHandler = commitHandlerFactory.create(transactionId, network);
这里enum类的create方法会执行, return factory.create(transactionId, network);
返回一个 CommitHandler .这里才会真正执行那个 lamdba定义的函数。
到这里只看到lamdb应用。。。
再分析一下create ,枚举类里的每个枚举变量都会实现一个这个方法。这里可以看到它其实是一个工厂类。
它创造的产品是CommitHandler ,其具体实现是CommitHandlerImpl类。
这里巧妙的使用一个enum当工厂类的实现。整个代码用了工厂模式加策略模式的实现。
优点:得宜于lamdb的应用,减少了具体工厂类的实现。
缺点:工厂模式可以实现不改动程序创建产品。那么这里如果要增一个产品,对这个enum类需要再添加一个枚举变量。
这个enum类有改动。


posted on 2019-07-06 12:06 傻 瓜 阅读(758) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(7)

我参与的团队

随笔分类

随笔档案

文章分类

友情链接

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜