设计模式学习实例——Command模式(繁荣的股市) ( 积分: 100 )

G

gmsft

Unregistered / Unconfirmed
GUEST, unregistred user!
设计模式学习实例——Command模式(繁荣的股市)
上次提交的Decorator模式(孙悟空的七十二变) ( 积分:100, 回复:76, 阅读:782 )
得到了富翁们的关注,非常荣幸。
这次又改写的阎宏《Java与模式》中的一个例子,请富翁们批评。
另:
1)我用 MM 做的类图为什么没有字段,方法等项?
2)界面单元的两个按钮单击方法中,只有一句不同:
Command := TBuyCommand.Create(......);
Command := TSellCommand.Create(......);
请问,如何改写可以实现代码复用?
代码附后:
http://bbs.2ccc.com/topic.asp?topicid=173573
{
*************************************************
设计模式学习实例——Command模式
版权所有(C) 2005
*************************************************
}
unit ugmStock;
{
*************************************************
项目:繁荣的股市
单元:业务逻辑
功能:提供相关业务逻辑
作者:
创建:2005-06-07
修改:2005-06-08
版本:Ver0.1.0
历史:时间 版本 说明
2005-06-08 Ver0.1.0 第一个版本
*************************************************
}
interface
uses
classes;
type
{
***********************************************
股票市场类(TStockMarket)
扮演接收者(Receiver)角色
***********************************************
}
TStockMarket = class
private
FStockList: TStrings;
//上市股票
public
constructor Create;
destructor Destroy;
override;
function SearchStock(StockCode: string): boolean;
function BuyStock(StockCode: string;
StockQuantity: integer): boolean;
function SellStock(StockCode: string;
StockQuantity: integer): boolean;
end;

{
***********************************************
命令类(TCommand)
扮演抽象命令(Abstract Command)角色
***********************************************
}
TCommand = class
protected
FStockMarket: TStockMarket;
FStockCode: string;
FStockQuantity: integer;
public
constructor Create(Market: TStockMarket;
Code: string;
Quantity: integer);
function Execute: boolean;
virtual;
abstract;
end;

{
***********************************************
买入命令类(TBuyCommand)
扮演具体命令(Concrete Command)角色
***********************************************
}
TBuyCommand = class(TCommand)
public
function Execute: boolean;
override;
end;

{
***********************************************
卖出命令类(TSellCommand)
扮演具体命令(Concrete Command)角色
***********************************************
}
TSellCommand = class(TCommand)
public
function Execute: boolean;
override;
end;

{
***********************************************
股票经纪人类(TBroker)
扮演请求者(Inkover)角色
***********************************************
}
TBroker = class
private
FCommand: TCommand;
public
constructor Create(Command: TCommand);
function Action: boolean;
end;

implementation
uses
Dialogs, SysUtils;
{
*************************************************TStockMarket
}
constructor TStockMarket.Create;
var
i: integer;
begin
inherited;
FStockList := TStringList.Create;
for i := 0 to 9do
begin
FStockList.Add(IntToStr(i));
end;
end;

destructor TStockMarket.Destroy;
var
i: integer;
begin
for i := 0 to 9do
begin
FStockList.Objects.Free;
end;
FStockList.Free;
inherited;
end;

function TStockMarket.SearchStock(StockCode: string): boolean;
var
i: integer;
begin
result := false;
for i := 0 to 9do
begin
if FStockList.Strings = StockCode then
begin
result := true;
exit;
end;
end;
end;

function TStockMarket.BuyStock(StockCode: string;
StockQuantity: integer): boolean;
begin
result := false;
if SearchStock(StockCode) then
begin
ShowMessage('买入股票:'+StockCode+chr(13)+IntToStr(StockQuantity)+' 股');
result := true;
end
else
ShowMessage('错误的股票代码!');
end;

function TStockMarket.SellStock(StockCode: string;
StockQuantity: integer): boolean;
begin
result := false;
if SearchStock(StockCode) then
begin
ShowMessage('卖出股票:'+StockCode+chr(13)+IntToStr(StockQuantity)+' 股');
result := true;
end
else
ShowMessage('错误的股票代码!');
end;

{
*************************************************TCommand
}
constructor TCommand.Create(Market: TStockMarket;
Code: String;
Quantity: integer);
begin
FStockMarket := Market;
FStockCode := Code;
FStockQuantity := quantity;
end;

{
*************************************************TBuyCommand
}
function TBuyCommand.Execute: boolean;
begin
result := FStockMarket.BuyStock(FStockCode, FStockQuantity);
end;

{
*************************************************TSellCommand
}
function TSellCommand.Execute: boolean;
begin
result := FStockMarket.SellStock(FStockCode, FStockQuantity)
end;

{
*************************************************TBroker
}
constructor TBroker.Create(Command: TCommand);
begin
FCommand := Command;
end;

function TBroker.Action: boolean;
begin
result := FCommand.Execute;
end;

