目录
命令模式
什么是命令模式?
命令模式是一种行为型设计模式,主要就是将每种请求或对象封装为一个独立的对象,从而可以集中管理这些请求或操作,比如 多个操作打包成一个执行、请求队列化执行、对操作进行日志记录、撤销.......
命令模式通过将请求的 发送者(客户端) 和 接收者(请求的执行者) 进行解耦,提高了更大的维护性和灵活性.
例如,电视机和遥控器,我们就相当于客户端,通过 遥控器(命令调用者)上的按钮(具体命令),来操控电视(请求执行者)。
这样一来,我们 和 电视机 就解耦了,哪怕遥控器丢了,换个遥控器就可以,不用关心设备到底是什么样的,十分便利.
命令模式的优点和应用场景
a)优点:最大的优点就是将请求发送者和请求执行者解耦,提高系统的灵活、可扩展性.
b)使用场景:
- 将多个操作打包成一个执行(事务协调).
- 操作排队.
- 记录操作日志.
- 撤销重做.
实战案例
例如,在一个大型的博客系统中,文章会被进行垂直分表,比如分成 文章基本信息表、文章内容表、文章照片表、文章统计信息表...... 这样一来光是一个发布文章的业务(新增文章)都十分麻烦. 这要是一串都写 Service 里,妥妥的屎山~
因此我们这里可以使用 命令模式 不仅能实现解耦,事务的管理也统一了.
a)命令接口:对命令进行规范
interface ArticleCommand<T> {
fun execute(obj: T)
}
b)具体命令:命令接口的实现,提供了多种不同复杂命令(多个操作进行打包).
//具体命令
//@Component 将来可以通过构造方法注入
class CreateArticleCommand(
private val articleInfoRepo: ArticleInfoRepo,
private val articleStatRepo: ArticleStatRepo,
private val articlePhotoRepo: ArticlePhotoRepo,
): ArticleCommand<Article> {
override fun execute(obj: Article) {
//1.创建文章基本信息
articleInfoRepo.save(obj)
//2.创建文章统计信息
articleStatRepo.save(obj)
//3.创建文章图片信息
articlePhotoRepo.save(obj)
}
}
//具体命令
//@Component 将来可以通过构造方法注入
class DeleteArticleCommand(
private val articleInfoRepo: ArticleInfoRepo,
private val articleStatRepo: ArticleStatRepo,
private val articlePhotoRepo: ArticlePhotoRepo,
): ArticleCommand<Long> {
override fun execute(obj: Long) {
//1.删除文章基本信息
articleInfoRepo.del(obj)
//2.删除文章统计信息
articleStatRepo.del(obj)
//3.删除文章图片信息
articlePhotoRepo.del(obj)
}
}
c)命令调用者
//@Component
class ArticleCommandInvoker {
fun <T> execute(cmd: ArticleCommand<T>, obj: T) {
cmd.execute(obj)
}
}
d)将来在 Service 中直接通过命令调用者,就可以执行对应的命令.
class ArticleService(
private val articleCommandInvoker: ArticleCommandInvoker,
private val createArticleCommand: CreateArticleCommand,
) {
fun pub(article: Article) {
articleCommandInvoker.execute(createArticleCommand, article)
}
}