设计模式循序渐进(2)装饰者模式 Decorator
模式解说:
装饰者模式以对客户端透明的方式动态的为对象附加责任。装饰者模式提供了一个比继承更为灵活的替代方案来扩展对象的功能。该模式的用意是保持对象的接口,增强对象的功能。
模式结构:
TComponent:抽象部件;定一个对象接口,可以动态附加责任到其它对象上。
TConcreteComponent:具体部件;定义可以被附加责任的对象。
TDecorator:装饰者;维护一个到抽象部件对象的引用,并定义与抽象部件接口一致的接口,以便“装饰”抽象部件对象的接口。
TConcreteDecorator:具体装饰者;附加责任到抽象部件,完成具体的“装饰”。
UML结构图:
Delphi实现
客户端调用
窗体文件
装饰者模式以对客户端透明的方式动态的为对象附加责任。装饰者模式提供了一个比继承更为灵活的替代方案来扩展对象的功能。该模式的用意是保持对象的接口,增强对象的功能。
模式结构:
TComponent:抽象部件;定一个对象接口,可以动态附加责任到其它对象上。
TConcreteComponent:具体部件;定义可以被附加责任的对象。
TDecorator:装饰者;维护一个到抽象部件对象的引用,并定义与抽象部件接口一致的接口,以便“装饰”抽象部件对象的接口。
TConcreteDecorator:具体装饰者;附加责任到抽象部件,完成具体的“装饰”。
UML结构图:
Delphi实现
unit uDecorator;
interface
uses
forms;
type
TFrmShow = class(TObject)
public
procedure Display(Owner: TForm); virtual; abstract;
end;
TFrm = class(TFrmShow)
public
procedure Display(Owner: TForm); override;
end;
TDecorated = class(TFrmShow)
private
FComponent: TFrmShow;
public
constructor Create(FrmShow: TFrmShow);
procedure Display(Owner: TForm); override;
destructor Destroy; virtual;
end;
TDecoratedA = class(TDecorated)
public
procedure Display(Owner: TForm); override;
end;
TDecoratedB = class(TDecorated)
public
procedure Display(Owner: TForm); override;
end;
implementation
{ TFrm }
procedure TFrm.Display(Owner: TForm);
begin
// inherited;
Owner.Caption := 'TFrm.Display';
end;
{ TDecorated }
constructor TDecorated.Create(FrmShow: TFrmShow);
begin
self.FComponent := FrmShow;
end;
destructor TDecorated.Destroy;
begin
if FComponent <> nil then
FComponent.Free;
end;
procedure TDecorated.Display(Owner: TForm);
begin
// inherited;
if FComponent <> nil then
FComponent.Display(Owner);
end;
{ TDecoratedA }
procedure TDecoratedA.Display(Owner: TForm);
begin
inherited;
Owner.Caption := Owner.Caption + '::TDecoratedA.Display';
Owner.Width := Owner.Width + 200;
end;
{ TDecoratedB }
procedure TDecoratedB.Display(Owner: TForm);
begin
inherited;
Owner.Caption := Owner.Caption + '::TDecoratedB.Display';
Owner.Width := Owner.Width + 200;
end;
end.
interface
uses
forms;
type
TFrmShow = class(TObject)
public
procedure Display(Owner: TForm); virtual; abstract;
end;
TFrm = class(TFrmShow)
public
procedure Display(Owner: TForm); override;
end;
TDecorated = class(TFrmShow)
private
FComponent: TFrmShow;
public
constructor Create(FrmShow: TFrmShow);
procedure Display(Owner: TForm); override;
destructor Destroy; virtual;
end;
TDecoratedA = class(TDecorated)
public
procedure Display(Owner: TForm); override;
end;
TDecoratedB = class(TDecorated)
public
procedure Display(Owner: TForm); override;
end;
implementation
{ TFrm }
procedure TFrm.Display(Owner: TForm);
begin
// inherited;
Owner.Caption := 'TFrm.Display';
end;
{ TDecorated }
constructor TDecorated.Create(FrmShow: TFrmShow);
begin
self.FComponent := FrmShow;
end;
destructor TDecorated.Destroy;
begin
if FComponent <> nil then
FComponent.Free;
end;
procedure TDecorated.Display(Owner: TForm);
begin
// inherited;
if FComponent <> nil then
FComponent.Display(Owner);
end;
{ TDecoratedA }
procedure TDecoratedA.Display(Owner: TForm);
begin
inherited;
Owner.Caption := Owner.Caption + '::TDecoratedA.Display';
Owner.Width := Owner.Width + 200;
end;
{ TDecoratedB }
procedure TDecoratedB.Display(Owner: TForm);
begin
inherited;
Owner.Caption := Owner.Caption + '::TDecoratedB.Display';
Owner.Width := Owner.Width + 200;
end;
end.
客户端调用
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
rgDecorator: TRadioGroup;
btn2: TButton;
btn3: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses uDecorator;
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
AForm: TForm;
begin
AForm := TForm.Create(nil);
try
AForm.ShowModal;
finally
AForm.Free;
end;
end;
procedure TForm1.btn2Click(Sender: TObject);
var
AForm: TForm;
AFrmShow: TFrmShow;
begin
AForm := TForm.Create(nil);
AFrmShow := TFrm.Create;
AFrmShow.Display(AForm);
try
AForm.ShowModal;
finally
AFrmShow.Free;
AForm.Free;
end;
end;
procedure TForm1.btn3Click(Sender: TObject);
var
AForm: TForm;
AFrmShow: TFrmShow;
begin
AForm := TForm.Create(nil);
// AFrmShow := TDecorated.Create(TFrm.Create); //应该设计成不能通过TDecorated来创建
case rgDecorator.ItemIndex of
0: AFrmShow := TDecoratedA.Create(TFrm.Create);
1: AFrmShow := TDecoratedB.Create(TFrm.Create);
2: AFrmShow := TDecoratedB.Create( TDecoratedA.Create(TFrm.Create) );
3: AFrmShow := TDecoratedA.Create( TDecoratedB.Create(TFrm.Create) );
4: AFrmShow := TDecoratedB.Create( TDecoratedA.Create( TDecoratedA.Create(TFrm.Create) ) );
end;
AFrmShow.Display(AForm);
try
AForm.ShowModal;
finally
AFrmShow.Free;
AForm.Free;
end;
end;
end.
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
rgDecorator: TRadioGroup;
btn2: TButton;
btn3: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses uDecorator;
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
AForm: TForm;
begin
AForm := TForm.Create(nil);
try
AForm.ShowModal;
finally
AForm.Free;
end;
end;
procedure TForm1.btn2Click(Sender: TObject);
var
AForm: TForm;
AFrmShow: TFrmShow;
begin
AForm := TForm.Create(nil);
AFrmShow := TFrm.Create;
AFrmShow.Display(AForm);
try
AForm.ShowModal;
finally
AFrmShow.Free;
AForm.Free;
end;
end;
procedure TForm1.btn3Click(Sender: TObject);
var
AForm: TForm;
AFrmShow: TFrmShow;
begin
AForm := TForm.Create(nil);
// AFrmShow := TDecorated.Create(TFrm.Create); //应该设计成不能通过TDecorated来创建
case rgDecorator.ItemIndex of
0: AFrmShow := TDecoratedA.Create(TFrm.Create);
1: AFrmShow := TDecoratedB.Create(TFrm.Create);
2: AFrmShow := TDecoratedB.Create( TDecoratedA.Create(TFrm.Create) );
3: AFrmShow := TDecoratedA.Create( TDecoratedB.Create(TFrm.Create) );
4: AFrmShow := TDecoratedB.Create( TDecoratedA.Create( TDecoratedA.Create(TFrm.Create) ) );
end;
AFrmShow.Display(AForm);
try
AForm.ShowModal;
finally
AFrmShow.Free;
AForm.Free;
end;
end;
end.
窗体文件
object Form1: TForm1
Left = 334
Top = 168
Width = 362
Height = 327
Caption = 'Decorator装饰者模式-练习'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object btn1: TButton
Left = 24
Top = 16
Width = 145
Height = 25
Caption = '显示一个Form'
TabOrder = 0
OnClick = btn1Click
end
object rgDecorator: TRadioGroup
Left = 24
Top = 72
Width = 185
Height = 185
Caption = 'rgDecorator'
ItemIndex = 0
Items.Strings = (
'A'
'B'
'A+B'
'B+A'
'A+A+B')
TabOrder = 1
end
object btn2: TButton
Left = 184
Top = 16
Width = 153
Height = 25
Caption = '显示一个处理过的Form'
TabOrder = 2
OnClick = btn2Click
end
object btn3: TButton
Left = 224
Top = 80
Width = 113
Height = 49
Caption = '通过装饰者显示一个处理过的Form'
TabOrder = 3
WordWrap = True
OnClick = btn3Click
end
end
Left = 334
Top = 168
Width = 362
Height = 327
Caption = 'Decorator装饰者模式-练习'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object btn1: TButton
Left = 24
Top = 16
Width = 145
Height = 25
Caption = '显示一个Form'
TabOrder = 0
OnClick = btn1Click
end
object rgDecorator: TRadioGroup
Left = 24
Top = 72
Width = 185
Height = 185
Caption = 'rgDecorator'
ItemIndex = 0
Items.Strings = (
'A'
'B'
'A+B'
'B+A'
'A+A+B')
TabOrder = 1
end
object btn2: TButton
Left = 184
Top = 16
Width = 153
Height = 25
Caption = '显示一个处理过的Form'
TabOrder = 2
OnClick = btn2Click
end
object btn3: TButton
Left = 224
Top = 80
Width = 113
Height = 49
Caption = '通过装饰者显示一个处理过的Form'
TabOrder = 3
WordWrap = True
OnClick = btn3Click
end
end