Вот тут был достаточно развесистый пост про подсчёт ссылок - http://18delphi.blogspot.com/2013/04/iunknown.html
Хочу обратить внимание на следующий кусок:
Следующим постом я надеюсь - доберусь до подсчёта ссылок и контейнеров.
(!)(!)(!) ДА в случае наследования от TInterfacedObject фабричный метод выглядит так:
Хочу обратить внимание на следующий кусок:
TmyReferenceCountGuard = class(TmyInterfacedObject, ImyReferenceCountGuard) {* Класс исключительно для примеров } ... public // public methods class function Make: ImyReferenceCountGuard; reintroduce; {* Фабрика TmyReferenceCountGuard.Make } end;//TmyReferenceCountGuard .... class function TmyReferenceCountGuard.Make: ImyReferenceCountGuard; var l_Inst : TmyReferenceCountGuard; begin l_Inst := Create; try Result := l_Inst; finally l_Inst.Free; end;//try..finally end;
И его использование:
procedure TmyReferenceCountGuardTest.DoIt; var l_G : ImyReferenceCountGuard; begin l_G := TmyReferenceCountGuard.Make; ...
Вне зависимости от того как реализован подсчёт ссылок - я предпочитаю пользоваться ИМЕННО фабричным методом, а не конструктором. Во-первых - его использование подчёркивает тот факт, что конструируется ИМЕННО интерфейс, а не просто объект. А во-вторых - снимается опасность использования конструктора при передаче интерфейса внутрь метода с параметром const (то что описал gunsmoker тут - http://www.gunsmoker.ru/2013/04/plugins-9.html (Неочевидная особенность учёта ссылок интерфейсов (конструктор в const-параметре))).
Да и читать мне такое приятнее/проще. А при "моём подсчёте ссылок" - ещё и скрывается лишний Free (внутрь фабричного метода).
Ну и понятное дело, что можно сделать несколько фабричных методов - для создания одним классом разных интерфейсов. И например с overload по параметрам.
Да и кеширование в фабричный метод всегда можно потом безболезненно воткнуть, или логирование, ну или бизнес-логику какую. Или например граничные условия обработать.
По мне - если бы это позволял корректно сделать компилятор - я бы вообще конструктор бы скрыл в данном конкретном случае. А так - "приходится договариваться с коллегами".
Следующим постом я надеюсь - доберусь до подсчёта ссылок и контейнеров.
(!)(!)(!) ДА в случае наследования от TInterfacedObject фабричный метод выглядит так:
class function TmyReferenceCountGuard.Make: ImyReferenceCountGuard; begin Result := Create; end;
Кстати если бы мне позволил компилятор сделать это корректно - я бы в данном случае - вообще бы спрятал бы конструктор.
ОтветитьУдалитьЭммм... А разве компилятор запрещает спрятать конструктор в protected?
УдалитьКомпилятор не запрещает. Но при этом будет виден конструктор от TObject.
ОтветитьУдалитьМожете проверить.