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 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 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 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 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 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 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 傻 瓜 阅读(333) 评论(0)  编辑  收藏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值