`
futeng
  • 浏览: 264163 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

命令模式(Command pattern)-- 请求与实现的解耦

阅读更多
PART 1 请求与实现

        什么叫请求:用户选中一行文字,点击复制按钮,意图将文字复制到剪贴板,这个意图就叫做请求,但具体到程序中,这个请求被具象化为一个复制按钮被点击。
        什么叫实现:复制按钮被点击之后,引发一个操作,可能就是调用了一个方法,该方法主要实现将当前选中的内容复制到剪贴板,这个具体的操作就是实现。

        例如:有个记事本(notepad),记事本上面有个复制按钮(copyButton)。那么一次复制操作,就可以被分解为两步,首选是用户选中一行文字并单击复制按钮(此时触发用户想进行复制操作的请求),第二是复制操作被具体执行(也就是操作被实现了)。

        文字往往描述的不如具体实践来的直白,大家想象一下选中本行文字,点击假设右边存在的“复制”按钮,此刻是不是能想象到该行已经被缓存了,可以做后面注入粘贴等等的操作了。

        请求和实现,都非常直观,很容易理解。


PART 2 请求与实现的耦合

        我们实现一个Notepad对象,顺便写了个复制和粘贴的方法。这是常见的实现方式。main函数充当一个用户去调用相应的方法,即做相应的请求。此时操作的被请求和操作的实现都是在Notepad里面耦合了。
       
/**        
 * Copyright (c) 2013 by www.futeng.org    
 * @{#} @Notepad.java Create on @2013-6-9 @上午11:39:18 
 */    
package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class NotepadTest {
	
	public void copy() {
		System.out.println("复制当前选中文字到剪贴板...");
	}
	
	public void paste() {
		System.out.println("获取剪贴板数据复制到当前光标后面...");
	}
}

/**        
 * Copyright (c) 2013 by www.futeng.org      
 * @{#} @UserTest.java Create on @2013-6-9 @上午11:41:11 
 */    
package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class UserTest {
	
	public static void main(String[] args) {
		
		NotepadTest notepadTest = new NotepadTest();
		
		System.out.println("用户选中一行文字,点击复制按钮...");
		notepadTest.copy();
		System.out.println("用户将鼠标点在下一行,准备粘贴...");
		notepadTest.paste();
	}
}

引用
用户选中一行文字,点击复制按钮...
复制当前选中文字到剪贴板...
用户将鼠标点在下一行,准备粘贴...
获取剪贴板数据复制到当前光标后面...


        到目前为止一切都没有问题,我们可以把复制和粘贴看成是notepad所拥有的行为。但是问题会出现在真实实现的时候,这个方法体内可就不是以行输出了,往往是拥有大量的属性甚至是状态的。一个方法是这样,一个notepad少说支持这样的操作有十几个,想想就要死人了。
        怎么去解决,这里面一个关键性的key,价值连城的思维转变就是,把复制或者粘贴这个操作也当成是一个对象。那么notepad接受到复制或者粘贴的请求的时候,直接交给相应的对象去处理。那么代码的健壮性简洁性就提高了很多。
        不要以为能把复制粘贴想象出作为具体对象处理不是多么了不起的事情,看看自己的代码,很肯能动辄就包含了几十个方法,很多并不是这个类在逻辑上应该能具备的功能。能细化和抽离出也是很需要业务与技术功力的。
        下面看请求与实现是怎么分离的。


PART 3 请求与实现的分离

package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public interface Command {
	public void execute();
}

package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class CopyButtonCommand implements Command{
	@Override
	public void execute() {
		System.out.println("复制当前选中文字到剪贴板...");
	}

}

package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class PasteButtonCommand implements Command {

	@Override
	public void execute() {
		System.out.println("获取剪贴板数据复制到当前光标后面...");
	}

}

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class Notepad {
	
	private Command copy;
	private Command paste;
	
	public Notepad() {
		this.copy = new CopyButtonCommand();
		this.paste = new PasteButtonCommand();
	}
	
	public void copy() {
		this.copy.execute();
	}
	
	public void paste() {
		this.paste.execute();
	}
}

package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class User {
	public static void main(String[] args) {
		Notepad notepad = new Notepad();
		
		System.out.println("用户选中一行文字,点击复制按钮...");
		notepad.copy();
		System.out.println("用户将鼠标点在下一行,准备粘贴...");
		notepad.paste();
	}
}

        这次转变的核心思想,就是把一个方法生生抽象成一个对象了。
        后面介绍一个将方法抽象对象的几个有趣应用。

PART 4 批处理实现

        这里的批处理,理解为多个命令依次执行。可以想象一下很多绘图工具的滤镜怎么实现的。其实就是一层一层的命令加上去。例如先磨皮再调大眼睛再上色等等。这里实现一个“一键复制粘贴的功能”,其实就是将当前行复制到下一行。

package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class Notepad {
	
	private Command copy;
	private Command paste;
	private Command[] batch = new Command[2];
	
	
	public Notepad() {
		this.copy = new CopyButtonCommand();
		this.paste = new PasteButtonCommand();
		this.batch[0] = this.copy;
		this.batch[1] = this.paste;
	}
	
	public void copy() {
		this.copy.execute();
	}
	
	public void paste() {
		this.paste.execute();
	}
	
	public void copyAndPaste() {
		for (Command command : this.batch) {
			command.execute();
		}
	}
}

package org.futeng.pattern.command;

/**      
 * @author <a href="mailto:ifuteng@gmail.com">futeng</a> 
 */
public class User {
	public static void main(String[] args) {
		Notepad notepad = new Notepad();
		
		System.out.println("用户选中一行文字,直接点击一键复制粘贴按钮");
		notepad.copyAndPaste();
	}
}

引用
用户选中一行文字,直接点击一键复制粘贴按钮
复制当前选中文字到剪贴板...
获取剪贴板数据复制到当前光标后面...
分享到:
评论

相关推荐

    命令模式command pattern

    在Java中实现命令模式,我们可以利用面向对象编程的特性来构建系统,使得请求发送者与请求接收者之间解耦,提高代码的灵活性和可维护性。 首先,我们需要理解命令模式中的四个关键角色: 1. **Command(命令接口)*...

    设计模式之命令模式(Command Pattern)

    命令模式是一种行为设计模式,它将请求封装成独立的对象,使得可以使用不同的请求、队列请求、记录请求历史以及支持可撤销的操作。这种模式在软件工程中被广泛应用,尤其是在需要解耦请求发起者和接收者时,提高了...

    命令模式 Command Pattern

    ### 命令模式(Command Pattern) #### 概述 命令模式是一种行为设计模式,它将请求封装成对象,以便使用不同的请求对客户端进行参数化。该模式有助于将发送请求的对象与执行请求的对象解耦。 #### 核心概念 在...

    c++-设计模式之命令模式(Command Pattern)

    命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为对象,从而使您可以使用不同的请求、队列请求或日志请求,并支持可撤销操作。命令模式通常用于实现操作的解耦,使得发送者和接收者之间不直接关联...

    design-pattern-java.pdf

    命令模式-Command Pattern 请求发送者与接收者解耦——命令模式(一) 请求发送者与接收者解耦——命令模式(二) 请求发送者与接收者解耦——命令模式(三) 请求发送者与接收者解耦——命令模式(四) 请求发送者...

    Head First 设计模式 (六) 命令模式(Command pattern) C++实现

    在实际项目中,命令模式常用于事件驱动编程、GUI系统、事务处理以及任何需要将请求与处理解耦的场景。例如,在图形用户界面中,每个按钮点击都可以看作是一个命令,当用户点击按钮时,对应的命令被触发执行相应的...

    command 模式的c++实现

    **命令模式(Command Pattern)详解** 命令模式是一种行为设计模式,它将请求封装为一个对象,使得你可以使用不同的请求、队列或者日志请求,也可以支持可撤销的操作。在C++中实现命令模式,可以有效地解耦调用者和...

    Command-Pattern--Color-Changing

    命令模式是一种行为设计模式,它将请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。在C#编程中,这种模式常用于解耦调用者和接收者,提高代码的灵活...

    CommandPattern)管理智能家电最终代码共4页

    **命令模式(Command Pattern)详解** 命令模式是一种行为设计模式,它将请求封装为一个对象,使得你可以使用不同的请求、队列或者日志请求,也可以支持可撤销的操作。在这个场景中,我们关注的是如何利用命令模式...

    命令模式最简单实现

    在`CommandPattern.zip`文件中,可能包含了这个模式的示例代码,你可以进一步查看和学习这些代码,以便更好地理解和应用命令模式。记住,虽然这是一个简单的实现,但命令模式的威力在于其能够适应复杂的需求,例如在...

    [行为型模式]命令模式的理解

    总之,命令模式提供了一种将请求与执行请求的对象解耦的方式,提高了系统的可扩展性和可维护性。在需要支持撤销操作或者需要动态调度命令执行的场景中,命令模式是一个非常实用的设计模式。在实际的编程工作中,特别...

    C#命令模式模型

    在提供的文件列表中,`Program.cs`通常是主程序入口,`TestPatternCommand.csproj`是项目文件,`CommandPattern`可能是包含命令模式相关类的文件夹,`Properties`包含了项目的配置信息,而`TestPatternCommand.sln`...

    06-命令模式.pdf

    ### 命令模式(Command Pattern)详解 #### 一、命令模式定义与应用场景 命令模式是一种行为设计模式,它把请求封装为一个对象,从而使您可以用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可...

    设计模式-COMMAND

    **命令模式(Command Pattern)** 是一种行为设计模式,它将请求封装成对象,从而使你能够用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 在软件开发中,特别是面向对象编程语言...

    C#命令模式(Command Pattern)实例教程

    命令模式是一种设计模式,它将请求封装为一个对象,使得我们可以使用不同的请求、队列请求、或者记录请求日志,也可以支持可撤销的操作。在C#中,命令模式的应用可以帮助我们更好地解耦系统中的调用者和接收者,提高...

    C#命令模式应用

    在C#编程中,命令模式常用于实现解耦,使得调用者与执行者之间不再有直接的依赖关系,提高了代码的灵活性和可维护性。 首先,我们要理解命令模式的基本结构。在C#中,一个命令模式通常包含以下几个角色: 1. **...

    .NET设计模式(17):命令模式(CommandPattern)

    在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合[李建忠]。这就是本文要说的Command模式。将一个请求封装为一个对象,从而使你可用不同的请求对客户进行...

    命令模式demo

    在本示例"命令模式demo"中,我们将深入理解这一模式的实现与应用。 首先,命令模式的核心组成部分包括:**命令接口(Command Interface)**、**具体命令类(Concrete Command)**、**接收者(Receiver)**和**调用...

    设计模式系列之命令模式

    在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的...这就是命令模式(Command Pattern)。

    C#设计模式视频11-15

    5. **命令模式(Command Pattern)**: 命令模式将请求封装成对象,使得可以使用不同的请求、队列请求、或者支持撤销操作。在C#中,命令模式通常通过定义接口或抽象类来实现,具体实现类包含了对请求的处理逻辑。它...

Global site tag (gtag.js) - Google Analytics