• 命令模式的意图

  将一个请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化;

  对请求排队或记录请求日志,以及支持可撤销的操作;

  命令模式告诉我们可以为一个操作生成一个对象并给出它的一个执行方法。





  • 命令模式的构成

  1.客户角色:

  创建一个具体命令对象,并确定其接受者。



  2.命令角色:

  声明一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个接口或抽象类实现。



  3.具体命令角色:

  定义一个接收者和行为之间的弱耦合,实现execute方法,负责调用接收者的相应操作。



  4.请求者角色:

  负责调用命令对象执行请求。



  5.接收者角色:

  负责具体实施和执行一个请求。





关于命令者模式,我前面还有一篇博客。说的简单点命令者模式就是将请求对象和请求对象的实现解耦,2个都作为参数实现动态传参。在Java1.8中已经有了函数式接口,也就是专门针对Java不能将一段代码块作为参数传入一个方法做的补充。

OK,现在我们来写个例子吧。

package org.linkinpark.junit.testjunit;

/**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 命令者模式接口
*/
public interface Command
{ void execute(); }

package org.linkinpark.junit.testjunit;

/**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 接受者,也就是处理请求的那个对象
*/
public class Receiver
{ public void doSomething()
{
System.out.println("doSomething in receiver。。。");
} }
package org.linkinpark.junit.testjunit;

/**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 接受者和行为之间的弱耦合实现
*/
public class ConcreteCommand implements Command
{ private Receiver receiver; public ConcreteCommand(Receiver receiver)
{
super();
this.receiver = receiver;
} @Override
public void execute()
{
receiver.doSomething();
} }
package org.linkinpark.junit.testjunit;

/**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 请求执行器,创建一个请求接受者,然后触发命令者接口中对接受者行为的触发
*/
public class Invoker
{ private Command command; public Invoker(Command command)
{
super();
this.command = command;
} public void doAction()
{
command.execute();
} }
package org.linkinpark.junit.testjunit;

import org.junit.Test;

public class CommandTest
{ @Test
public void testCommand()
{
// 接收者
Receiver receiver = new Receiver(); // 命令:具体命令关联接收者
Command command = new ConcreteCommand(receiver); // 调用者
Invoker invoker = new Invoker(command); // 调用者调用命令,实际是所关联的接收者执行操作
invoker.doAction();
} }



OK,最后我们写了一个测试了,我们看下控制台,成功执行了我们想要的逻辑。

doSomething in receiver。。。

上面的这几段代码,轻松的实现了一个对象和该对象行为之间的松耦合。

1,假如我们现在想要改变该对象的行为,其他的代码根本不需要动。只需要修改command接口中对象的行为代码就OK。比如我们现在想在对象执行doSomething()方法前后执行特定的逻辑,直接这里修改就OK。比如我们现在对concreteCommand做如下修改:

package org.linkinpark.junit.testjunit;

/**
* @创建作者: LinkinPark
* @创建时间: 2016年2月5日
* @功能描述: 接受者和行为之间的弱耦合实现
*/
public class ConcreteCommand implements Command
{ private Receiver receiver; public ConcreteCommand(Receiver receiver)
{
super();
this.receiver = receiver;
} @Override
public void execute()
{
System.out.println("这里是对象执行doSomething()之前的行为。。。");
receiver.doSomething();
System.out.println("这里是对象执行doSomething()之后的行为。。。");
} }

控制台输出如下:

这里是对象执行doSomething()之前的行为。。。
doSomething in receiver。。。
这里是对象执行doSomething()之后的行为。。。

2,假如我们现在不想改变该对象的行为,而是想改变测试对象。那么我们只需要直接修改receiver对象就可以,比如我们继承或者重新组合一个对象。我们现在对Receiver对象派生一个子类:

package org.linkinpark.junit.testjunit;

public class SonReceiver extends Receiver
{ @Override
public void doSomething()
{
super.doSomething();
System.out.println("上面是父类的执行,这里开始走自己的逻辑。。。");
} }

控制台输出如下:

这里是对象执行doSomething()之前的行为。。。
doSomething in receiver。。。
上面是父类的执行,这里开始走自己的逻辑。。。
这里是对象执行doSomething()之后的行为。。。

在JUnit中的体现

  我们编写的TestCase就像是一个命令,通过调用器调用后,JUnit框架中有相应的接收者来执行我们的测试方法。TestCase是真正的测试执行者,每个测试用例都会生成一个TestCase对象,这就是典型的命令者模式。TestCase实现Test接口中定义的方法,测试开发人员只需要关注这些接口方法,而不必关心TestCase以及junit内部的实现细节,run()方法就是Command模式中Execute()方法。

public void run(TestResult result)
{
result.run(this);
}

使用命令(Command)模式后给系统的架构带来了哪些效果

  Command模式将实现请求的一方(TestCase)和调用一方(JUnit)进行解耦。

  Command模式使得新的TestCase很容易加入,无需改变已有的类,只需继承TestCase类即可,这样方便了测试人员。

  Command模式可以将多个TestCase进行组合成一个复合命令,TestSuite就是复合命令,它使用了Composite模式。

  Command模式容易把请求的TestCase组合成请求队列,这样使接收请求的一方(JUnit Framework)容易决定是否执行请求,一旦发现测试用例失败或者错误可以立刻停止,进行报告。





junit设计模式--命令者模式的更多相关文章

  1. [Head First设计模式]餐馆中的设计模式——命令模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  2. linkin大话设计模式--命令模式

    linkin大话设计模式--命令模式 首先考虑一种应用情况,某个方法需要完成某一个功能,这个功能的大部分功能已经确定了,但是有可能少量的步骤没法确定,必须等到执行这个方法才可以确定. 也就是说,我们写 ...

  3. 【设计模式】Java设计模式 - 命令模式

    Java设计模式 - 命令模式 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目录 Ja ...

  4. Java设计模式-享元模式(Flyweight)

    享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工厂需要检查 ...

  5. 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)

    命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...

  6. 设计模式之迭代器模式详解(foreach的精髓)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,很久没以LZ的身份和 ...

  7. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  8. 折腾Java设计模式之状态模式

    原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...

  9. iOS设计模式 - 命令

    iOS设计模式 - 命令 原理图 说明 命令对象封装了如何对目标执行指令的信息,因此客户端或调用者不必了解目标的任何细节,却仍可以对他执行任何已有的操作.通过把请求封装成对象,客户端可以把它参数化并置 ...

随机推荐

  1. 用mint ui去实现滚动选择日期并可以关闭拾取器

    转发要备注出处哈,么么哒 注释的那些部分都是我在尝试的时候写得,留给自己看得,删除不影响效果哈,希望对你们有帮助,比较忙可能写得很粗糙,不好意思,有空再改了 实例一:   <template&g ...

  2. js 移动端写搜索时怎么调用软键盘上面的搜索按钮

    这段时间一直在做移动端,所以遇到很多问题,现在很多网站在做移动端搜索的时候都不会在后面加一个搜索按钮,而是直接调用输入法上面的搜索搜索按钮进行搜索 input的一个新属性给我们提供非常方便的书写, 就 ...

  3. Babel 转码器 § es6转换es5

    Babel 转码器 § es6转换es5 实时转码 /  Repl  -babel-node / babel-register(自动转码引入babel-register模块) 配置文件.babelrc ...

  4. CTF---密码学入门第一题 这里没有key

    这里没有key分值:10 来源: 西普学院 难度:易 参与人数:5577人 Get Flag:1965人 答题人数:2074人 解题通过率:95% 你说没有就没有啊,俺为啥要听你的啊 解题链接: ht ...

  5. 江西理工大学南昌校区cool code竞赛

    这次比赛原本就是来打酱油的,想做个签到题就走!一开始不知道1002是签到题,一直死磕1001,WA了四发过了,回头一看Rank,三十名,我靠!看了1001的AC率,在我AC之前只有一个人AC了,当时我 ...

  6. 【Java学习笔记之四】java进制转化

    十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinar ...

  7. [51nod1614]刷题计划

    大赛将至,摆在你面前的是n道题目,第 i(1 ≤ i ≤ n) 道题目能提升 ai 点智力值,代码量为 bi KB,无聊值为 ci ,求至少提升m点智力值的情况下,所做题目代码量之和*无聊值之和最小为 ...

  8. dijk

    .....................用矩阵存..................... 1 int mp[N][N]; bool p[N]; int dist[N]; void dijk(int ...

  9. 搬寝室(经典dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1421 hdu_1421:搬寝室 Time Limit: 2000/1000 MS (Java/Othe ...

  10. Java大数应用

    1.大数加法 import java.math.BigInteger; import java.util.Scanner; public class Main { public static void ...