先看例子:
//灯:有开、关两个操作
public class Light {
public void off(){
System.out.println("off...");
}
public void on(){
System.out.println("on...");
}
}
//命令
public interface Command {
public void execute();
}
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light){
this.light = light;
}
public void execute() {
light.on();
}
}
public class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light){
this.light = light;
}
public void execute() {
light.off();
}
}
//遥控器
public class RemoteControl {
Command c;
public void setCommand(Command c){
this.c = c;
}
public void pressButton(){
c.execute();
}
}
测试:
public class CommandLoader {
public static void main(String[] args) {
//遥控器对象
RemoteControl src = new RemoteControl();
//灯对象
Light light = new Light();
LightOnCommand lo = new LightOnCommand(light);
//LightOffCommand lo = new LightOffCommand(light);
src.setCommand(lo);
src.pressButton();
}
}
运行结果是:
on...
我们分析下这段代码可知,程序的最终目的是通过“遥控器”控制“灯”打开,效果类似于在RemoteControl类的pressButton()方法里直接:
Light light = new Light();
light.on();
这样很直接,也很好理解,但是灵活性不好,如果我们要换一种“灯”或者给“灯”添加一些新的操作,比如brighter()调高亮度、dim()调低亮度,就必须修改RemoteControl类了,根本原因在于上面RemoteControl类中使用了硬编码,我们把具体的类Light放进了RemoteControl类中,殊不知这个具体的东西以后可能常常有变化。
再分析下,我们上面这种写法,让RemoteControl类针对抽象的Command接口,而将Light的具体操作封装进Command的实现类中,相当于在RemoteControl和Light中间人为的加了一层,RemoteControl针对Command编程,而一个具体的Command实际上就代表了原来Light里的一个操作。
这就是命令模式:请一个请求封装成对象,从而可以使用不同的请求对客户进行参数化。
下面是命令模式的类图模型:
Invoker:命令的调用者,但却不直接与命令的实施者Receiver关联,而是关联一个Command引用;
Command:(一般用接口)表示命令,给所有需要执行的实际操作一个统一的“接口”;
ConcreteCommand: 具体的操作命令,实现Command接口,同时关联一个Receiver,表示作用在哪个实施者上面的操作;
Receiver:命令的实施者,可将它的每一种操作都封装成一个独立的命令对象,比如LightOnCommand、LightOffCommand、LightXXXCommand等,它们都实现Command接口,从而有一个共同的身份Command;
CommandLoader: 负责组装Reveiver和ConceteCommand,实际的客户端操作Invoker对象。
仔细分析命令模式,可以看出它有很多好处:
1、请求的调用者与请求的实施者解耦
Invoker(请求调用者)不用像以前一样知道每一Receiver(请求的实施者),假如我们要扩展Light,例如添加一个dim()方法调低亮度,RemoteControl完全不用修改,只用添加一个LightDimCommand命令,在把它动态组装到ConreteCommand中即可。
2、可实现撤销功能
不使用命令模式时,light.on()就是一个原子操作,执行完了就完了,而命令模式中由于我们把这个操作封装进了一个对象中,而对象是一个实实在在的有状态的东西,我们可以把它保存起来,这样即使操作结束,由于我们之前保存了那个命令对象,我们也就知道它到底干了什么,当然也就可以撤销了。
我们甚至可以多级撤销,只要将命令对象存放进一个stack栈中,之后便可以轻松取出来。
总结:
命令模式的关键点在于:共同的接口Command、用Command对象封装每一个请求。另外,对象有状态、可以保存,以至于我们可以拿这些对象做一些扩展的功能。
分享到:
相关推荐
《白话设计模式》文档很可能是以通俗易懂的方式介绍设计模式的入门读物。 在软件开发过程中,设计模式可以帮助我们更有效地组织代码,提高代码的可读性和可维护性。设计模式通常分为三类:创建型、结构型和行为型...
15. 命令模式:将请求封装为一个对象,以便使用不同的请求、队列请求、记录请求或支持可撤销的操作,如模型的保存和恢复操作。 16. 访问者模式:允许在不改变元素类的情况下,增加对元素的新操作,如对模型的可视化...
在本文中,我们将深入探讨WPF(Windows Presentation Foundation)中的MvvM(Model-View-ViewModel)设计模式,这是现代Windows应用程序开发中的一个重要概念。WPF是.NET Framework的一部分,提供了丰富的用户界面...
通过子命令可以指定要运行的算法,可选子命令包括`rf`, `knn`和 `cnn`。 # 仅使用cnn算法对MNIST分类 python main.py cnn 指定子命令后,可以设置算法相关参数,各算法配置项如下所示。 ## RF配置项 通过`--...
在本项目中,我们使用的是一种基于WPF(Windows Presentation Foundation)框架和MVVM(Model-View-ViewModel)设计模式的实现方式。下面将详细阐述这两个关键知识点。 **Windows Presentation Foundation (WPF)** ...
cqrs,全称为Command Query Responsibility Segregation(命令查询职责分离),是一种软件设计模式,它将一个应用程序的读写操作分开,以提高系统的性能和可维护性。在CQRS架构中,命令部分负责处理修改数据的操作,...
在.NET Core平台上,WPF(Windows Presentation Foundation)框架与Prism Unity结合,为开发者提供了强大的MVVM(Model-View-ViewModel)设计模式实现工具。Prism是一个开源库,旨在简化XAML应用程序的开发,尤其是...
6. **MVVM模式**: Model-View-ViewModel(MVVM)是一种软件设计模式,特别适合WPF应用。ViewModel作为Model和View之间的桥梁,负责处理业务逻辑和UI交互,实现数据双向绑定。 **MVVM模式详解** 1. **Model**: 模型...
2. **MVVM模式**:为了实现可维护和可测试的代码,我们通常采用Model-View-ViewModel (MVVM)设计模式。模型代表业务逻辑和数据,视图是用户看到的界面,而视图模型作为两者之间的桥梁,处理数据绑定和命令。 3. **...
这个项目对于学习者来说,尤其适用于毕业设计或课程设计作业,因为它涵盖了Web开发中的核心概念和技术。 首先,让我们深入了解一下每个组成部分: 1. **Servlet**:Servlet是Java提供的一种用于扩展服务器功能的...
1. **MVVM模式**:Model-View-ViewModel模式是WPF开发中的常用设计模式,有助于实现更清晰的代码结构。 2. **动画和视觉状态管理**:利用动画和视觉状态使UI更具交互性和动态效果。 3. **附加属性和行为**:扩展WPF...
7. **MVVM模式**: Model-View-ViewModel(MVVM)是一种设计模式,常用于WPF应用开发。它将业务逻辑(Model)、用户界面(View)和数据绑定逻辑(ViewModel)分离,使得代码更加结构化,便于测试和维护。 ### MVVM...
1. **模块化**:Prism中的模块化允许将应用程序拆分为独立的功能单元,每个模块可以单独开发、测试和部署。这降低了系统的复杂性,增强了可扩展性。 2. **依赖注入**:通过Unity Container,Prism实现了依赖注入,...
**WPF(Windows Presentation Foundation)**是...为了深入学习WPF,除了熟悉这些基础知识外,还需要了解事件处理、命令模式、资源字典、控件的自定义和扩展、以及MVVM(Model-View-ViewModel)设计模式等高级主题。
5. MVC架构:Laravel遵循Model-View-Controller(MVC)设计模式,将业务逻辑、数据处理和用户界面分离,使代码结构清晰,便于维护。 6. 身份验证和授权:Laravel提供了内置的认证服务,可以帮助开发者快速实现用户...
首先,Laravel 是一个优雅的 PHP Web 开发框架,它遵循 MVC(Model-View-Controller)设计模式,提供了一套简洁、强大的工具,使得开发者可以更高效地编写代码。Laravel-Admin 则是在此基础上构建的,它引入了 ...
1. **package.json**:定义项目依赖和配置信息,通过`npm install`命令安装所有依赖库。 2. **index.js**或**app.js**:入口文件,初始化服务器,设置路由,处理HTTP请求。 3. **models**目录:存放与数据库交互的...
3. **恢复数据库**:在不同模式下执行恢复操作,如NOARCHIVELOG模式下的恢复。 **RMAN恢复** - **还原与恢复的区别**:还原是指将备份文件恢复到特定位置,而恢复则是指通过应用归档日志和联机日志,确保数据库...
1. **分类问题**:如使用SVM或神经网络对分类数据进行建模,可能涵盖手写数字识别、图像分类等场景。 2. **回归分析**:可能包括线性回归、多项式回归或非线性回归,用于预测连续变量。 3. **聚类分析**:K-means或...