关于设计模式中的策略模式的理解(Delphi版)(0分)

  • 主题发起人 主题发起人 billy_yuan
  • 开始时间 开始时间
B

billy_yuan

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
// 策略接口 (抽象类)
TFinanzeCharge = class
public
// 返回计算的结果
function getCharge(const Balance:do
uble):do
uble;
virtual;
abstract;
end;

// 具体策略
TRegularCharge = class(TFinanzeCharge)
public
function getCharge(const Balance:do
uble):do
uble;
override;
end;

//具体策略
TPreferredCharge = class(TFinanzeCharge)
public
function getCharge(const Balance:do
uble):do
uble;
override;
end;

// 上下文接口
TChargeContext = class
public
function ComputeCharges(const Balance:do
uble):do
uble;
virtual;
abstract;
end;

//具体的上下文的实现
TMonthlyCharges = class(TChargeContext)
private
//其目的是存储具体策略的实例
FFinanzeCharge: TFinanzeCharge;
public
//客户程序访问的接口
function ComputeCharges(const Balance:do
uble):do
uble;
override;
//通过具体策略做为参数
constructor Create(aFinanzeCharge: TFinanzeCharge);
virtual;
destructor Destroy;
override;
end;

TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
function TRegularCharge.getCharge(const Balance:do
uble):do
uble;
var
REG_RATE :integer ;
begin
REG_RATE := 100 ;
//这里是随便一个数,只是说与TPreferredCharge不同的计算方式
result := Balance * (REG_RATE / 12);
end;

function TPreferredCharge.getCharge(const Balance:do
uble):do
uble;
var
PREFERRED_RATE:double ;
begin
PREFERRED_RATE := 150 ;
//这里是随便一个数,只是说与TRegularCharge不同的计算方式
result := Balance * (PREFERRED_RATE / 12);
end;

constructor TMonthlyCharges.Create(aFinanzeCharge: TFinanzeCharge);
begin
inherited Create;
//保存传入的具体策略的实例
//所有的具体策略都是策略接口的子类,根据子类可以代替父类的原则,这里什么具体策略都可以传进来!
FFinanzeCharge := aFinanzeCharge;
end;

destructor TMonthlyCharges.Destroy;
begin
FFinanzeCharge.Free;
inherited Destroy;
end;

function TMonthlyCharges.ComputeCharges(const Balance:do
uble):do
uble;
begin
result := FFinanzeCharge.getCharge(Balance);
//这行是关键,这时的FFinanzeCharge是根据Create传入的aFinanzeCharge 来决定的!
end;
{$R *.DFM}
end.
以上的模式再加上类工厂模式的话,那样的代码的可阔张性就很强了!
最后请大家记住两件事,一件是这个模式叫strategy模式,另外一件事是我叫billy!
香蕉皮,鸡蛋怎么来了!
 
学习了!!!
 
认知中.....[:D]
 
最好能讲解一下这些模式都适合什么情况下使用.
 
类工厂模式要维护两个平行的类层次,不好操作呀,
 
程序看懂,但不懂里面有什么策略。
 
我想扔西红柿
 
其实我的注释写得比较清楚了,
不过我还是再想说明一下,如果有过写过逻辑类的经验那非常好理解!如果还没能懂
我的意思,那只有扔西红柿过来吧!
TRegularCharge,TRegularCharge在这里就是具体策略,如果你想要写的话,你还可以
写出很多的具体策略(即具体的实现方法),TMonthlyCharges是月结的意思,在月结
当中由于各重各样的原因,计算方式(具体策略)就有可能不同,计算方式的增加与
修改只需要写增加与修改一个相应的类就行了,这样的结构非常清晰,
其实好的代码就在于一旦你的业务逻辑发生改变,你的代码能迅速能通过增加代码来
实现,或者通过修改基础数据来实现。程序做了3年,业务逻辑本人还没有真正碰到过
一成不变的。
好了现在可以扔西红柿过来了!
 
[8D]
Strategy就是把一组算法用类包装起来吧
不过delphi的模式实现看起来总是怪怪的,有abstract factory的代码吗?
 
看通你的程序了。不过有一点我觉得值得商榷:
TFinanzeCharge的各子类的生成是在TMonthlyCharge类的构造函数里实现的,也就是说在
生成TChargeContext类之前就要先生成一个TFinazeCharge的实例,调用的时候应当是这样
的:
aRegularCharge = TRegularCharge.create;
aMonthlyCharge = TMonthlyCharge.create(aRegularCharge);
那样的话,生成TFinanzeCharge各子类的逻辑就在TChargeContext类外部了
我觉得可以利用一个敉举变量(Enumerated types),然后将它作为参数传给TChargeContext
的构造函数,这样实现TFinanzeCharge的过程就隐藏在TChargeContext类的内部了。
这样做的好处在于,对于客户(调用TChargeContext的程序)来说,它不必知道TFinanzeCharge
类的存在,你只要知道一个算法的代号(敉举变量的值)和初始参数的列表就行了
 
例子:
TSort= class
All abstract methord
TAVLTree= class(TSort)
Realize abstract methord with AVLTree
TBTree= class(TSort)
Realize abstract methord with BTree or B+Tree
...
 
继续其它模式
 
to kusanagi
你的例子看起来好象简单了一点,本人看不太明白!
to mor
你的提议很好,但是我在上面说了,如果结合类工厂的模式就能实现!
function CreateCharge(FinanzeKind:integer):TFinanzeCharge ;
通过FinanzeKind的值来具体决定用那个类的算法!你是用枚举变量来是实现,INTEGER也可以啊
在这个函数里面不涉及到具体的实现类!
然后再把 CreateCharge的返回值放到constructor Create(aFinanzeCharge: TFinanzeCharge);
virtual
里面,多爽啊。。。。。
 
面向接口编程
 
我有《设计模式》中所有模式的例子(Delphi版)。
有兴趣的报名。
 
高手,挺不错的,学习!能否让我报个名?zou7705@etang.com.谢谢了!
 
正在学习模式中。。。
 
kusanagi和楼主的意思是一致的,关键在于策略模式的神髓就在于一个对象指定一个特定的响应或需求,而这种响应或需求通过不同对象来进行各不相同的实现。其实就是OO中的多态的概念模式化。
 
当规则发生变化时,新增加一个类就行了。
修改规则后,也只需修改一个类
 
to 搂主:
如果把TFinanzeCharge换成IFinanzeCharge(接口),具体策略再从(Iinterfaceobject,IFinanzecharge)派生,有什么优劣?谢。
 

Similar threads

I
回复
0
查看
585
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部