end.


{
*************************************************
设计模式学习实例——Command模式
版权所有(C) 2005
*************************************************
}
unit fmMain;
{
*************************************************
项目:繁荣的股市
单元:用户界面
功能:提供用户界面
作者:
创建:2005-06-07
修改:2005-06-08
版本:Ver0.1.0
历史:时间 版本 说明
2005-06-08 Ver0.1.0 第一个版本
*************************************************
}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ActnList, jpeg;
type
TForm1 = class(TForm)
Panel1: TPanel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
uses ugmStock;
{$R *.dfm}
var
StockMarket: TStockMarket;
StockCode: string;
StockQuantity: integer;
Broker: TBroker;
Command: TCommand;

procedure TForm1.FormCreate(Sender: TObject);
begin
StockMarket := TStockMarket.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
try
StockCode := Edit1.Text;
StockQuantity := StrToInt(Edit2.Text);
except
ShowMessage('交易指令错误!'+chr(13)+chr(13)+ '请检查股票代码和数量。');
end;
Command := TBuyCommand.Create(StockMarket, StockCode, StockQuantity);
Broker := TBroker.Create(Command);
if Broker.Action then
ShowMessage('交易成功!')
else
ShowMessage('交易失败!');
Broker.Free;
Command.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
try
StockCode := Edit1.Text;
StockQuantity := StrToInt(Edit2.Text);
except
ShowMessage('交易指令错误!'+chr(13)+chr(13)+ '请检查股票代码和数量。');
end;
Command := TSellCommand.Create(StockMarket, StockCode, StockQuantity);
Broker := TBroker.Create(Command);
if Broker.Action then
ShowMessage('交易成功!')
else
ShowMessage('交易失败!');
Broker.Free;
Command.Free;
end;

end.

end.
 
设计模式学习实例——Command模式(繁荣的股市)
上次提交的Decorator模式(孙悟空的七十二变) ( 积分:100, 回复:76, 阅读:782 )
得到了富翁们的关注,非常荣幸。
这次又改写的阎宏《Java与模式》中的一个例子,请富翁们批评。
另:
1)我用 MM 做的类图为什么没有字段,方法等项?
2)界面单元的两个按钮单击方法中,只有一句不同:
Command := TBuyCommand.Create(......);
Command := TSellCommand.Create(......);
请问,如何改写可以实现代码复用?
代码附后:
http://bbs.2ccc.com/topic.asp?topicid=173573
{
*************************************************
设计模式学习实例——Command模式
版权所有(C) 2005
*************************************************
}
unit ugmStock;
{
*************************************************
项目:繁荣的股市
单元:业务逻辑
功能:提供相关业务逻辑
作者:
创建:2005-06-07
修改:2005-06-08
版本:Ver0.1.0
历史:时间 版本 说明
2005-06-08 Ver0.1.0 第一个版本
*************************************************
}
interface
uses
classes;
type
{
***********************************************
股票市场类(TStockMarket)
扮演接收者(Receiver)角色
***********************************************
}
TStockMarket = class
private
FStockList: TStrings;
//上市股票
public
constructor Create;
destructor Destroy;
override;
function SearchStock(StockCode: string): boolean;
function BuyStock(StockCode: string;
StockQuantity: integer): boolean;
function SellStock(StockCode: string;
StockQuantity: integer): boolean;
end;

{
***********************************************
命令类(TCommand)
扮演抽象命令(Abstract Command)角色
***********************************************
}
TCommand = class
protected
FStockMarket: TStockMarket;
FStockCode: string;
FStockQuantity: integer;
public
constructor Create(Market: TStockMarket;
Code: string;
Quantity: integer);
function Execute: boolean;
virtual;
abstract;
end;

{
***********************************************
买入命令类(TBuyCommand)
扮演具体命令(Concrete Command)角色
***********************************************
}
TBuyCommand = class(TCommand)
public
function Execute: boolean;
override;
end;

{
***********************************************
卖出命令类(TSellCommand)
扮演具体命令(Concrete Command)角色
***********************************************
}
TSellCommand = class(TCommand)
public
function Execute: boolean;
override;
end;

{
***********************************************
股票经纪人类(TBroker)
扮演请求者(Inkover)角色
***********************************************
}
TBroker = class
private
FCommand: TCommand;
public
constructor Create(Command: TCommand);
function Action: boolean;
end;

implementation
uses
Dialogs, SysUtils;
{
*************************************************TStockMarket
}
constructor TStockMarket.Create;
var
i: integer;
begin
inherited;
FStockList := TStringList.Create;
for i := 0 to 9do
begin
FStockList.Add(IntToStr(i));
end;
end;

destructor TStockMarket.Destroy;
var
i: integer;
begin
for i := 0 to 9do
begin
FStockList.Objects.Free;
end;
FStockList.Free;
inherited;
end;

