对象初始化模式

时间:2015-07-07 17:15:35

标签: delphi oop design-patterns initialization

这个问题与OOP模式有关(但我正在使用delphi IDE)。 我正在开发一个库,需要对其对象进行一种内存管理(没有垃圾收集也没有引用计数)。 我正在考虑向用户公开初始化/终结方法,因为他们知道将自动调用构造/销毁方法(允许用户清理对象内存而不会破坏对象)。建议使用类似的模式或最佳做法吗?

type
  TAbstractInitializable = abstract class(TAbstractBase)
  constructor Create();
  destructor Destroy(); override;
  private
    FInitialized: Boolean;
  protected
    procedure CheckError();
    procedure DoInitialize(); virtual; abstract;
    procedure DoFinalize(); virtual; abstract;
  public
    procedure Initialize();
    procedure Finalize();
  end;

  //...

  procedure TAbstractInitializable.CheckError();
  begin
    if not FInitialized then
      raise Exception.Create('Error: Trying to use a non initialized object.');
  end;

  procedure TAbstractInitializable.Create();
  begin
    inherited;
    DoInitialize();
  end;

  procedure TAbstractInitializable.Destroy();
  begin
    DoFinalize();
    inherited;
  end;

  procedure TAbstractInitializable.Initialize();
  begin
    if not FInitialized then begin
      DoInitialize();
      FInitialized:=True;
    end;
  end;

  procedure TAbstractInitializable.Finalize();
  begin
    if FInitialized then begin
      DoFinalize();  
      FInitialized:=False;
    end;
  end;

所以这可能是一个非抽象类的库:

type
  TDataModel = class(TAbstractInitializable)
  private
    FDataList: TList;
  protected
    procedure DoInitialize(); override;
    procedure DoFinalize(); override;
  public
    procedure DoSomethingWithData();  
  end;

//...

procedure TDataModel.DoInitialize();
begin
  FDataList:=TList.Create();
  LoadData(FDataList); //for non emptyness in this example
end;

procedure TDataModel.DoFinalize();
begin
  FreeData(FDataList); //for no memory leaks in this example
  FDataList.Destroy();
end;

procedure TDataModel.DoSomethingWithData();
begin
  CheckError();
  //Do something here
end;

1 个答案:

答案 0 :(得分:0)

我不了解Delphi,但我认为使用公共方法初始化和取消初始化对象是正确的方法。例如,在任何类型的文件流对象中,您通常会看到open()close()方法。尽管它们并不总是被自动调用,但它使客户端能够显式地管理这些行为,而不是依赖于类本身来隐式初始化和清理。对于文件句柄,您不希望将文件句柄发送到垃圾收集,因为垃圾收集通常很难预测。

我不会公开您的initialize()finalize()方法。如果这些语言是为客户使用这些方法而设计的,那么它们就已经公开了,而且在我使用过的所有库中,我都没见过类似的东西。我会写两个不同名称的方法来描述你的表演行为(例如create()& destroy())。您的initialize()finalize()可以分别调用这些方法。