《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;
说明:
当一些客户对克隆对象已经相当满意时,另一些客户将会希望使用他们所选择的一些值来初始化该对象的一些或是所有的内部状态。一般来说不可能在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;
相关文章推荐
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于类的原型管理器(使用TList和TObject对象服务实现)
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于实例的原型管理器
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于类的原型管理器(使用TList实现)
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于类的原型管理器(使用TStringList实现)
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:浅拷贝和深拷贝
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:原型接口
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:浅拷贝和深拷贝
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于Assign方法的拷贝
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于流操作的拷贝
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于原型的迷宫1
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于原型的迷宫2
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:原型接口
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:乐谱编辑器
- 《GOF设计模式》—工厂方法(Factory Method)—Delphi源码示例:延迟初始化对象
- 《GOF设计模式》—原型(Prototype)—Delphi源码示例:电路设计编辑器
- 《GOF设计模式》—迭代器 (ITERATOR)—Delphi源码示例:用于复合对象的外部迭代器
- 《GOF设计模式》—抽象工厂(Abstract Factory)—Delphi源码示例:基于原型的工厂
- 《GOF设计模式》—迭代器 (ITERATOR)—Delphi源码示例:用于复合对象的内部迭代器
- 《GOF设计模式》—适配器(ADAPTER)—Delphi源码示例:可插入的Adapter(使用代理对象)
- 《GOF设计模式》—适配器(ADAPTER)—Delphi源码示例:可插入的Adapter(使用代理对象)