《GOF设计模式》—原型(Prototype)—Delphi源码示例:基于类的原型管理器(使用TList实现)

示例:基于类的原型管理器(使用TList实现)

实现:

应用程序启动时自动注册每个类,并用类管理器来管理这个注册类。然后应用程序从配置文件中获取动态装载类的信息,并向类管理器请求该注册类以创建实例,这些类原本并没有和程序相连接。

代码:

unit uClassManager1;

 

interface

 

uses

    SysUtils,Classes,Dialogs;

 

type

    TBaseObjectClass = class of TBaseObject;

 

    TBaseObject = class

    public

        procedure Show; virtual; abstract;

    end;

    TObjectA = class(TBaseObject)

    public

        procedure Show; override;

    end;

    TObjectB = class(TBaseObject)

    public

        procedure Show; override;

    end;

 

    TClassInfo = record

        ClassName: string;

        ObjectClass: TBaseObjectClass;

    end;

    PClassInfo = ^TClassInfo;

 

    TClassList = class

    private

        FDataList: TList;

        function GetItems(Index: integer): PClassInfo;

    public

        constructor Create;

        destructor Destroy; override;

        //---

        procedure Clear;

        function IndexOf(const AClassName: string): integer;

        procedure Add(const AClassName: string; const AClass: TBaseObjectClass);

        procedure Delete(const AIndex: integer);

        //---

        property Items[Index: integer]: PClassInfo read GetItems; default;

    end;

 

    TClassManager = class

    private

        FClassList: TClassList;

    public

        constructor Create;

        destructor Destroy; override;

        //---

        procedure RegisterClass(const AClassName: string; AClass: TBaseObjectClass);

        procedure UnregisterClass(const AClassName: string);

        function Registered(const AClassName: string): Boolean;

        function GetClass(const AClassName: string): TBaseObjectClass;

    end;

 

procedure RegisterClass(const AClassName: string; AClass: TBaseObjectClass);

function GetClass(const AClassName: string): TBaseObjectClass;

 

implementation

 

var

    ClassManager: TClassManager;

 

function GetClass(const AClassName: string): TBaseObjectClass;

begin

    Result := ClassManager.GetClass(AClassName);

end;

 

procedure RegisterClass(const AClassName: string; AClass: TBaseObjectClass);

begin

    ClassManager.RegisterClass(AClassName,AClass);

end;

 

procedure TObjectA.Show;

begin

    showmessage('这是ObjectA');

end;

 

procedure TObjectB.Show;

begin

    showmessage('这是ObjectB');

end;

 

constructor TClassList.Create;

begin

    inherited;

    //---

    FDataList := TList.Create;

end;

 

destructor TClassList.Destroy;

begin

    Clear;

    FDataList.Free;

    //---

    inherited;

end;

 

procedure TClassList.Clear;

var

    i: Integer;

    pData: PClassInfo;

begin

    with FDataList do

    begin

        for i := 0 to Count - 1 do

        begin

            pData := Items[i];

            dispose(pData);

        end;

        //---

        Clear;

    end;

end;

 

procedure TClassList.Add(const AClassName: string; const AClass:

    TBaseObjectClass);

var

    pData: PClassInfo;

begin

    new(pData);

    //---

    with pData^ do

    begin

        ClassName := AClassName;

        ObjectClass := AClass;

    end;

    //---

    FDataList.Add(pData);

end;

 

function TClassList.IndexOf(const AClassName: string): integer;

var

    i: integer;

    pData: PClassInfo;

begin

    with FDataList do

    begin

        for i := 0 to Count - 1 do

        begin

            pData := Items[i];

            if pData.ClassName = AClassName then

            begin

                Result := i;

                exit;

            end;

        end;

    end;

    //---

    Result := -1;

end;

 

procedure TClassList.Delete(const AIndex: integer);

var

    pData: PClassInfo;

begin

    with FDataList do

    begin

        if (AIndex >= 0) and (AIndex < Count) then

        begin

            pData := Items[AIndex];

            dispose(pData);

            //---

            Delete(AIndex);

        end;

    end;

end;

 

function TClassList.GetItems(Index: integer): PClassInfo;

begin

    Result := FDataList[Index];

end;

 

constructor TClassManager.Create;

begin

    FClassList := TClassList.Create;

end;

 

destructor TClassManager.Destroy;

begin

    FClassList.Free;

    //---

    inherited;

end;

 

function TClassManager.GetClass(const AClassName: string): TBaseObjectClass;

var

    AIndex: Integer;

begin

    AIndex := FClassList.IndexOf(AClassName);

    if AIndex >= 0 then

        Result := FClassList[AIndex].ObjectClass

    else

        Result := nil;

end;

 

procedure TClassManager.RegisterClass(const AClassName: string; AClass: TBaseObjectClass);

var

    LClassName: string;

begin

    if Registered(AClassName) then

        raise Exception.CreateFmt('A class named %s already exists', [LClassName])

    else

        FClassList.Add(AClassName,AClass);

end;

 

function TClassManager.Registered(const AClassName: string): Boolean;

begin

    Result := FClassList.IndexOf(AClassName) >= 0;

end;

 

procedure TClassManager.UnregisterClass(const AClassName: string);

var

    AIndex: Integer;

begin

    AIndex := FClassList.IndexOf(AClassName);

    if AIndex >= 0 then

        FClassList.Delete(AIndex);

end;

 

initialization

    ClassManager := TClassManager.Create;

    RegisterClass('TObjectA',TObjectA);

    RegisterClass('TObjectB',TObjectB);

 

finalization

    ClassManager.Free;

end.

 

procedure TForm1.Button1Click(Sender: TObject);

var

    AObject: TBaseObject;

    //---

    function GetClassNameFromIni:string;

    begin

        Result := 'TObjectA';

    end;

begin

    AObject := GetClass(GetClassNameFromIni).Create;

    try

        AObject.Show;

    finally

        AObject.Free;

    end;

end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值