初学接口,我们觉得它是java一个解决多继承的方式。学深了以后就会觉得接口是一个功能的标志,不关里面有没有函数声明。再加上多态的加持,可以解决一些特殊的结构性的问题。
这次我以一个例子来构造一个组合型的操作。这是我做的netty-udp重传操作里的部分内容,来说明接口的声明和使用。并且通过这个例子,可以让我们透视下大牛们在构造包结构时的想法和高瞻远瞩。
首先上个结构图:
这里先说明下,我想构造的操作结构有两种,一种是简单操作,三次超时返回失败,如果有响应返回正常结果。还有一种操作是复杂操作,复杂操作可以包含另外的操作比如简单操作和复杂操作。复杂操作的返回结果是所有里面操作的结果。复杂操作又分两种一种是里面所有的子操作并发的,还有一种是顺序的。
so,我的根的接口那么就是IOperation
1 2 3 4 5
| public interface IOperation {
}
|
另外,为了使得我的复杂操作能够加入某个子操作(可能是复杂的,可能是简单的),那么定义了个IParent接口
1 2 3 4 5 6
| public interface IParent {
void addProtocolOneOperation(IOperation ProtocolOperation); }
|
另外为了使子操作能够把结果交给父操作还定义了一个IChild接口
1 2 3 4 5 6
| public interface IChild {
IProtocolComplexOperation parent(); }
|
好了先定义简单操作,IProtocolSimpleOperation接口继承了IOperation和IChild。
1 2 3 4 5 6 7 8 9
| public interface IProtocolSimpleOperation extends IOperation,IChild{
Object doRpc(int retrytimes,long timeOut);
Object doIt();
}
|
再定义复杂操作接口IProtocolComplexOperation,继承了IOperation,IChild和IParent。为什么需要IChild,因为复杂操作里可能还包括复杂操作
是这么设计的。还有两个得到返回结果的函数。
1 2 3 4 5 6
| public interface IProtocolComplexOperation extends IOperation,IParent,IChild {
ConcurrentHashMap<IOperation, RpcResult> getRpcResultMap(); Vector<RpcResult> getRpcResultVector(); }
|
后面定义两个并发的复杂操作和顺序的复杂操作。
1 2 3 4 5 6
| public interface IProtocolMutiCurrOperation extends IProtocolComplexOperation{ Object doAllCurrconcurrent();
}
|
1 2 3 4 5
| public interface IProtocolSeqOperation extends IProtocolComplexOperation{ Object doItSequence();
}
|
这样整个接口结构就比较完整了。那么我还实现了两个抽象类 AbstractSimpleOperation和AbstractComplexOperation
来实现一些缺省的函数。
具体的和项目相关。就不在细说,有兴趣的可以留言。
贴下AbstractComplexOperation里的函数实现,是个递归实现返回结果,尤其是复杂操作套复杂操作等等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| public abstract class AbstractComplexOperation implements IProtocolMutiCurrOperation, IResponseOperationHandler {
略
@Override public Object doAllCurrconcurrent() {
Vector<IFindNode> vector = new Vector<>(); for (Map.Entry<IOperation, RpcResult> entry : rpcResultMap.entrySet()) { IOperation iOperation = entry.getKey(); ProtocolTask protocolTask=new ProtocolTask(iOperation); BaseMap.kadServer.submit(protocolTask).addListener(new GenericFutureListener<Future<? super Object>>() { @Override public void operationComplete(Future<? super Object> future) throws Exception { setResult(future, iOperation); } });
}
while (rpcResultVector.size() != rpcResultMap.size()) ; log.info("收到全部结果2"); // IProtocolComplexOperation iProtocolComplexOperation= ((IChild) iOperation).parent();; // if(iProtocolComplexOperation!=null) return iProtocolComplexOperation.getRpcResultVector(); return rpcResultVector; }
private void setResult(Future<? super Object> future, IOperation iProtocolOperation) { if (((IChild) iProtocolOperation).parent() != null) {
IProtocolComplexOperation iProtocolComplexOperation = ((IChild) iProtocolOperation).parent(); RpcResult rpcResult = new RpcResult(); if (future.getNow() != null) { Object o = future.getNow();
rpcResult.setObj(o); iProtocolComplexOperation.getRpcResultVector().addElement(rpcResult);
iProtocolComplexOperation.getRpcResultMap().put(iProtocolOperation, rpcResult); } else {
rpcResult.setObj(null); iProtocolComplexOperation.getRpcResultVector().addElement(rpcResult);
iProtocolComplexOperation.getRpcResultMap().put(iProtocolOperation, rpcResult); } }
}
略
}
|