Создание фабричной функции для иерархии классов в Delphi с использованием виртуальных функций
Вопрос, поднятый в контексте, заключается в создании фабричной функции для иерархии классов в Delphi, где каждый класс соответствует определенному потомку TComponent. Автор хочет избежать использования каскада if-else или RTTI для создания экземпляров классов. Предложено решение с использованием регистрации классов, но в контексте статьи мы рассмотрим создание фабричной функции с использованием виртуальных функций.
Шаг 1: Определение базового интерфейса
Сначала определим базовый интерфейс IFrobber, который будет использоваться всеми классами иерархии:
type
IFrobber = interface
end;
Шаг 2: Создание базового класса TComponentFrobber
Базовый класс TComponentFrobber будет реализовывать интерфейс IFrobber и содержать виртуальную функцию для создания экземпляра:
type
TComponentFrobber = class(TInterfacedObject, IFrobber)
private
FComponent: TComponent;
protected
constructor Create(AComponent: TComponent);
property Component: TComponent read FComponent;
public
function CreateFrobberInstance(AComponent: TComponent): TComponentFrobber; virtual; abstract; overload;
end;
Шаг 3: Реализация виртуальной функции в производных классах
Производные классы, такие как TActionFrobber и TMenuItemFrobber, должны реализовать виртуальную функцию CreateFrobberInstance, создавая соответствующие экземпляры:
type
TActionFrobber = class(TComponentFrobber)
public
function CreateFrobberInstance(AComponent: TComponent): TActionFrobber; virtual; overload;
end;
TMenuItemFrobber = class(TComponentFrobber)
public
function CreateFrobberInstance(AComponent: TComponent): TMenuItemFrobber; virtual; overload;
end;
implementation
function TActionFrobber.CreateFrobberInstance(AComponent: TComponent): TActionFrobber;
begin
Result := TActionFrobber.Create(TCustomAction(AComponent));
end;
function TMenuItemFrobber.CreateFrobberInstance(AComponent: TComponent): TMenuItemFrobber;
begin
Result := TMenuItemFrobber.Create(TMenuItem(AComponent));
end;
Шаг 4: Создание фабричной функции
Теперь, когда у нас есть виртуальная функция CreateFrobberInstance, мы можем создать фабричную функцию, которая будет вызывать эту функцию для создания экземпляра:
function CreateFrobber(AComponent: TComponent): IFrobber;
begin
Result := TComponentFrobber(AComponent as TComponentFrobber).CreateFrobberInstance(AComponent);
end;
Этот код использует оператор as для приведения типа AComponent к соответствующему производному классу, который затем вызывает реализацию CreateFrobberInstance.
Заключение
Использование виртуальных функций позволяет создать гибкую фабричную функцию, которая не зависит от конкретных классов иерархии и может быть расширена без изменения исходного кода фабрики. Это также упрощает тестирование и поддержку кода, поскольку логика создания объектов централизована в одном месте.
Контекст заключается в создании фабричной функции для иерархии классов в Delphi, использующей виртуальные функции для обеспечения гибкости и удобства создания объектов без прямого использования условий и RTTI.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.