基本概念
Command
- 命令模式是一个高内聚的模式(满足单一职责原则)
- 概念:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
- 命令模式在项目中频繁使用,封装性和拓展性都有很好的保障
- Command模式中的角色分工:
- Client:创建一个命令并决定接受者
- Command:命令接口,定义一个抽象方法
- Concrete Command:具体命令,负责调用接受者的相关操作
- Invoker:请求者,负责调用命令对象执行请求
- Receiver:接受者,负责具体实施和执行一次请求
- 命令模式的主要作用就是封装命令,把发出命令的责任(Client)和执行命令(Invoker)的责任分开,也是一种功能的分工
- 命令模式的优点:
- 类间解耦
调用者与接收者角色之间不存在依赖关系,调用者只需调用(*Invoke)命令(Command),无需关注接收者(Receiver) - 可拓展性
Command子类可以轻易拓展,因为耦合存在于抽象层,不影响命令的具体实现 - 可合作性
- 可以结合责任链模式,实现命令族解析任务
- 可以结合模板方法模式,弱化Command子类膨胀的问题
- 类间解耦
例讲Command
像我们这种程(diao)序(si)员(nan),虽然是足够聪明能够知道基本是不存在被女神看上的概率的,但是还是甘于做备胎,对女神唯命是从(最起码女神有事的时候还是挺温柔的……),那么女神(Invoker)的请求自然也就是命令了,而往往程序员会利用身边同样无辜的程序员分工合作达到女神的要求
代码实现如下:
* Created by liulin on 16-4-25.
*/
interface Receiver{
void code();
}
interface Command{
void execute();
}
class DBA implements Receiver{
@Override
public void code() {
System.out.println("Database Ready!");
}
}
class Javaer implements Receiver{
@Override
public void code() {
System.out.println("Background Finish!");
}
}
class Designer implements Receiver{
@Override
public void code() {
System.out.println("Html done!!!");
}
}
class WebAppRequirement implements Command{
private Receiver a = new Designer();
private Receiver b = new Javaer();
private Receiver c = new DBA();
@Override
public void execute() {
a.code();
b.code();
c.code();
System.out.println("The WebApp done!");
}
}
class Invoker{
private Command command;
public void action (){
this.command.execute();
}
public void setCommand(Command command) {
this.command = command;
}
}
public class CommandTest {
public static void main ( String [] args ){
Invoker goddess = new Invoker();
goddess.setCommand( new WebAppRequirement());
goddess.action();
}
}
效果如下:
Tomcat中Command模式的应用
Tomcat作为一个应用服务器,无疑会收到很多请求,如何分配和执行这些请求是必须的功能,这部分功能主要靠Connector和Container组件实现。
- Tomcat中的角色对应如下:
- Connector:抽象的Invoker
- HttpConnector:具体的Invoker
- HttpProcessor:Command
- Container:Command的抽象Receiver
- ContainerBase:Command的具体的Receiver
- Server组件:Client
- 具体的逻辑实现如下:
- Server首先创建命令请求者HttpConnector对象
- 然后创建命令HttpProcessor对象
- 再把命令Command对象交给命令Receiver的ContainerBase容器来处理。
- 命令最终是被Tomcat的Container执行的。