《GOF设计模式》—代理(PROXY)—Delphi源码示例:更新前拷贝机制(copy-on-write)

示例:更新前拷贝机制(copy-on-write

说明:

Proxy模式还可以对用户隐藏另一种称之为copy-on-write的优化方式,该优化与根据需要创建对象有关。拷贝一个庞大而复杂的对象是一种开销很大的操作,如果这个拷贝根本没有被修改,那么这些开销就没有必要。用代理延迟这一拷贝过程,我们可以保证只有当这个对象被修改的时候才对它进行拷贝。

在实现Copy-on-write时必须对实体进行引用计数,“拷贝代理”仅会增加引用计数。只有当用户请求一个修改该实体的操作时,代理才会真正的拷贝它。在这种情况下,代理还必须减少实体的引用计数。当引用的数目为零时,这个实体将被删除。

Copy-on-Write可以大幅度的降低拷贝庞大实体时的开销。

 

代码:

unit uCopyOnWrite;

 

interface

 

uses

    SysUtils,Dialogs;

 

type

    TSubject = class

    protected

        procedure SetState(const Value: string); virtual; abstract;

    public

        procedure Request; virtual; abstract;

        //---

        property State: string write SetState;

    end;

    TRealSubject = class(TSubject)

    private

        FRefCount: Integer;

        FState: string;

    protected

        procedure SetState(const Value: string); override;

    public

        constructor Create;

        //---

        procedure AddRef;

        procedure Release;

        function Copy: TRealSubject;

        procedure Request; override;

        //---

        property RefCount: Integer read FRefCount;

    end;

    TProxy = class(TSubject)

    private

        FSubject: TRealSubject;

    protected

        procedure SetState(const Value: string); override;

    public

        constructor Create;

        destructor Destroy; override;

        //---

        procedure Request; override;

        //---

        procedure Equal(Value: TRealSubject);

    end;

 

implementation

 

constructor TRealSubject.Create;

begin

    FRefCount := 0;

end;

 

procedure TRealSubject.AddRef;

begin

    inc(FRefCount);

end;

 

procedure TRealSubject.Release;

begin

    dec(FRefCount);

end;

 

procedure TRealSubject.Request;

begin

    ShowMessage(FState);

end;

 

procedure TRealSubject.SetState(const Value: string);

begin

    FState := Value;

end;

 

function TRealSubject.Copy: TRealSubject;

begin

    Result := TRealSubject.Create;

    Result.State := FState;

end;

 

constructor TProxy.Create;

begin

    FSubject := nil;

end;

 

destructor TProxy.Destroy;

begin

    self.Equal(nil);

    //---

    inherited;

end;

 

procedure TProxy.Request;

begin

    if Assigned(FSubject) then

        FSubject.Request;

end;

 

procedure TProxy.Equal(Value: TRealSubject);

    //---

    procedure _Clear;

    begin

        if Assigned(FSubject) then

        begin

            FSubject.Release;

            if FSubject.RefCount = 0 then

                FreeAndNil(FSubject);

        end;

    end;

    //---

    procedure _Equal;

    begin

        FSubject := Value;

        if Assigned(FSubject) then

            FSubject.AddRef;

    end;

begin

    if FSubject <> Value then

    begin

        _Clear;

        _Equal;

    end;

end;

 

procedure TProxy.SetState(const Value: string);

    //---

    procedure _Copy;

    begin

        if Assigned(FSubject) then

            self.Equal(FSubject.Copy)

        else

            self.Equal(TRealSubject.Create);

    end;

    //---

    procedure _Write;

    begin

        FSubject.State := Value;

    end;

begin

    _Copy;

    _Write;

end;

 

end.

 

procedure TForm1.Button1Click(Sender: TObject);

var

    ASubject1: TRealSubject;

    ASubject2: TProxy;

begin

    ASubject1 := TRealSubject.Create;

    ASubject1.State := '123';

    //---

    ASubject2 := TProxy.Create;

    try

        ASubject2.Equal(ASubject1);

        ASubject2.Request;

        //---

        ASubject2.State := 'abc';

        ASubject2.Request;

    finally

        ASubject2.Free;

    end;

end;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值