在Delphi 7中更改构造函数参数的对象工厂

时间:2016-02-20 18:37:16

标签: delphi

我有类似的问题。

IBase = interface
end;

TObjectType = ( otUnknown, otDesc1, otDesc2 );

TBase = class ( TInterfacedObject, IBase )
  private
    fType : TObjectType;
  public
    constructor create( type_ : TObjectType );
end;

TDesc1 = class ( TBase )
  public
    constructor create;
end;

TDesc2 = class ( TBase )
  public
    constructor create;
end;

TObjectFactory = class
  public
    function createInstance( key_ : string ) : IBase; virtual; abstract;
end;

TMyObjectFactory = class ( TObjectFactory )
  private
    fRegisteredTypes : TStringList;
  public
    function createInstance( key_ : string ) : IBase; override;

end;

EUnregisteredType = class ( Exception )
end;

constructor TBase.create( type_ : TObjectType );
begin
  inherited create;
  fType := type_;
  //...
end;

constructor TDesc1.create;
begin
  inherited create( otDesc1 );
  //...
end;

constructor TDesc2.create;
begin
  inherited create( otDesc2 );
  //...
end;

function TMyObjectFactory.createInstance( key_ : string ) : IBase;
var
  ndx : integer;
begin
  ndx := fRegisteredTypes.indexOf( key_ );
  if ( ndx > -1 ) then
    result := TBase( fRegisteredTypes.objects[ndx] ).create 
  else
    raise EUnregisteredType.create( key_ );
end;

当我阅读实现抽象工厂设计模式时,我应该创建动态构造函数并在后代中覆盖它。但我的构造函数参数在后代(而不是任何)中有所不同,因此无法覆盖。在这种情况下,对抽象工厂模式还是原型设计模式有什么办法吗?

1 个答案:

答案 0 :(得分:1)

要执行您正在尝试的操作,您需要使用虚拟构造函数,这意味着您不能在祖先和派生构造函数中使用不同的参数。但是,您可以使fX成员受到保护而不是私有,因此派生的构造函数可以直接访问它。

尝试更像这样的事情:

type
  X = (x1, x2, ...);

  TBase = class ( TInterfacedObject, IBase )
  protected
    fX : X;
  public
    constructor Create; virtual;
  end;

  TBaseClass = class of TBase;

  TDesc1 = class ( TBase )
  public
    constructor Create; override;
  end;

  TDescr2 = class ( TBase )
  public
    constructor Create; override;
  end;

  TObjectFactory = class
  private
    fRegisteredTypes : TStringList;
  public
    function createInstance( key_ : string ) : IBase;
    ...
  end;

...

constructor TBase.Create;
begin
  inherited Create;
  ...
end;

constructor TDesc1.Create;
begin
  inherited Create;
  fX := x1;
  ...
end;

constructor TDesc2.Create;
begin
  inherited Create;
  fX := x2;
  ...
end;

function TObjectFactory.createInstance( key_ : string ) : IBase;
var
  ndx : Integer;
begin
  ndx := fRegisteredTypes.indexOf( key_ );
  if ( ndx = -1 ) then
    raise EUnregisteredType.Create( key_ );
  Result := TBaseClass( fRegisteredTypes.objects[ndx] ).Create;
end;