По мотивам:
Коротко. Ещё о фабриках
Я там писал - "фабрики, скажем так - это "полиморфизм в квадрате"".
Так вот.
Я сегодня сделал "полиморфизм в кубе".
Как?
Сделал "фабрику фабрик".
Примерно так:
Для меня лично - всё вокруг реализации IStorage вертится.
Там есть блоки "такой системы" и блоки "другой системы". А ещё есть "блоки в заголовком" и "блоки без заголовка". А ещё есть блоки "такого размера" и есть "блоки другого размера".
Вот там и возникает "Це из Эн по Ка". Которая решается "фабриками фабрик".
Может быть кому-нибудь мысль понравится.
P.S. Понятно, что тут всё "не так линейно". Конечно в реале появляются "циклы" и "списки фабрик". Особенно там где написано SomeConditionXXX.
Могу и про это детально написать. Если вдруг интересно.
Реальный пример (а не "коня в вакууме") - я тоже постараюсь описать.
Но пока может быть кому-то и "конь в вакууме" понравится.
Коротко. Ещё о фабриках
Я там писал - "фабрики, скажем так - это "полиморфизм в квадрате"".
Так вот.
Я сегодня сделал "полиморфизм в кубе".
Как?
Сделал "фабрику фабрик".
Примерно так:
type TSomeDataToDecide = record ... end;//TSomeDataToDecide TUsedBaseClass = class abstract (TObject) public constructor Create(const aSomeDataToDecide: TSomeDataToDecide); end;//TUsedBaseClass RUsedBaseClass = class of TUsedBaseClass; TUsedImpl1 = class(TBaseClass) end;//TUsedImpl1 TUsedImpl2 = class(TBaseClass) end;//TUsedImpl2 TBaseClass = class abstract (TObject) private f_Used : TUsedBaseClass; public constructor Create(aUsed: RUsedBaseClass; const aSomeDataToDecide: TSomeDataToDecide); end;//TBaseClass TImpl1 = class(TBaseClass) end;//TImpl1 TImpl2 = class(TBaseClass) end;//TImpl2 TBaseClassFactory = class abstract (TObject) public class function Make(aUsed: RUsedBaseClass; const aSomeDataToDecide: TSomeDataToDecide): TBaseClass; virtual; abstract; end;//TBaseClassFactory RBaseClassFactory = class of TBaseClassFactory; TFactory1 = class(TBaseClassFactory) public class function Make(aUsed: RUsedBaseClass; const aSomeDataToDecide: TSomeDataToDecide): TBaseClass; override; end;//TFactory1 TFactory2 = class(TBaseClassFactory) public class function Make(aUsed: RUsedBaseClass; const aSomeDataToDecide: TSomeDataToDecide): TBaseClass; override; end;//TFactory2 TBaseClassFactoryFactory = class abstract (TObject) public class function Make(const aSomeDataToDecide: TSomeDataToDecide): RBaseClassFactory; virtual; abstract; class function Used(const aSomeDataToDecide: TSomeDataToDecide): RUsedBaseClass; virtual; abstract; end;//TBaseClassFactoryFactory RBaseClassFactoryFactory = class of TBaseClassFactoryFactory; TFactoryFactory1 = class (TObject) public class function Make(const aSomeDataToDecide: TSomeDataToDecide): RBaseClassFactory; override; end;//T1FactoryFactory1 TFactoryFactory2 = class (TObject) public class function Make(const aSomeDataToDecide: TSomeDataToDecide): RBaseClassFactory; override; end;//T1FactoryFactory2 ... constructor TBaseClass.Create(aUsed: RUsedBaseClass; const aSomeDataToDecide: TSomeDataToDecide); begin f_Used := aUsed.Create(aSomeDataToDecide); ... end; ... class function TFactory1.Make(aUsed: RUsedBaseClass; const aSomeDataToDecide: TSomeDataToDecide): TBaseClass; begin if SomeCondition(aSomeDataToDecide) then Result := TImpl1.Create(aUsed, aSomeDataToDecide) else if SomeOtherCondition(aSomeDataToDecide) then Result := TImpl2.Create(aUsed, aSomeDataToDecide) else begin Assert(false); Result := nil; end; end; class function TFactory2.Make(aUsed: RUsedBaseClass; const aSomeDataToDecide: TSomeDataToDecide): TBaseClass; begin if SomeCondition(aSomeDataToDecide) then Result := TImpl2.Create(aUsed, aSomeDataToDecide) else if SomeOtherCondition(aSomeDataToDecide) then Result := TImpl1.Create(aUsed, aSomeDataToDecide) else begin Assert(false); Result := nil; end; end; ... class function TFactoryFactory1.Make(const aSomeDataToDecide: TSomeDataToDecide): RBaseClassFactory; begin if SomeCondition(aSomeDataToDecide) then Result := TFactory1 else if SomeOtherCondition(aSomeDataToDecide) then Result := TFactory2 else begin Assert(false); Result := nil; end; end; ... class function TFactoryFactory2.Make(const aSomeDataToDecide: TSomeDataToDecide): RBaseClassFactory; begin if SomeCondition(aSomeDataToDecide) then Result := TFactory2 else if SomeOtherCondition(aSomeDataToDecide) then Result := TFactory1 else begin Assert(false); Result := nil; end; end; ... var l_FF : RBaseClassFactoryFactory; l_BC : TBaseClass; l_SD : TSomeDataToDecide; begin ... l_SD := TSomeDataToDecide.Create(SomeParams); ... if SomeCondition(l_SD) then l_FF := TFactoryFactory1 else if SomeOtherCondition(l_SD) then l_FF := TFactoryFactory2 else begin Assert(false); l_FF := nil; end; l_BC := l_FF.Make(l_SD).Make(l_FF.Used(l_SD), l_SD); try ... finally FreeAndNil(l_BC): end;//try..finally end;Зачем всё это? Чтобы охватить "Це из Эн по Ка".
Для меня лично - всё вокруг реализации IStorage вертится.
Там есть блоки "такой системы" и блоки "другой системы". А ещё есть "блоки в заголовком" и "блоки без заголовка". А ещё есть блоки "такого размера" и есть "блоки другого размера".
Вот там и возникает "Це из Эн по Ка". Которая решается "фабриками фабрик".
Может быть кому-нибудь мысль понравится.
P.S. Понятно, что тут всё "не так линейно". Конечно в реале появляются "циклы" и "списки фабрик". Особенно там где написано SomeConditionXXX.
Могу и про это детально написать. Если вдруг интересно.
Реальный пример (а не "коня в вакууме") - я тоже постараюсь описать.
Но пока может быть кому-то и "конь в вакууме" понравится.
Комментариев нет:
Отправить комментарий