您的位置:首页 > 其它

设计模式循序渐进(6)命令模式 command

2008-06-13 16:33 507 查看
模式解说:

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

Comnand模式的思想是把命令封装在一个类中,就是这里的ICommand接口,同时把接收对象也封装在一个类中就是这里的TReceiver类中,由调用这个命令的类祈求者TInvoker类来调用。

Comnand模式和面向过程的回调函数是一样的,注册回调函数和为具体的命令对象设置接受者对象相似,采用Command模式对命令的发出者和命令的执行者进行了解耦。

UML结构图

// Added by zhangsk 2008-6-13 14:47:40 command模式学习

unit uCommand;

interface

uses

SysUtils;

type

TReceiver = class(TObject) //接受者,相当于实现回调的具体功能;

public

procedure Action;

end;

ICommand = interface //命令接口

['{062332DB-F4A4-435B-98E3-3E05E7ADBDEF}']

procedure SetReceiver(const Value: TReceiver);

procedure Execute; //执行命令

end;

TInvoker = class(TObject) //祈求者,客户端直接调用祈求者

private

FCommand: ICommand; //维护一个具体命令

procedure SetCommand(const Value: ICommand);

public

property Command: ICommand read FCommand write SetCommand; //设置具体命令

procedure Invoker; //客户端操作祈求者的具体方法;

end;

TConcreteCommand = class(TInterfacedObject, ICommand) //具体命令

private

FReceiver: TReceiver;

public

procedure SetReceiver(const Value: TReceiver);

procedure Execute; //具体命令执行的实现

end;

implementation

procedure TInvoker.Invoker;

begin

if Supports(FCommand, ICommand) then

FCommand.Execute;

end;

procedure TInvoker.SetCommand(const Value: ICommand);

begin

FCommand := Value;

end;

procedure TConcreteCommand.Execute;

begin

if Assigned(FReceiver) then //相当实现了一个回调;TCommand.Execute回调TReceiver.Action

FReceiver.Action;

Writeln('Command By TConcreteCommand.Execute');

end;

procedure TReceiver.Action;

begin

Writeln('TReceiver.Action');

end;

procedure TConcreteCommand.SetReceiver(const Value: TReceiver);

begin

FReceiver := Value;

end;

end.

unit uClient;

interface

uses

uCommand;

type

TClient = class(TObject)

private

FReceiver: TReceiver;

FCommand: ICommand;

FInvoker: TInvoker;

public

constructor Create;

destructor Destroy; override;

procedure TestCommand;

end;

implementation

constructor TClient.Create;

begin

inherited Create;

FReceiver := TReceiver.Create;

FCommand := TConcreteCommand.Create;

FInvoker := TInvoker.Create;

FInvoker.Command := FCommand;

FCommand.SetReceiver(FReceiver);

end;

destructor TClient.Destroy;

begin

if Assigned(FReceiver) then //client创建了FReceiver,所以要client来释放

begin

FReceiver.Free;

FReceiver := nil;

end;

//FCommand是接口自己通过引用计数释放。

if Assigned(FInvoker) then

begin

FInvoker.Free;

FInvoker := nil;

end;

inherited Destroy;

end;

procedure TClient.TestCommand;

begin

FInvoker.Invoker;

end;

end.

program Project1;

uses

SysUtils,

uCommand in 'uCommand.pas',

uClient in 'uClient.pas';

var

client: TClient;

begin

client := TClient.Create;

client.TestCommand;

client.Free;

Readln;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: