Один подход:
Public
Property CreatedOK: boolean read fCreatedOK;
constructor TSomeComponent.Create(AOwner: TComponent);
begin
...
fCreatedOK := ThereIsAnIncompatibleCondition;
end;
Затем программист создает объект следующим образом:
MyObject := TSomeComponent.Create(Self);
if (NOT MyObject.CreatedOK) then
... deal with it...
Мы предпочитаем это, потому что он избегает большого количества кода исключения, который может быть громоздким, ихлопоты при отладке.(Это еще одна тема!)
Другой подход, который мы используем, - если у конструктора много работы, переместите работу в другой метод, который пользователь должен вызвать после создания.Это также имеет то преимущество, что позволяет нам легко передавать многие значения объекту.
public
constructor Create...
function InitAfterCreate:boolean;
end;
Вызывающая сторона делает:
MyObject := TSomeComponent.Create
if (NOT MyObject.InitAfterCreate) then
... deal with it ...
или, если вы используете InitAfterCreate для передачи значений,вы бы определили его как
function InitAfterCreate( Value1: Integer, etc.):boolean
Затем InitAfterCreate может проверить состояние объекта и вернуть результат.
Одна из слабых сторон этих подходов заключается в том, что программист должен помнить, чтобы вызыватьInitAfterCreate или проверьте MyObject.CreatedOk.Чтобы защититься от того, что они этого не сделают, вы можете поместить некоторые Asserts в начало некоторых других методов вашего объекта, таких как:
procedure TForm.FormShow
begin
Assert(fCreatedOK, "Programmer failed to check creation result.")
...
end;
Во всех случаях одна из проблем состоит в том, чтобы не завершать Create, оставляя объектнаполовину созданный, в неопределенном состоянии, из-за которого вашему деструктору будет трудно понять, сколько нужно уничтожить.