设计模式循序渐进(8)职责链模式 Chain Of Responsibility
模式解说:
责任链模式是一种对象的行为模式,它将处理客户端请求的那些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。其目的是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
UML结构图
下面看看职责链的实现,并对该if进行重构
http://www.zhangsk.cn
责任链模式是一种对象的行为模式,它将处理客户端请求的那些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。其目的是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
UML结构图
//先看一个复杂的if语句,我已经将该语句在面向过程的范围内进行了重构,看起来好一点。
unit uAudit;
interface
type
TAudit = class(TObject)
public
procedure ProcessAudit(money: Integer);
end;
implementation
{ TAudit }
procedure TAudit.ProcessAudit(money: Integer); //处理审批
procedure ProcessByDirectorate;
begin
Writeln('500000元以上的审批,董事会处理');
end;
procedure ProcessByPresident;
begin
if money > 500000 then
ProcessByDirectorate
else
Writeln('50001-500000元的审批,总裁处理');
end;
procedure ProcessByManager;
begin
if money > 50000 then
ProcessByPresident
else
Writeln('5001-50000元的审批,经理处理');
end;
begin
if money > 5000 then
ProcessByManager
else
Writeln('5000元以下的审批,主任处理');
end;
end.
unit uAudit;
interface
type
TAudit = class(TObject)
public
procedure ProcessAudit(money: Integer);
end;
implementation
{ TAudit }
procedure TAudit.ProcessAudit(money: Integer); //处理审批
procedure ProcessByDirectorate;
begin
Writeln('500000元以上的审批,董事会处理');
end;
procedure ProcessByPresident;
begin
if money > 500000 then
ProcessByDirectorate
else
Writeln('50001-500000元的审批,总裁处理');
end;
procedure ProcessByManager;
begin
if money > 50000 then
ProcessByPresident
else
Writeln('5001-50000元的审批,经理处理');
end;
begin
if money > 5000 then
ProcessByManager
else
Writeln('5000元以下的审批,主任处理');
end;
end.
下面看看职责链的实现,并对该if进行重构
// Added by zhangsk 2008-6-9 23:09:08 使用职责链模式重构
unit uAuditChain;
interface
type
THandle = class(TObject)
private
FSuccessor: THandle;
procedure SetSuccessor(const Value: THandle);
public
property Successor: THandle read FSuccessor write SetSuccessor;
procedure HandleRequest(money: Integer); virtual; abstract;
end;
TDirectorHandle = class(THandle) //主任
public
procedure HandleRequest(money: Integer); override;
end;
TManagerHandle = class(THandle) //经理
public
procedure HandleRequest(money: Integer); override;
end;
TPresidentHandle = class(THandle) //总裁
public
procedure HandleRequest(money: Integer); override;
end;
TDirectorateHandle = class(THandle) //董事会
public
procedure HandleRequest(money: Integer); override;
end;
implementation
{ THandle }
procedure THandle.SetSuccessor(const Value: THandle);
begin
FSuccessor := Value;
end;
{ TDirectorHandle }
procedure TDirectorHandle.HandleRequest(money: Integer);
begin
if Assigned(FSuccessor) and (money > 5000) then
FSuccessor.HandleRequest(money)
else
Writeln('5000元以下,主任处理');
end;
{ TManagerHandle }
procedure TManagerHandle.HandleRequest(money: Integer);
begin
if Assigned(FSuccessor) and (money > 50000) then
FSuccessor.HandleRequest(money)
else
Writeln('5001-50000元,经理处理');
end;
{ TPresidentHandle }
procedure TPresidentHandle.HandleRequest(money: Integer);
begin
if Assigned(FSuccessor) and (money > 500000) then
FSuccessor.HandleRequest(money)
else
Writeln('50001-500000元,总裁处理');
end;
{ TDirectorateHandle }
procedure TDirectorateHandle.HandleRequest(money: Integer);
begin
Writeln('500000元以上,董事会处理');
end;
end.
unit uAuditChain;
interface
type
THandle = class(TObject)
private
FSuccessor: THandle;
procedure SetSuccessor(const Value: THandle);
public
property Successor: THandle read FSuccessor write SetSuccessor;
procedure HandleRequest(money: Integer); virtual; abstract;
end;
TDirectorHandle = class(THandle) //主任
public
procedure HandleRequest(money: Integer); override;
end;
TManagerHandle = class(THandle) //经理
public
procedure HandleRequest(money: Integer); override;
end;
TPresidentHandle = class(THandle) //总裁
public
procedure HandleRequest(money: Integer); override;
end;
TDirectorateHandle = class(THandle) //董事会
public
procedure HandleRequest(money: Integer); override;
end;
implementation
{ THandle }
procedure THandle.SetSuccessor(const Value: THandle);
begin
FSuccessor := Value;
end;
{ TDirectorHandle }
procedure TDirectorHandle.HandleRequest(money: Integer);
begin
if Assigned(FSuccessor) and (money > 5000) then
FSuccessor.HandleRequest(money)
else
Writeln('5000元以下,主任处理');
end;
{ TManagerHandle }
procedure TManagerHandle.HandleRequest(money: Integer);
begin
if Assigned(FSuccessor) and (money > 50000) then
FSuccessor.HandleRequest(money)
else
Writeln('5001-50000元,经理处理');
end;
{ TPresidentHandle }
procedure TPresidentHandle.HandleRequest(money: Integer);
begin
if Assigned(FSuccessor) and (money > 500000) then
FSuccessor.HandleRequest(money)
else
Writeln('50001-500000元,总裁处理');
end;
{ TDirectorateHandle }
procedure TDirectorateHandle.HandleRequest(money: Integer);
begin
Writeln('500000元以上,董事会处理');
end;
end.
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
uAudit in 'uAudit.pas',
uAuditChain in 'uAuditChain.pas';
var
aAudit: TAudit;
Director: THandle;
Manager: THandle;
President: THandle;
Directorate: THandle;
begin
{ TODO -oUser -cConsole Main : Insert code here }
//使用面向过程的方法
aAudit := TAudit.Create;
aAudit.ProcessAudit(500);
aAudit.ProcessAudit(6000);
aAudit.ProcessAudit(60000);
aAudit.ProcessAudit(600000);
aAudit.Free;
//职责链重构后
Director := TDirectorHandle.Create;
Manager := TManagerHandle.Create;
President := TPresidentHandle.Create;
Directorate := TDirectorateHandle.Create;
Director.Successor := Manager;
Manager.Successor := President;
President.Successor := Directorate;
Director.HandleRequest(500);
Director.HandleRequest(6000);
Director.HandleRequest(60000);
Director.HandleRequest(600000);
Director.Free;
Manager.Free;
President.Free;
Directorate.Free;
Readln;
end.
{$APPTYPE CONSOLE}
uses
SysUtils,
uAudit in 'uAudit.pas',
uAuditChain in 'uAuditChain.pas';
var
aAudit: TAudit;
Director: THandle;
Manager: THandle;
President: THandle;
Directorate: THandle;
begin
{ TODO -oUser -cConsole Main : Insert code here }
//使用面向过程的方法
aAudit := TAudit.Create;
aAudit.ProcessAudit(500);
aAudit.ProcessAudit(6000);
aAudit.ProcessAudit(60000);
aAudit.ProcessAudit(600000);
aAudit.Free;
//职责链重构后
Director := TDirectorHandle.Create;
Manager := TManagerHandle.Create;
President := TPresidentHandle.Create;
Directorate := TDirectorateHandle.Create;
Director.Successor := Manager;
Manager.Successor := President;
President.Successor := Directorate;
Director.HandleRequest(500);
Director.HandleRequest(6000);
Director.HandleRequest(60000);
Director.HandleRequest(600000);
Director.Free;
Manager.Free;
President.Free;
Directorate.Free;
Readln;
end.
http://www.zhangsk.cn