开篇,这里开了个blog 那么就要写点东西上去了,最进做了个东西需要一堆命令做脚本,但是实现不怎么满意,这里重新编写一下然后与大家分享,本来还有更多的废话的 :) 但是 优快云 的blog 貌似不怎么可靠,直接没掉了
5555555555555 好几百个字呢,培我字来!!!
好了,那些个也找不到心情写了,然后只好郁闷的直接上代码了,命令模式我也不多说了,大家就去看吧 。这里直接贴上代码了,首先是几个借口,然后是demo设计和实现过程,嘿嘿 看书的流程有点像调试,大家凑合着看。
有什么意见和建议欢迎直接提出。 第一次写那么长的东西 ,有点心虚的說 。
希望大家喜欢!
using System;
using System.Collections.Generic;
using System.Text;

namespace DS_CMD.Command

...{

/**//// <summary>
/// 命令接受者
/// *通常这里将是一个关于对象的描述
/// 比如一个电视机的描述
/// 接口只是告诉管理器这里是个有效的可以进行命令接受的对象
/// </summary>
interface IReceiver

...{

}
}

using System;
using System.Collections.Generic;
using System.Text;

namespace DS_CMD.Command

...{

/**//// <summary>
/// 命令对象接口
/// </summary>
interface ICmd

...{

/**//// <summary>
/// 执行命令
/// </summary>
void Execute();
}
}

using System;
using System.Collections.Generic;
using System.Text;

namespace DS_CMD.Command

...{

/**//// <summary>
/// 请求客户端
/// </summary>
interface ICilent

...{

/**//// <summary>
/// 请求一个命令外部
/// </summary>
/// <param name="cmd"></param>
void SendCmd(string cmd);


/**//// <summary>
/// 请求一个命令
/// </summary>
/// <param name="cmd"></param>
void SendCmd(ICmd cmd);
}
}

using System;
using System.Collections.Generic;
using System.Text;

namespace DS_CMD.Command

