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

《GOF设计模式》—适配器(ADAPTER)—Delphi源码示例:可插入的Adapter(使用代理对象)

2010-11-13 15:24 651 查看
示例:可插入的Adapter(使用代理对象)
实现:
b)、使用代理对象
在这种方法中,TreeDisplay将访问树结构的请求转发到代理对象。TreeDisplay的客户进行一些选择,并将这些选择提供给代理对象,这样客户就可以对适配加以控制,如下图所示。



例如,有一个DirectoryBrowser,它像前面一样使用TreeDisplay。DirectoryBrowser可能为匹配TreeDisplay和层次目录结构构造出一个较好的代理。在Smalltalk或ObjectiveC这样的动态类型语言中,该方法只需要一个接口对适配器注册代理即可。然后TreeDisplay简单地将请求转发给代理对象。
在C++这样的静态类型语言中,需要一个代理的显式接口定义。我们将TreeDisplay需要的窄接口放入纯虚类TreeAccessorDelegate中,从而指定这样的一个接口。然后我们可以运用继承机制将这个接口融合到我们所选择的代理中—这里我们选择DirectoryBrowser。如果DirectoryBrowser没有父类我们将采用单继承,否则采用多继承。这种将类融合在一起的方法相对于引入一个新的TreeDisplay子类并单独实现它的操作的方法要容易一些。

代码:



unit uTreeDisplay1;

interface

uses
Classes;

type
PNodes = ^TNodes;

TNode = record
Text: string;
Child: PNodes;
end;
TNodes = array of TNode;

TFileDirs = array of string;

TTreeAccessorDelegate = class;
TFileSystemEntity = class;

TTreeDisplay = class
private
FDelegate: TTreeAccessorDelegate;
FList: TStringList;
procedure SetDelegate(const Value: TTreeAccessorDelegate);
procedure AddGraphiNode(const n: string);
public
constructor Create;
destructor Destroy; override;
//---
function Display: string;
procedure BuildTree(n: TNode);
//---
property Delegate: TTreeAccessorDelegate write SetDelegate;
end;

TTreeAccessorDelegate = class
public
procedure GetChildren(TreeDisplay: TTreeDisplay; var n: TNode); virtual; abstract;
function CreateGraphiNode(TreeDisplay: TTreeDisplay; n: TNode): string; virtual; abstract;
end;

TDirectoryBrowser = class(TTreeAccessorDelegate)
private
FEntity: TFileSystemEntity;
public
constructor Create(AEntity: TFileSystemEntity);
//---
function CreateGraphiNode(TreeDisplay: TTreeDisplay; n: TNode): string; override;
procedure GetChildren(TreeDisplay: TTreeDisplay; var n: TNode); override;
procedure CreateFile;
procedure DeleteFile;
end;

TFileSystemEntity = class
function GetSubclasses(const ADir: string): TFileDirs;
end;

implementation

constructor TTreeDisplay.Create;
begin
FList := TStringList.Create;
end;

destructor TTreeDisplay.Destroy;
begin
FList.Free;
//---
inherited;
end;

procedure TTreeDisplay.BuildTree(n: TNode);
var
i: integer;
begin
FDelegate.GetChildren(self,n);
if n.Child <> nil then
begin
for i := low(n.Child^) to high(n.Child^) do
begin
AddGraphiNode(FDelegate.CreateGraphiNode(self,n.Child^[i]));
BuildTree(n.Child^[i]);
end;
//---
Dispose(n.Child);
n.Child := nil;
end;
end;

procedure TTreeDisplay.AddGraphiNode(const n: string);
begin
FList.Add(n);
end;

function TTreeDisplay.Display: string;
begin
result := FList.Text;
end;

procedure TTreeDisplay.SetDelegate(const Value: TTreeAccessorDelegate);
begin
FDelegate := Value;
end;

function TFileSystemEntity.GetSubclasses(const ADir: string): TFileDirs;
begin
if ADir = 'a' then
begin
SetLength(Result,2);
//---
Result[0] := '123';
Result[1] := '456';
end
else
SetLength(Result,0);
end;

constructor TDirectoryBrowser.Create(AEntity: TFileSystemEntity);
begin
inherited Create;
//---
FEntity := AEntity;
end;

procedure TDirectoryBrowser.CreateFile;
begin

end;

function TDirectoryBrowser.CreateGraphiNode(TreeDisplay: TTreeDisplay; n: TNode): string;
begin
Result := n.Text;
end;

procedure TDirectoryBrowser.DeleteFile;
begin

end;

procedure TDirectoryBrowser.GetChildren(TreeDisplay: TTreeDisplay; var n: TNode);
var
ADirs: TFileDirs;
i: integer;
begin
if n.Child <> nil then
begin
Dispose(n.Child);
n.Child := nil;
end;
//---
ADirs := FEntity.GetSubclasses(n.Text);
if length(ADirs) > 0 then
begin
new(n.Child);
//---
setlength(n.Child^,length(ADirs));
for i := low(n.Child^) to high(n.Child^) do
n.Child^[i].Text := ADirs[i];
end;
end;

end.

procedure TForm1.Button1Click(Sender: TObject);
var
AEntity: TFileSystemEntity;
ADelegate:TTreeAccessorDelegate;
ATree:TTreeDisplay;
n: TNode;
begin
AEntity:= TFileSystemEntity.Create;
ADelegate := TDirectoryBrowser.Create(AEntity);
ATree := TTreeDisplay.Create;
try
ATree.Delegate := ADelegate;
//---
n.Text := 'a';
n.Child := nil;
//---
ATree.BuildTree(n);
self.Memo1.Text := ATree.Display;
finally
ATree.Free;
AEntity.Free;
ADelegate.Free;
end;
end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