天天看点

《大话设计模式》之 装饰模式 Delphi实现

 装饰模式:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。[GOF 《设计模式》]

这句话怎么理解?

 一般来说,增加功能,一般有增加类本身的功能;另外一种是增加子类;但是现实中,靠增加子类来满足实际需求,是远远不够的,缺少灵活性;

 

装饰模式,它强调的要增加功能,但又不允许生产过多子类,那么该怎么实现呢? 它的指导思想,是进行包裹,层次包裹。子类对象包裹父类对象,一层一层,功能就一层一层。

  1.首先定义一个首先抽象类或接口;

  2.定了两个继承抽象类或实现接口方法的类,一个是装饰类,一个一般类,装饰类,定义一个方法,接受父类型;

 

 

{

 装饰模式,强调的功能逐渐一层层包裹。 本例子, 以西游记中,孙悟空的72般变化,话说当年,

 悟空不远千里,拜师学艺,功夫是一天天长进。腾云驾雾,翻筋斗,变美女/树等,这些功夫,是

 一一学会的。

 抽象虚拟类,作为父类。

所有代码 均在 Delphi7 测试通过

 

}

unit Decorator;

interface

uses ComObj;

type

   {基础类}

  TMonkey = class(TObject)

  private

    FMonkey: TMonkey;

  public

    FGongFu: string;

    procedure Operation; virtual;

    procedure SetGongFuMonkey(Monkey: TMonkey);

    procedure WriteLog;

  end;

  {无法术}

  TFongFuNo = class(TMonkey)

  public

    procedure Operation; override;

  end;

  {腾云驾雾}

  TGongFuKey = class(TMonkey)

  public

    procedure Operation; override;

  end;

  {翻筋斗}

  TGongFuSomeRsault = class(TMonkey)

  public

    procedure Operation; override;

  end;

  {变树/美人}

  TGongFuChange = class(TMonkey)

  public

    procedure Operation; override;

    procedure AddOtherMethod;

  end;

implementation

uses Unit1;

{ TGongFuKey }

procedure TGongFuKey.Operation;

begin

  inherited;

  FGongFu := '已经学会腾云驾雾之术';

  WriteLog;

end;

{ TGongGuSomeRsault }

procedure TGongFuSomeRsault.Operation;

begin

  inherited;

  FGongFu := '已经学会翻跟斗';

  WriteLog;

end;

{ TGongFuChange }

procedure TGongFuChange.AddOtherMethod;

begin

  {增加其它方法}

end;

procedure TGongFuChange.Operation;

begin

  inherited;

  FGongFu := '已经变美女和变树';

  WriteLog;

  AddOtherMethod;

  {......}

end;

{ TMonkey }

procedure TMonkey.SetGongFuMonkey(Monkey: TMonkey);

begin

  FMonkey := Monkey;

end;

procedure TMonkey.Operation;

begin

  if FMonkey <> nil then

    FMonkey.Operation;

end;

procedure TMonkey.WriteLog;

begin

  Form1.Memo1.Lines.Add(FGongFu);

end;

{ TFongFuNo }

procedure TFongFuNo.Operation;

begin

  inherited;

  FGongFu := '无功夫,需要学习';

  WriteLog;

end;

end.

 

{调用}

 

unit Unit1;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls;

type

  TForm1 = class(TForm)

    Button1: TButton;

    Memo1: TMemo;

    procedure Button1Click(Sender: TObject);

  private

    procedure GongFun;

    { Private declarations }

  public

    { Public declarations }

  end;

var

  Form1: TForm1;

implementation

uses Decorator;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin

  GongFun;

end;

procedure TForm1.GongFun;

var

  {猴子}

  Monkey: TMonkey;

  {无功夫}

  FongFuNo: TFongFuNo;

  {腾云驾雾}

  GongFuKey: TGongFuKey;

  {翻筋斗}

  GongFuSomeRsault: TGongFuSomeRsault;

  {变树、美女}

  GongFuChange: TGongFuChange;

begin

  {猴子}

  Monkey := TMonkey.Create;

  {无功夫}

  FongFuNo := TFongFuNo.Create;

  {腾云驾雾}

  GongFuKey := TGongFuKey.Create;

  {翻筋斗}

  GongFuSomeRsault := TGongFuSomeRsault.Create;

  {变树、美女}

  GongFuChange := TGongFuChange.Create;

  Memo1.Lines.Clear;

  {注意装饰模式中,对象创建的先后顺序是可以随时可以变化的}

  {情况之一 的猴子}

  {

   无功夫,需要学习

   已经学会腾云驾雾之术

   已经学会翻跟斗

   已经变美女和变树

   }

  Form1.Memo1.Lines.Add('情况之一 的猴子:   ');

  FongFuNo.SetGongFuMonkey(Monkey);

  GongFuKey.SetGongFuMonkey(FongFuNo);

  GongFuSomeRsault.SetGongFuMonkey(GongFuKey);

  GongFuChange.SetGongFuMonkey(GongFuSomeRsault);

  GongFuChange.Operation;

  Form1.Memo1.Lines.Add('                   ');

  Form1.Memo1.Lines.Add('                   ');

   {情况之二 的猴子}

   {无功夫,需要学习

    已经变美女和变树

    已经学会腾云驾雾之术

    已经学会翻跟斗}

  Form1.Memo1.Lines.Add('情况之二 的猴子:   ');

  FongFuNo.SetGongFuMonkey(Monkey);

  GongFuChange.SetGongFuMonkey(FongFuNo);

  GongFuKey.SetGongFuMonkey(GongFuChange);

  GongFuSomeRsault.SetGongFuMonkey(GongFuKey);

  GongFuSomeRsault.Operation;

end;

end.

 

 

{Frm 文件}

 

object Form1: TForm1

  Left = 297

  Top = 186

  Width = 312

  Height = 392

  Caption = 'Form1'

  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 Button1: TButton

    Left = 8

    Top = 312

    Width = 193

    Height = 25

    Caption = '测试-策略模式用例'

    TabOrder = 0

    OnClick = Button1Click

  end

  object Memo1: TMemo

    Left = 8

    Top = 8

    Width = 249

    Height = 297

    Lines.Strings = (

      'Memo1')

    TabOrder = 1

  end

end

 

继续阅读