命令设计模式
(Command Pattern)是一种行为设计模式,它将请求的操作封装为一个对象,从而实现请求者和执行者之间的解耦。这样,请求者只需要知道如何发送请求,而无需关心请求的具体执行过程。命令模式在很多场景下都非常有用,例如撤销操作、延迟执行、记录操作日志等。
execute()
的方法。// 抽象命令
interface Command {
void execute();
}
// 具体命令
class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
}
// 接收者
class Receiver {
void action() {
System.out.println("执行具体操作");
}
}
// 请求者
class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void invoke() {
command.execute();
}
}
// 客户端代码
public class CommandPatternDemo {
public static void main(String[] args) {
//**在这个示例中,我们定义了一个抽象命令Command接口和一个具体命令ConcreteCommand类。具体命令封装了接收者Receiver的操作逻辑。请求者Invoker负责调用命令对象来执行请求。客户端代码创建了接收者、具体命令和请求者,并通过调用请求者的invoke()方法来执行请求。这样,请求者和接收者之间实现了解耦,使得代码更加灵活、易于维护。**/
// 创建接收者
Receiver receiver = new Receiver();
// 创建具体命令
Command command = new ConcreteCommand(receiver);
// 创建请求者
Invoker invoker = new Invoker();
invoker.setCommand(command);
// 执行请求
invoker.invoke();
}
}
在Dubbo框架中,命令模式被用于处理网络通信中的请求和响应。下面是相关流程中的简版代码
1、org.apache.dubbo.remoting.exchange.ExchangeChannel
接口。这是Dubbo通信层中的一个关键接口,它代表了一个通信通道。其中,request(Object request)
方法用于发送请求,而send(Object message)
方法用于发送响应:
public interface ExchangeChannel extends Channel {
CompletableFuture<Object> request(Object request) throws RemotingException;
CompletableFuture<Object> request(Object request, int timeout) throws RemotingException;
void send(Object message) throws RemotingException;
// 省略部分代码...
}
2、当通道收到一个请求或响应时,它会将其封装为org.apache.dubbo.remoting.exchange.Request
或org.apache.dubbo.remoting.exchange.Response
对象。这两个类分别表示请求和响应,其中Request
类包含请求的数据以及请求的ID,而Response
类包含响应的数据、状态以及请求的ID:
public class Request {
private final long id;
private String version;
private boolean twoWay = true;
private boolean event = false;
private Object data;
// 省略部分代码...
}
public class Response {
private final long id;
private String version;
private int status;
private boolean event = false;
private Object result;
private Throwable exception;
// 省略部分代码...
}
3、在通信层,有一个org.apache.dubbo.remoting.Dispatcher
接口,它负责分发请求和响应。分发器会将收到的请求和响应封装为ChannelHandler
对象,并调用相应的方法进行处理。例如,当分发器收到一个请求时,它会调用ChannelHandler
的received(Channel channel, Object message)
方法进行处理:
public interface ChannelHandler {
void connected(Channel channel) throws RemotingException;
void disconnected(Channel channel) throws RemotingException;
void sent(Channel channel, Object message) throws RemotingException;
void received(Channel channel, Object message) throws RemotingException;
void caught(Channel channel, Throwable exception) throws RemotingException;
}
4、对于请求的处理,通常会使用org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler
类。这个类实现了ChannelHandler
接口,并重写了received(Channel channel, Object message)
方法。在这个方法中,它首先判断收到的消息是否为Request
对象,然后根据请求的类型(如普通请求、心跳请求等)进行相应的处理:
public class HeaderExchangeHandler implements ChannelHandlerDelegate {
//展示相关代码
@Override
public void received(Channel channel, Object message) throws RemotingException {
if (message instanceof Request) {
//省略部分代码
// 处理请求
handleRequest(channel, (Request) message);
} else if (message instanceof Response) {
// 处理响应
handleResponse(channel, (Response) message);
} else {
//省略部分代码
// 对于其他类型的消息,调用父类的方法进行处理
handler.received(channel, message);
}
}
}
undo
的方法,以便在需要时撤销操作。具体命令类可以保存先前的状态,以便在执行undo
方法时能够恢复原始状态。