`
tgwiloveyou
  • 浏览: 9834 次
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

白话设计模式_命令模式1

阅读更多

        先看例子:

//灯:有开、关两个操作
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对象封装每一个请求。另外,对象有状态、可以保存,以至于我们可以拿这些对象做一些扩展的功能。

 

分享到:
评论

相关推荐

    设计模式入门众多好东西大集合

    《白话设计模式》文档很可能是以通俗易懂的方式介绍设计模式的入门读物。 在软件开发过程中,设计模式可以帮助我们更有效地组织代码,提高代码的可读性和可维护性。设计模式通常分为三类:创建型、结构型和行为型...

    以深度学习的模型搭建和训练过程为例,解释面向对象编程中22种设计模式的基本原理.zip

    15. 命令模式:将请求封装为一个对象,以便使用不同的请求、队列请求、记录请求或支持可撤销的操作,如模型的保存和恢复操作。 16. 访问者模式:允许在不改变元素类的情况下,增加对元素的新操作,如对模型的可视化...

    这是一个学习WPF中MvvM模式的仓库.zip

    在本文中,我们将深入探讨WPF(Windows Presentation Foundation)中的MvvM(Model-View-ViewModel)设计模式,这是现代Windows应用程序开发中的一个重要概念。WPF是.NET Framework的一部分,提供了丰富的用户界面...

    模式识别,课程设计,实验作业,使用使用随机森林, K近邻, 卷积神经网络识别MNIST数据集,对比验证,手写数据识别实验报告

    通过子命令可以指定要运行的算法,可选子命令包括`rf`, `knn`和 `cnn`。 # 仅使用cnn算法对MNIST分类 python main.py cnn 指定子命令后,可以设置算法相关参数,各算法配置项如下所示。 ## RF配置项 通过`--...

    日程管理软件.zip

    在本项目中,我们使用的是一种基于WPF(Windows Presentation Foundation)框架和MVVM(Model-View-ViewModel)设计模式的实现方式。下面将详细阐述这两个关键知识点。 **Windows Presentation Foundation (WPF)** ...

    cqrs是基于事件回溯的高性能架构,主要针对单个领域业务高度复杂且需要高性能的业务场景

    cqrs,全称为Command Query Responsibility Segregation(命令查询职责分离),是一种软件设计模式,它将一个应用程序的读写操作分开,以提高系统的性能和可维护性。在CQRS架构中,命令部分负责处理修改数据的操作,...

    使用 Prism Unity 实现 .NET Core WPF MVVM 学习实例教程.zip

    在.NET Core平台上,WPF(Windows Presentation Foundation)框架与Prism Unity结合,为开发者提供了强大的MVVM(Model-View-ViewModel)设计模式实现工具。Prism是一个开源库,旨在简化XAML应用程序的开发,尤其是...

    WPF上位机学习实践.zip

    6. **MVVM模式**: Model-View-ViewModel(MVVM)是一种软件设计模式,特别适合WPF应用。ViewModel作为Model和View之间的桥梁,负责处理业务逻辑和UI交互,实现数据双向绑定。 **MVVM模式详解** 1. **Model**: 模型...

    使用WPF模仿Microsoft ToDo 应用程序.zip

    2. **MVVM模式**:为了实现可维护和可测试的代码,我们通常采用Model-View-ViewModel (MVVM)设计模式。模型代表业务逻辑和数据,视图是用户看到的界面,而视图模型作为两者之间的桥梁,处理数据绑定和命令。 3. **...

    用户信息管理系统,采用servlet+mysql+jdbc技术和借助springMVC开发模式.zip

    这个项目对于学习者来说,尤其适用于毕业设计或课程设计作业,因为它涵盖了Web开发中的核心概念和技术。 首先,让我们深入了解一下每个组成部分: 1. **Servlet**:Servlet是Java提供的一种用于扩展服务器功能的...

    WPF学习,入门.zip

    1. **MVVM模式**:Model-View-ViewModel模式是WPF开发中的常用设计模式,有助于实现更清晰的代码结构。 2. **动画和视觉状态管理**:利用动画和视觉状态使UI更具交互性和动态效果。 3. **附加属性和行为**:扩展WPF...

    WPF的学习.zip

    7. **MVVM模式**: Model-View-ViewModel(MVVM)是一种设计模式,常用于WPF应用开发。它将业务逻辑(Model)、用户界面(View)和数据绑定逻辑(ViewModel)分离,使得代码更加结构化,便于测试和维护。 ### MVVM...

    WPF Prism框架应用学习.zip

    1. **模块化**:Prism中的模块化允许将应用程序拆分为独立的功能单元,每个模块可以单独开发、测试和部署。这降低了系统的复杂性,增强了可扩展性。 2. **依赖注入**:通过Unity Container,Prism实现了依赖注入,...

    学习wpf应用.zip

    **WPF(Windows Presentation Foundation)**是...为了深入学习WPF,除了熟悉这些基础知识外,还需要了解事件处理、命令模式、资源字典、控件的自定义和扩展、以及MVVM(Model-View-ViewModel)设计模式等高级主题。

    基于Laravel5.3的后台基本管理系统.zip

    5. MVC架构:Laravel遵循Model-View-Controller(MVC)设计模式,将业务逻辑、数据处理和用户界面分离,使代码结构清晰,便于维护。 6. 身份验证和授权:Laravel提供了内置的认证服务,可以帮助开发者快速实现用户...

    基于 laravel-admin 实现的 oa 系统.zip

    首先,Laravel 是一个优雅的 PHP Web 开发框架,它遵循 MVC(Model-View-Controller)设计模式,提供了一套简洁、强大的工具,使得开发者可以更高效地编写代码。Laravel-Admin 则是在此基础上构建的,它引入了 ...

    管理系统平台(node.js+MongoDB).zip

    1. **package.json**:定义项目依赖和配置信息,通过`npm install`命令安装所有依赖库。 2. **index.js**或**app.js**:入口文件,初始化服务器,设置路由,处理HTTP请求。 3. **models**目录:存放与数据库交互的...

    HC1309136 备份解决方案场景3(Oracle Rac备份).pptx

    3. **恢复数据库**:在不同模式下执行恢复操作,如NOARCHIVELOG模式下的恢复。 **RMAN恢复** - **还原与恢复的区别**:还原是指将备份文件恢复到特定位置,而恢复则是指通过应用归档日志和联机日志,确保数据库...

    MATLAB数据分析与挖掘实战案例 (12).zip

    1. **分类问题**:如使用SVM或神经网络对分类数据进行建模,可能涵盖手写数字识别、图像分类等场景。 2. **回归分析**:可能包括线性回归、多项式回归或非线性回归,用于预测连续变量。 3. **聚类分析**:K-means或...

Global site tag (gtag.js) - Google Analytics