其实这个应该挺好理解的,可以跟工厂模式,策略模式做个对比,工厂模式注重的是创建不同的对象,毕竟是创建型设计模式。策略模式是行为型设计模式,注重选择不同的策略以及对应后面的算法。命令模式跟二者结构很像,可以理解为在进一步的策略模式,直接根据一个简单的命令去执行后面对应的逻辑。
设计模式其实很多结构都是大同小异,因为毕竟语言特性也就那些,继承,实现,组合这些,再加上一些数据结构。很多区别就是后面的意图。
创建型针对的是对象的创建和管理,
结构型是关于这个结构的解耦,不要一坨,能够充分的复用,也就是DRY原则,do not repaet yousrself,一次且仅一次。
行为型则是对应行为设计和逻辑处理的解耦
Command Design Pattern 行为模式 GoF定义:
The command pattern encapsulates a request as an object, thereby
letting us parameterize other objects with different requests, queue
or log requests, and support undoable operations.
命令模式将请求(命令)封装为一个对象,这样可以使用不同的请求参数化其他对象(将不同请求依赖注入到其他对象),并且能够支持请求(命令)的排队执行、记录日志、撤销等(附加控制)功能。
代码同样通过游戏的demo
public interface Command {
void execute();
}
public class GotDiamondCommand implements Command {
// 省略成员变量
public GotDiamondCommand(/*数据*/) {
//...
}
@Override
public void execute() {
// 执行相应的逻辑
}
}
//GotStartCommand/HitObstacleCommand/ArchiveCommand类省略
public class GameApplication {
private static final int MAX_HANDLED_REQ_COUNT_PER_LOOP = 100;
private Queue<Command> queue = new LinkedList<>();
public void mainloop() {
while (true) {
List<Request> requests = new ArrayList<>();
//省略从epoll或者select中获取数据,并封装成Request的逻辑,
//注意设置超时时间,如果很长时间没有接收到请求,就继续下面的逻辑处理。
for (Request request : requests) {
Event event = request.getEvent();
Command command = null;
if (event.equals(Event.GOT_DIAMOND)) {
command = new GotDiamondCommand(/*数据*/);
} else if (event.equals(Event.GOT_STAR)) {
command = new GotStartCommand(/*数据*/);
} else if (event.equals(Event.HIT_OBSTACLE)) {
command = new HitObstacleCommand(/*数据*/);
} else if (event.equals(Event.ARCHIVE)) {
command = new ArchiveCommand(/*数据*/);
} // ...一堆else if...
queue.add(command);
}
int handledCount = 0;
while (handledCount < MAX_HANDLED_REQ_COUNT_PER_LOOP) {
if (queue.isEmpty()) {
break;
}
Command command = queue.poll();
command.execute();
}
}
}
}
这里有一个人总结的关于结构大差不差的设计模式对比很不错,摘抄一下:
单例模式和享元模式,缓存,静态工厂方法: 他们的共同点是:对象的复用 不同点: 应用享元模式是为了对象"共享使用",节省内存
而应用单例/多例模式是为了限制对象的个数 应用缓存是为了提高访问效率
应用对象池(数据库连接池,线程池)是为了对象的"重复使用"和管理,主要是为了节省时间 有一种方法叫 静态工厂方法,例如
Boolean.valueof(),不会在每次调用时返回一个新对象,而是复用已有的,这一点有点像享元模式适配器,代理,装饰器,桥接,: 他们的共同点是:对方法的增强 不同点: 适配器模式的作用是"适配",通常用于适配不同的组件,新旧系统
桥接模式将接口部分和实现部分分离,使两者可以分别扩展 装饰者模式是对原始类功能进行增强,并且可以支持多次,多种增强
代理模式实现了代理类和原始类的解耦,使代理类可以用于增强不同的功能策略模式与简单工厂模式,命令模式: 共同点:都有对if/else进行下沉 不同点:
策略模式根据运行时状态返回一个"策略"/“算法”,这些"策略"具有相同目的,比如BubbleSort、SelectionSort
都是为了实现排序 命令模式中不同的命令具有不同的目的,对应不同的处理逻辑,并且互相之间不可替换 而简单工厂更侧重返回一个创建的对象桥接模式与服务提供者框架,静态工厂的辨析(来自effective java): 服务提供者框架是这样一个系统:
多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把它们从多个实现中解耦出来 它分为四部分:
服务接口:系统抽象出一个接口,交给服务提供者实现(JDBC中的connection即为服务接口)
提供者注册API:交给服务提供者注册自己的API
(Class.forName(),将自己的Driver类加载到JVM中,JDBC会查找该类并注册他的api)
服务访问API:是一个静态方法,供客户端获取服务实例(DriverManager.gtConnection()便是此处的静态工厂,它拿到的connection实例,其实是mysql包里的connection实现)
服务提供者接口:是服务接口实例的工厂对象(在此为mysql包内的Driver类)在此处,桥接模式和静态工厂方法的使用,共同构成了服务提供者框架