function TStockMarket.SearchStock(StockCode: string): boolean;
var
i: integer;
begin
result := false;
for i := 0 to 9do
begin
if FStockList.Strings = StockCode then
begin
result := true;
exit;
end;
end;
end;

function TStockMarket.BuyStock(StockCode: string;
StockQuantity: integer): boolean;
begin
result := false;
if SearchStock(StockCode) then
begin
ShowMessage('买入股票:'+StockCode+chr(13)+IntToStr(StockQuantity)+' 股');
result := true;
end
else
ShowMessage('错误的股票代码!');
end;

function TStockMarket.SellStock(StockCode: string;
StockQuantity: integer): boolean;
begin
result := false;
if SearchStock(StockCode) then
begin
ShowMessage('卖出股票:'+StockCode+chr(13)+IntToStr(StockQuantity)+' 股');
result := true;
end
else
ShowMessage('错误的股票代码!');
end;

{
*************************************************TCommand
}
constructor TCommand.Create(Market: TStockMarket;
Code: String;
Quantity: integer);
begin
FStockMarket := Market;
FStockCode := Code;
FStockQuantity := quantity;
end;

{
*************************************************TBuyCommand
}
function TBuyCommand.Execute: boolean;
begin
result := FStockMarket.BuyStock(FStockCode, FStockQuantity);
end;

{
*************************************************TSellCommand
}
function TSellCommand.Execute: boolean;
begin
result := FStockMarket.SellStock(FStockCode, FStockQuantity)
end;

{
*************************************************TBroker
}
constructor TBroker.Create(Command: TCommand);
begin
FCommand := Command;
end;

function TBroker.Action: boolean;
begin
result := FCommand.Execute;
end;

end.


{
*************************************************
设计模式学习实例——Command模式
版权所有(C) 2005
*************************************************
}
unit fmMain;
{
*************************************************
项目:繁荣的股市
单元:用户界面
功能:提供用户界面
作者:
创建:2005-06-07
修改:2005-06-08
版本:Ver0.1.0
历史:时间 版本 说明
2005-06-08 Ver0.1.0 第一个版本
*************************************************
}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ActnList, jpeg;
type
TForm1 = class(TForm)
Panel1: TPanel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
uses ugmStock;
{$R *.dfm}
var
StockMarket: TStockMarket;
StockCode: string;
StockQuantity: integer;
Broker: TBroker;
Command: TCommand;

procedure TForm1.FormCreate(Sender: TObject);
begin
StockMarket := TStockMarket.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
try
StockCode := Edit1.Text;
StockQuantity := StrToInt(Edit2.Text);
except
ShowMessage('交易指令错误!'+chr(13)+chr(13)+ '请检查股票代码和数量。');
end;
Command := TBuyCommand.Create(StockMarket, StockCode, StockQuantity);
Broker := TBroker.Create(Command);
if Broker.Action then
ShowMessage('交易成功!')
else
ShowMessage('交易失败!');
Broker.Free;
Command.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
try
StockCode := Edit1.Text;
StockQuantity := StrToInt(Edit2.Text);
except
ShowMessage('交易指令错误!'+chr(13)+chr(13)+ '请检查股票代码和数量。');
end;
Command := TSellCommand.Create(StockMarket, StockCode, StockQuantity);
Broker := TBroker.Create(Command);
if Broker.Action then
ShowMessage('交易成功!')
else
ShowMessage('交易失败!');
Broker.Free;
Command.Free;
end;

end.

end.
 
呵呵,今天大盘上涨8%,老兄有感而发吧:)
 
是郭大侠,荣幸!荣幸!
敬请指教!
 
第一个问题:
点击MM图上空白部分,右键,属性,大概在第二页(我现在机器上没有mm,可能说不清楚)
第二个问题:
可以尝试工厂方法
 
感谢老张的提示。
工厂方法大的相关章节,我也读过,却没想到可以用在此处。
看来,还是纸上谈兵。
请张大侠多多指教!
 
这样写
type
TCommandClass=class of TCommand;
....
procedure TForm1.ExecuteCommand(cmdClass:TCommandClass);
begin
Command := cmdClass.Create(......);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ExecuteCommand(TBuyCommand);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ExecuteCommand(TSellCommand);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

end;
 
呵呵,更正一下
type
TCommandClass=class of TCommand;
....
procedure TForm1.ExecuteCommand(cmdClass:TCommandClass);
begin
Command := cmdClass.Create(......);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ExecuteCommand(TBuyCommand);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ExecuteCommand(TSellCommand);
end;
 
感谢楼主,又学习了学习!
 
Class实现的?模仿C++和原版的设计模式的例子.
为什么不用Interface呢?
不过我在实现模式的时候也同样喜欢用Class。
只是在这里和大家探讨而已,如果没有需要实现双继承的时候Class是否和Interface有相同的用处呢?就算有也可以用成员对象来完成...
 

Similar threads

I
回复
0
查看
525
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
817
SUNSTONE的Delphi笔记
S
顶部