...{

/**//// <summary>
/// 代码注释类
/// </summary>
[AttributeUsage(AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public class CodeDescription : Attribute

...{
public CodeDescription()

...{
}

public CodeDescription(string description)

...{
this._Desc = description;
}

private string _Desc;


/**//// <summary>
/// 命令说明帮助
/// </summary>
public string Description

...{
get

...{
return this._Desc;
}
}
}


/**//// <summary>
/// 可执行命令属性类
/// </summary>
[AttributeUsage(AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public class CmdAttrib : CodeDescription

...{
public CmdAttrib()

...{
}


/**//// <summary>
/// Initializes a new instance of the <see cref="CmdAttrib"/> class.
/// </summary>
/// <param name="cmd">外部执行的命令.</param>
/// <param name="description">命令说明帮助.</param>
public CmdAttrib(string cmd, string description)
: base(description)

...{
this._Cmd = cmd;
}

object[] _Args;


/**//// <summary>
/// 也许需要一些参数 *保留
/// </summary>
public object[] Args

...{

get ...{ return _Args; }

set ...{ _Args = value; }
}

string _Cmd;


/**//// <summary>
/// 外部执行的命令
/// 如果为空则使用方法名称
/// </summary>
public string Cmd

...{
get

...{
return _Cmd;
}
}

}
}


license#region license
// **************************************************
// Copyright (c) 2008 fengjian (icesun963@Gmail.com)
// All rights reserved.
// 无聊加个版权玩
// **************************************************
#endregion

using System;
using System.Collections.Generic;
using System.Text;

namespace DS_CMD.Command.Demo

...{

/**//// <summary>
/// 邮件群发器中的主要对象
/// 这里用我自己的项目作为说明
/// 并且根据个人的需要进行设计的
/// 忽然觉得也许中文编程写起来会更清晰一些 所有我来尝试一下
/// 看清楚哦 不是伪代码
/// (带字母是为了更好的定位)
/// </summary>
class M邮件群发 : IReceiver

...{
string _S发件数量;

public string S发件数量

...{

get ...{ return _S发件数量; }

set ...{ _S发件数量 = value; }
}

bool _已经启动;

public bool 已经启动

...{

get ...{ return _已经启动; }

set ...{ _已经启动 = value; }
}
//请跳往命令对象->

}

//->编写客户端
//刚才构造了关于命令对象和接收对象,并且提供了两种方式进行调用
//下面该构造一个发送者了
//刚发现如果是字母开头无法很好的进行联想
//如果是下划线就开始变得好多了
//如果格式有点问题 请见谅
class _控制器:ICilent

...{
//->控制器
M邮件群发 _控制对象;

public _控制器(M邮件群发 控制对象)

...{
_控制对象 = 控制对象;
}


ICilent 成员#region ICilent 成员


/**//// <summary>
/// 这个先不管
/// </summary>
/// <param name="cmd"></param>
void ICilent.SendCmd(string cmd)

...{
throw new Exception("The method or operation is not implemented.");
}


/**//// <summary>
/// 这里我们需要进行对命令进行发送了
/// 为什么还需要一个发送者
/// 这里只是一种简单的方式
/// 你完全可以直接在Main里面进行发送命令
/// 比如我们看一个刚完成的过程
/// 来编写一小段关于执行的过程
/// 跳往Main一号->
///
/// ->SendCmd
/// 我们看到了 刚才我们尝试使用了这么一个过程来执行过程
/// 构造接收对象
/// 命令构造
/// 运行
/// 很显然我希望一种更简单的方式
/// 我只要发送一个命令就可以了
/// 看代码
/// </summary>
/// <param name="cmd"></param>
public void SendCmd(ICmd cmd)

...{
//这里我需要做的就是告诉我要把什么命令发送给谁
cmd.Execute();
//没什么区别啊 也没看出和原来的有什么区别
//稍等 还有过程
//继续
}

public void 启动()

...{
SendCmd(new DS_CMD.Command.Demo.Cmd.M启动命令(_控制对象 ));
}


public void 停止 ()

...{
SendCmd(new DS_CMD.Command.Demo.Cmd.M停止命令(_控制对象));
}

//好了
//继续跳往Main二号->
#endregion
}

//->万能控制器
class _万能控制器 : ICilent

...{
//->控制器
protected IReceiver _控制对象;

public _万能控制器(IReceiver 控制对象)

...{
_控制对象 = 控制对象;
}


ICilent 成员#region ICilent 成员


/**//// <summary>
/// 这个先不管
/// </summary>
/// <param name="cmd"></param>
void ICilent.SendCmd(string cmd)

...{
throw new Exception("The method or operation is not implemented.");
}


/**//// <summary>
/// 和原来一样
/// </summary>
/// <param name="cmd"></param>
public void SendCmd(ICmd cmd)

...{
cmd.Execute();
}

//好了
#endregion
}
//万能控制器就那么简单? 恩....没错...
//然后是需要一个带命令列表的控制器

class _邮件群发控制器 : _万能控制器

...{

public _邮件群发控制器(IReceiver 控制对象)
:base(控制对象)

...{

}

public void 启动()

...{

SendCmd(new DS_CMD.Command.Demo.Cmd._命令纸条(new CmdObj("启动", _控制对象)));
}


public void 停止()

...{
SendCmd(new DS_CMD.Command.Demo.Cmd._命令纸条(new CmdObj("停止", _控制对象)));
}

//看起来是完成了
//测试一下
//跳往Main三号->
}

//制造一个命令对象
class CmdObj : DS_CMD.Command.Demo.Cmd._命令纸条.ICmdObj

...{


/**//// <summary>
/// 简单的模拟下就好了
/// </summary>
/// <param name="name"></param>
/// <param name="receiver"></param>
public CmdObj(string name, IReceiver receiver)

...{
_Name = name;
_Receiver = receiver;
}


ICmdObj 成员#region ICmdObj 成员

string _Name;
public string Name

...{

get ...{ return _Name; }
}
IReceiver _Receiver;
public IReceiver Receiver

...{

get ...{ return _Receiver; }
}
string _ExecuteObject;

public string ExecuteObject

...{

get ...{return _ExecuteObject; }
}
DS_CMD.Command.Demo.Cmd._命令纸条.CmdType _CmdType;
public DS_CMD.Command.Demo.Cmd._命令纸条.CmdType CmdType

...{

get ...{ return _CmdType; }
}
object[] _Args;
public object[] Args

...{

get ...{ return _Args; }
}

#endregion
}

class _入口

...{
//->Main一号
//很欣慰的看到你来到这里 嘿嘿 有点废话了
//来看函数
public static void _Main一号()

...{
//首先我们需要一个接受者
M邮件群发 m邮件群发 = new M邮件群发();
//我们发送一个启动命令
ICmd cmd = new DS_CMD.Command.Demo.Cmd.M启动命令(m邮件群发);//这里有个工厂的话会好很多的 觉得呢?
cmd.Execute();
//检查状态
Console.WriteLine("检查状态 >> {0}", m邮件群发.已经启动);
//然后发送一个关闭命令
cmd = new DS_CMD.Command.Demo.Cmd.M停止命令(m邮件群发);
cmd.Execute();
Console.WriteLine("检查状态 >> {0}", m邮件群发.已经启动);

Console.ReadKey();

//运行下 恩 很完美吧 已经成功完成了
//但是这不是我想要的继续返回
//你不觉得有点长么?
//经常看到某些人说 OOP 的编写者被一堆Class掩埋 我这么记得 都是原话也许并不是这样
//但是有一件事情是真实的 我知道如果 这个东西要执行50条的命令的话 无论如何 都必须有 50个类
//我不得不重复 拷贝 修改 这样的一个过程
//如果你觉得 无所谓直接
//跳往SendCmd->

//如果你觉得 我也这么想 我们继续来完善和处理下这样的一个问题
//程序员总是懒惰的 希望设计一个简单的方法来完成所有的命令 我也一样 不然我不会在那个软件中使用那样的一种方式了 .
//但是事情并不是万能的 ,总是有很多问题,记得刚看到的一句话 脚本才是王道,确实如此,我们要设计一个脚本么 ?
//那可是一个庞大的工作 ,我可不想被他累死 .
//那么如何解决呢 ?
//回过去看下命令执行方式
//接受者 -> 重新包装一个命令 -> 执行命令
//接受貌似 没办法了 执行 就那么一条还想改变什么么 ?恩 包装 ...
//有没有更好的包装方式 ?
//首先 设想一下 ,如果我们构造一个 命令控制器的话 把所有的命令包装起来 然后执行 ?
//尝试一下再说
//跳往控制器->

}

//->Main二号
public static void _Main二号()

...{
//这里实现起来就简单一些了
//首先我们同样需要一个接受者
M邮件群发 m邮件群发 = new M邮件群发();
//但是我们使用一个控制器
_控制器 c = new _控制器(m邮件群发);
c.启动();
Console.WriteLine("检查状态 >> {0}", m邮件群发.已经启动);
c.停止();
Console.WriteLine("检查状态 >> {0}", m邮件群发.已经启动);
Console.ReadKey();
//跑一下
//跑的還不错 至少我们不需要再去记一堆的命令在哪里了
//而且知道了哪些是可执行的
//但是这个例子有个致命的缺陷就是 你无法更好的使用一些东西
//也就是說 比如我要控制另外的不是群发器 我需要控制 一个浏览器的话 这样就毫无意义 我们不得不重新编写这里的所有代码
//现在有2个问题摆在面前 1.如何更简洁的 对命令进行控制 2.如何增加代码的灵活性更通用
//分析下几个对象
//首先是控制器,如果我们做好一系列的命令 放置到面板中 你可以简单的调用,然后提供一个通用的入口 用于定制你的命令的话.
//但是如何实现呢 ? 分析过程 :
//*命令列表->保持更安全的执行 如果没有这个我们很可能在程序中敲错代码 导致一堆问题 这个 ,我们必须制作
//接受者
//*控制的对象 也是必须的 但是这个没有统一的访问方式和办法. 啊哈 ,嗯 既然不统一 我们就让他通过配置来解决吧,我想这个不是什么难事 .
//命令对象,真的需要那么多的类么 ?我可没有耐心不断的编写真的,我发誓 .
//但是他是怎么工作的呢 ?
//见过几个方式 修改一些属性 调用几个方法 好像还有见过调用事件的.
//能优化么 ? 反射如何 ?
//修改 ?没问题 ,方法? 同样不是难事 ,事件 一样处理了.
//效果会如何呢? 大家都知道 反射的性能实在不怎么样.到底如何写出来看看好了
//跳往 纸条 ->

}

//->Main三号
public static void _Main三号()

...{
//这里实现起来就简单一些了
//首先我们同样需要一个接受者
M邮件群发 m邮件群发 = new M邮件群发();
//但是我们使用一个控制器
_邮件群发控制器 c = new _邮件群发控制器(m邮件群发);
c.启动();
Console.WriteLine("检查状态 >> {0}", m邮件群发.已经启动);
c.停止();
Console.WriteLine("检查状态 >> {0}", m邮件群发.已经启动);
Console.ReadKey();
//忽~~ 总算告一段落了
//如果有人发现还有一些地方没有实现 比如 CMDManager
//本来这是准备先设计后写Demo的,结果不知不觉.
//坏毛病不少啊
//大家凑和的看吧
//欢迎有什么问题指出和给我留言.
//这里只是自己个人的一些看法和思考方式
}

}
}

/**////->命另对象:
///下面是命令对象名字空间
/// 我通常会希望有这样的一种简单的方式对命令进行调用
/// 我得到一个有效的命令列表 或者是一堆有效的命令对象 从程序或者是控制台进行调用
namespace DS_CMD.Command.Demo.Cmd

...{

/**//// <summary>
/// 通常是这么一个情况
/// 接受者是不可能拥有相同的属性的
/// 因此无法进行抽象
/// 而我们调用必须拥有一系列的对象
/// 所以这里对对象进行了继承以获取对象的访问权限
/// 但是并不进行除了命令对象外的任何操作,以保持对象的安全
/// 但是有致命的缺点 就是无法传递接口 只能传递对象
/// 当然我们也可以使用反射的方式
///
/// </summary>
class M启动命令 :M邮件群发, ICmd

...{


/**//// <summary>
/// Initializes a new instance of the <see cref="M启动命令"/> class.
/// </summary>
/// <param name="_接受者">The _接受者.</param>
public M启动命令(M邮件群发 _接受者)

...{
_R接受者 = _接受者;
}


[CmdAttrib("启动", "启动发邮件")]
private void S启动()

...{
_R接受者.已经启动 = true;
Console.WriteLine("对象已经启动...");
}

M邮件群发 _R接受者;



/**//// <summary>
/// 运行命令
/// </summary>
public void Execute()

...{
S启动();
}
}

//这里完成了一个简单的命令对象 就如上面所说的 我们应该可以使用另外一种方式进行对象的访问
//如果但是为了访问对象我们不得不开放访问接口,这个方式和上面的相比,访问更安全,但是必须对原有的访问权限进行修改
class M停止命令 : ICmd

...{


/**//// <summary>
/// Initializes a new instance of the <see cref="M启动命令"/> class.
/// </summary>
/// <param name="_接受者">The _接受者.</param>
public M停止命令(IReceiver _接受者)

...{
_R接受者 = _接受者;
}


[CmdAttrib("停止", "停止发邮件...")]
public void S停止()

...{
//这里将使用反射进行通用属性和方法的调用
//需要做的就是在接受者那里进行对象提取和调用
//比如我们使用另外一个属性的方式进行限制
//然后调用过程方法 这里就不进行编写了
//这里仅仅强制转换并且进行简单的操作。
if (_R接受者 is M邮件群发)

...{
(_R接受者 as M邮件群发).已经启动 = false;
}
Console.WriteLine("对象已停止...");
}

IReceiver _R接受者;



/**//// <summary>
/// 运行命令
/// </summary>
public void Execute()

...{
S停止();
}
}
//请重新返回上面继续
//跳往编写客户端->

//->纸条
//通常对于命令来说就是一个有意义的符号,并且需要一个可传递的过程
//所以我想到了纸条
//只要把要说的写进去,一切都不是问题
class _命令纸条 : ICmd

...{

ICmdObj _纸条;

/**//// <summary>
/// 开始构造
/// 很显然需要一个对命令进行描述的对象
/// 当然不能用 object 了 来构造一个
/// </summary>
/// <param name="?">命令描述</param>
public _命令纸条( ICmdObj 命令描述)

...{
_纸条 = 命令描述;
}




/**//// <summary>
/// 命令类型
/// </summary>
internal enum CmdType

...{
属性,
方法,
事件
}


/**//// <summary>
/// 纸条接口
/// </summary>
internal interface ICmdObj

...{

/**//// <summary>
/// 名称
/// </summary>

string Name ...{ get;}


/**//// <summary>
/// 接受对象
/// </summary>

IReceiver Receiver...{get;}


/**//// <summary>
/// 英文不好
/// 叫他运行对对象把
/// </summary>

string ExecuteObject ...{ get; }


/**//// <summary>
/// 命令类型
/// </summary>

CmdType CmdType ...{ get;}


/**//// <summary>
/// 参数
/// </summary>

object[] Args ...{ get;}
}






/**//// <summary>
/// 运行命令
/// </summary>
public void Execute()

...{
Console.WriteLine("执行纸条..." + _纸条.Name);
//通过反射进行对属性之类的操作
//这里同样不编写了 直接强制转换进行模拟下
switch (_纸条.Name)

...{
case "启动":
if (_纸条.Receiver is M邮件群发)

...{
(_纸条.Receiver as M邮件群发).已经启动 = true;
}
break;
case "停止":
if (_纸条.Receiver is M邮件群发)

...{
(_纸条.Receiver as M邮件群发).已经启动 = false;
}
break;
}
}
//挖喔 .看起来完成了
//继续构造一个万能控制器
//跳往->万能控制器
}

}

Command模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。