zoukankan      html  css  js  c++  java
  • 装饰者模式

    一.模式解说

    以客户端透明的方式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案。装饰者模式用意是要保持对象接口,增强对象性能.

    实际生活中经常发现装饰者模式.比如,你需要装裱挂画,你不想讲画和画框定死以便更换不同的画框.下图就是一个装裱挂画的装饰者模式.

    装饰者模式的使用时机:

    1. 在不影响其他对象的情况下,动态透明的增加责任到一个对象.

    2.希望责任和功能可以随时增加或取消.

    3.当无法通过类继承来扩展功能时.

    二.结构和用法

    2.1 模式结构

     装饰者模式结构如下图:

    包含以下参与者:

    1. 抽象部件(TComonent):定义一个接口可以动态的附加责任到其他对象.

    2.具体部件(TConcreteComponent): 定义可以被附加责任的对象.

    3.装饰者(TDecorator): 维护一个抽象部件对象的引用,并定义与抽象部件接口一致的接口,以便装饰抽象部件对象接口.

    4.具体装饰者(TConcreteDecorator): 附加责任到抽象部件,完成具体的装饰.

    2.2 代码模板(Delphi)

       

    unit Decorator;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;
    
    type
      Tcomponent = class(TObject)
      public
        procedure Operation; virtual; abstract;
      end;
    
      TConcreteComponent = class(Tcomponent)
      public
        procedure Operation; override;
      end;
    
      TDecorator = class(Tcomponent)
      private
        FComponent: TComponent;
      public
        constructor Create(Component: TComponent);
        procedure Operation;overload; override;
      end;
    
      TConcreteDecoratorA = class(TDecorator)
      private
        FAddedState: integer;
      public
        procedure Operation;override;
      end;
    
      TConcreteDecoratorB = class(TDecorator)
      public
        procedure AddedBehavior;
        procedure Operation;override;
      end;
    
    implementation
    
    { TConcreteComponent }
    
    procedure TConcreteComponent.Operation;
    begin
      //被装饰者部件的操作代码
    end;
    
    { TDecorator }
    
    constructor TDecorator.Create(Component: TComponent);
    begin
      FComponent := Component;
    end;
    
    procedure TDecorator.Operation;
    begin
      if FComponent <> nil then
        FComponent.Operation;
    end;
    
    { TConcreteDecoratorA }
    
    procedure TConcreteDecoratorA.Operation;
    begin
      //装饰部件操作代码
    end;
    
    { TConcreteDecoratorB }
    
    procedure TConcreteDecoratorB.AddedBehavior;
    begin
      //装饰者新增操作的代码
    end;
    
    procedure TConcreteDecoratorB.Operation;
    begin
      //装饰部件操作代码
      // 注意这里是装饰后已经扩展了对象的功能
      inherited Operation;
      AddedBehavior;
    end;
    
    end.

     2.3 问题讨论

     三. 范例与实践

    3.1 装饰者模式在图片观赏器中的应用

     

     部分示例代码:

    unit PicDecorator;
    
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, ComCtrls, Jpeg;
    
    type
    
      TPicShow = class(TObject)
      public
        procedure Display(Owner: TForm; ImgFile: string); virtual; abstract;
      end;
    
      TPic = class(TPicShow)
      public
        procedure Display(Owner: TForm; ImgFile: string); override;
      end;
    
      TDecoratedPic = class(TPicShow)
      private
        FComponent: TPicShow;
      public
        constructor Create(PicShow: TPicShow);
        procedure Display(Owner: TForm; ImgFile: string); overload; override;
      end;
    
      TPicWithFrame = class(TDecoratedPic)
      private
        FAddedFrame: integer;
      public
        procedure Display(Owner: TForm; ImgFile: string); override;
        destructor Destroy; override;
      end;
    
      TPicWithMusic = class(TDecoratedPic)
      public
        destructor Destroy; override;
        procedure AddMusic;
        procedure Display(Owner: TForm; ImgFile: string); override;
      end;
    
    implementation
    
    { TPic }
    
    procedure TPic.Display(Owner: TForm; ImgFile: string);
    var
      Img : TImage;
    begin
      Img := TImage.Create(Owner);
      Img.Picture.LoadFromFile(ImgFile);
      Img.AutoSize := True;
      Img.Stretch := True;
      Owner.Width := Img.Width + 32;
      Owner.Height := Img.Height + 64;
      Owner.Caption := ImgFile;
      Img.Left := 11;
      Img.Top := 13;
      Img.Parent := Owner;
    end;
    
    { TDecoratedPic }
    
    constructor TDecoratedPic.Create(PicShow: TPicShow);
    begin
      Self.FComponent := PicShow;
    end;
    
    procedure TDecoratedPic.Display(Owner: TForm; ImgFile: string);
    begin
      if FComponent <> nil then
        FComponent.Display(Owner, ImgFile);
    end;
    
    { TPicWithFrame }
    
    destructor TPicWithFrame.Destroy;
    begin
      if FComponent <> nil then FComponent.Free;
    end;
    
    procedure TPicWithFrame.Display(Owner: TForm; ImgFile: string);
    var
      FrmOut: TBevel;
      FrmIn: TBevel;
    begin
      inherited Display(Owner, ImgFile);
      FrmIn := Tbevel.Create(Owner);
      FrmIn.Parent := Owner;
      FrmIn.Width := Owner.Width - 30;
      FrmIn.Height := Owner.Height - 62;
      FrmIn.Left := 10;
      FrmIn.Top := 12;
      FrmIn.Shape := bsBox;
      FrmIn.Style := bsLowered;
    
      FrmOut := Tbevel.Create(Owner);
      FrmOut.Parent := Owner;
      FrmOut.Width := Owner.Width - 18;
      FrmOut.Height := Owner.Height - 48;
      FrmOut.Left := 4;
      FrmOut.Top := 6;
      FrmOut.Shape := bsBox;
      FrmOut.Style := bsRaised;
    end;
    
    { TPicWithMusic }
    
    procedure TPicWithMusic.AddMusic;
    begin
      SndPlaySound('SONG.wav', SND_ASYNC or SND_NODEFAULT);
    end;
    
    destructor TPicWithMusic.Destroy;
    begin
      if Self.FComponent <> nil then Self.FComponent.Free;
    end;
    
    procedure TPicWithMusic.Display(Owner: TForm; ImgFile: string);
    begin
      inherited Display(Owner, ImgFile);
      AddMusic;
    end;
    
    end.

    四.总结

  • 相关阅读:
    一个好的时间函数
    Codeforces 785E. Anton and Permutation
    Codeforces 785 D. Anton and School
    Codeforces 510 E. Fox And Dinner
    Codeforces 242 E. XOR on Segment
    Codeforces 629 E. Famil Door and Roads
    Codeforces 600E. Lomsat gelral(Dsu on tree学习)
    Codeforces 438D The Child and Sequence
    Codeforces 729E Subordinates
    【ATcoder】D
  • 原文地址:https://www.cnblogs.com/lp-blogs/p/6014581.html
Copyright © 2011-2022 走看看