您的位置:首页 > 编程语言 > Delphi

《GOF设计模式》—原型(Prototype)—Delphi源码示例:初始化克隆对象

2010-10-30 15:53 639 查看
示例:初始化克隆对象
说明:
当一些客户对克隆对象已经相当满意时,另一些客户将会希望使用他们所选择的一些值来初始化该对象的一些或是所有的内部状态。一般来说不可能在Clone操作中传递这些值,因为这些值的数目由于原型的类的不同而会有所不同。一些原型可能需要多个初始化参数,另一些可能什么也不要。在Clone操作中传递参数会破坏克隆接口的统一性。
有时候,原型类已经为(重)设定一些关键的状态值定义好了操作。如果这样的话,客户在克隆后马上就可以使用这些操作初始化克隆对象。否则,你就可能不得不引入一个Initialize操作,该操作使用初始化参数并据此设定克隆对象的内部状态。注意深拷贝Clone操作,一些复制在你重新初始化它们之前可能必须要被删除掉(删除可以显式地做也可以在Initialize内部做)。
代码:

unit uPrototypeInit;

interface

uses
Classes;

type
TStateObject = class
private
FState: string;
public
constructor Create(AState: string = '');
//---
property State: string read FState write FState;
end;

TBaseObject = class
private
FState: string;
public
function Clone: TBaseObject; virtual; abstract;
function GetAllState: string; virtual;
//---
property State: string read FState;
end;

TObjectA = class(TBaseObject)
private
procedure SetState(AState: string);
public
constructor Create(AState: string = '');
//---
function Clone: TBaseObject; override;
end;

TObjectB = class(TBaseObject)
public
function Clone: TBaseObject; override;
procedure Initialize(AState: string);
end;

TObjectC = class(TBaseObject)
private
FMyState: TStateObject;
public
constructor Create;
destructor Destroy; override;
//---
function Clone: TBaseObject; override;
function GetAllState: string; override;
procedure Initialize(AState: string); overload;
procedure Initialize(const Value: TStateObject); overload;
//---
property MyState: TStateObject read FMyState;
end;

TClient = class
private
FPrototype: TBaseObject;
public
constructor Create(Prototype: TBaseObject);
destructor Destroy; override;
//---
function CreateObject: TBaseObject;
end;

implementation

constructor TStateObject.Create(AState: string = '');
begin
FState := AState;
end;

function TBaseObject.GetAllState: string;
begin
Result := FState;
end;

function TObjectA.Clone: TBaseObject;
var
AObject: TObjectA;
begin
AObject := TObjectA.Create('');
AObject.SetState(self.State);
//---
Result := AObject;
end;

constructor TObjectA.Create(AState: string = '');
begin
inherited Create;
//---
SetState(AState);
end;

procedure TObjectA.SetState(AState: string);
begin
FState := AState;
end;

constructor TObjectC.Create;
begin
inherited;
//---
FMyState := nil;
end;

destructor TObjectC.Destroy;
begin
if FMyState <> nil then
FMyState.Free;
//---
inherited;
end;

function TObjectC.Clone: TBaseObject;
var
AObject: TObjectC;
AState: TStateObject;
begin
AObject := TObjectC.Create;
AObject.Initialize(self.State);
if self.MyState <> nil then
begin
AState := TStateObject.Create;
AState.State := self.MyState.State;
AObject.Initialize(AState);
end;
//---
Result := AObject;
end;

function TObjectC.GetAllState: string;
begin
if FMyState <> nil then
Result := FState + FMyState.State
else
Result := FState;
end;

procedure TObjectC.Initialize(AState: string);
begin
FState := AState;
end;

procedure TObjectC.Initialize(const Value: TStateObject);
begin
if assigned(FMyState) then
FMyState.Free;
FMyState := Value;
end;

constructor TClient.Create(Prototype: TBaseObject);
begin
FPrototype := Prototype;
end;

destructor TClient.Destroy;
begin
FPrototype.Free;
//---
inherited;
end;

function TClient.CreateObject: TBaseObject;
begin
Result := FPrototype.Clone;
end;

function TObjectB.Clone: TBaseObject;
var
AObject: TObjectB;
begin
AObject := TObjectB.Create;
AObject.Initialize(self.State);
//---
Result := AObject;
end;

procedure TObjectB.Initialize(AState: string);
begin
FState := AState;
end;

end.

procedure TForm1.Button1Click(Sender: TObject);
var
APrototype,AObject: TBaseObject;
AClient: TClient;
begin
APrototype := TObjectA.Create('Prototype A');
//---
AClient := TClient.Create(APrototype);
try
AObject := AClient.CreateObject;
showmessage(AObject.GetAllState);
AObject.Free;
finally
AClient.Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
APrototype: TObjectB;
AObject: TBaseObject;
AClient: TClient;
begin
APrototype := TObjectB.Create;
APrototype.Initialize('Prototype B');
//---
AClient := TClient.Create(APrototype);
try
AObject := AClient.CreateObject;
showmessage(AObject.GetAllState);
TObjectB(AObject).Initialize('Object B');
showmessage(AObject.GetAllState);
AObject.Free;
finally
AClient.Free;
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
APrototype: TObjectC;
AObject: TBaseObject;
AClient: TClient;
begin
APrototype := TObjectC.Create;
APrototype.Initialize('Prototype C');
APrototype.Initialize(TStateObject.Create(' 123'));
//---
AClient := TClient.Create(APrototype);
try
AObject := AClient.CreateObject;
showmessage(AObject.GetAllState);
TObjectC(AObject).Initialize(TStateObject.Create(' 456'));
showmessage(AObject.GetAllState);
AObject.Free;
finally
AClient.Free;
end;
end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