SOA都离不开网络,现在的框架都集成了自己网络传输模块。但如果要自己写框架的时候,就需要思考如何设计了?出于这种好奇,尝试一下自己设计。

首先要考虑远端传输需要满足什么,一般有哪些抽象实体,一般传输过程是怎么样的。既然面向对象思想是面向接口编程。又需要设计怎么样的接口来满足日后的扩展。这些都是我们需要思考的问题。

基于性能考虑,都用NIO网络编程。一般都有Channel,所以还需要设计Channel接口,负责连接通道的逻辑处理。具体的请求和响应还需要有东西去执行,为了执行方式更容易扩展,还需要设计ChannelHandler接口。顾名思义,ChannelHandler和Channel相关联,它是Channel请求和响应的实际执行者。这里很多时候用到了桥接模式,将抽象部分和实现部分分离,使它们可以独立的变化。

public interface Channel extends Endpoint{
ChannelHandler getChannelHandler();
InetSocketAddress getRemoteAddress();
boolean isConnnect();
void send(Object message);

}

Endpoint用来抽象共有的接口方法:

public interface Endpoint {
ChannelHandler getChannelHandler();
void close();
boolean isClosed();
}

ChannelHandler

public interface ChannelHandler {
//带上Channel,做成无状态化设计,有利保证线程安全
void send(Channel channel, Object message);
void receive(Channel channel, Object message) throws Exception;
}

传输一般由一方发起请求,另一方响应后再返回数据。这些都是C/S结构。所以应该有Client接口和Server接口。Server负责监听,建立连接,响应请求;client负责发起请求,接收响应。

Server接口:

public interface Server extends Endpoint{
void bind(InetSocketAddress address) throws InterruptedException;
}

Client接口

public interface Client {
Channel connect(InetSocketAddress inetSocketAddress) throws Exception;
}

每个接口最好设计一个抽象类,通常叫做AbstractXXX。在这个抽象类中实现默认功能,同时可以回调子类的方法。这也就是常说的骨架类(skeleton class).

比如如下AbstractServer接口和AbstractChannelHandler

public abstract class AbstractServer implements Server{
protected final ChannelHandler channelHandler;
private volatile boolean closed;
public AbstractServer(ChannelHandler handler){
this.channelHandler = handler;
}
public ChannelHandler getChannelHandler(){
return channelHandler;
}
}

AbstractChannelHandler接口

public abstract class AbstractChannelHandler implements ChannelHandler {
@Override
public void send(Channel channel, Object object) {
channel.send(object);
}
}

这里只是给了接口定义,其实还有许多需要考虑的:为了方便,一般都有类似Factory的工具类,用来创建实现;为了丰富接口方法,还会经常用包装模式包装接口,增加接口的功能;还有解码和编码的接口。这里都没有给出例子。

源码在​​https://github.com/Jdoing/example/tree/master/example-transport/src/main/java/example/transport​

下篇接介绍用netty去实现。