Классы-хелперы против циклических зависимостей


Есть два юнита, которые ссылаются друг на друга в интерфейсной части:

unit Unit1;

interface

type
  TA = class(TObject)
  public
     BB: TObject;
  end;

implementation

uses UnitClassHelper;

и Unit2:

unit Unit2;

interface

type
  TB = class(TObject)
  public
     AA: TObject;
  end;

implementation

uses UnitClassHelper;

Чтобы разрешить циклическую зависимость между этими классами,
нужно сделать класс-хелпер (или два класса, если отношения
присваивания будут бинаправленными)

unit UnitClassHelper;

interface

uses Unit1, Unit2;

type
  TAHelper = class helper for TA
    private
      function GetTB: TB;
      procedure SetTB(obj: TB);
    public
      property BB: TB read GetTB write SetTB;
  end;

type
  TBHelper = class helper for TB
    private
      function GetTa: TA;
      procedure SetTa(obj : TA);
    public
      property AA: TA read GetTA write SetTA;
  end;

implementation

function TaHelper.GetTB: TB;
begin
  Result:= Self.BB;
end;

procedure TaHelper.SetTb(obj: TB);
begin
  Self.BB:= obj;
end;

function TbHelper.GetTA: TA;
begin
  Result:= Self.AA;
end;

procedure TbHelper.SetTa(obj: TA);
begin
  Self.AA:= obj;
end;

end.

Внутри главной программы классы-хелперы используются НЕЯВНО:

program Test;

uses
  Unit1 in 'Unit1.pas',
  Unit2 in 'Unit2.pas',
  UnitClassHelper in 'UnitClassHelper.pas';

var
  AObj : TA;
  BObj : TB;

begin
  try
    AObj:= TA.Create;
    BObj:= TB.Create;

    AObj.BB:= BObj;
    BObj.AA:= AOBj;
    // Do something

  finally
    AObj.Free;
    BObj.Free;
  end;
end.

Вся фишка этой системы в том, что в основных классах объекты
приводятся к типу TObject, а в классах-хелперах через
сеттеры-геттеры типы уточняются до необходимых, что позволяет
избежать явного преобразования типов в дальнейшем.