设计模式循序渐进(2)装饰者模式 Decorator

模式解说:
  装饰者模式以对客户端透明的方式动态的为对象附加责任。装饰者模式提供了一个比继承更为灵活的替代方案来扩展对象的功能。该模式的用意是保持对象的接口,增强对象的功能。

模式结构:
  TComponent:抽象部件;定一个对象接口,可以动态附加责任到其它对象上。
  TConcreteComponent:具体部件;定义可以被附加责任的对象。
  TDecorator:装饰者;维护一个到抽象部件对象的引用,并定义与抽象部件接口一致的接口,以便“装饰”抽象部件对象的接口。
  TConcreteDecorator:具体装饰者;附加责任到抽象部件,完成具体的“装饰”。

UML结构图:

Delphi实现
unit uDecorator;

interface

uses
  forms;

type
  TFrmShow 
= class(TObject)
  
public
    procedure Display(Owner: TForm); 
virtualabstract;
  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.

窗体文件
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

posted @ 2008-06-06 08:15  treemon  阅读(353)  评论(0编辑  收藏  举报