Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Разработка универсальной фабрики классов с общим предком в Delphi

Delphi , Компоненты и Классы , RTTI

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

Проблема создания нового экземпляра класса

Рассмотрим типичную ситуацию, когда у нас есть список объектов различных классов, которые имеют общий предок. Нам необходимо создать новый экземпляр класса, не зная заранее, какого именно класса. Пример кода, который не следует "Open/Closed Principle", представлен ниже:

case MyObjectTypeInstance.MyTypeEnum of
  obj1:
    Result := TObjectType1.Create;
  obj2:
    Result := TObjectType2.Create;
  obj3:
    Result := TObjectType3.Create;
end;

Копирование данных членов класса - задача простая, но создание нового объекта вызывает затруднения. Интуитивно кажется, что можно использовать Result := MyObjectTypeInstance.Create;, но это не работает по ряду причин, включая проблемы с деструкторами.

Решение с использованием 'class of'

Один из способов решения этой проблемы - использование переменных 'class of'. Пример кода:

type
  TBaseObj = class
  end;
  TObjA = class(TBaseObj)
  end;
  TBaseObjClass = class of TBaseObj;

var
  objCls: TBaseObjClass;
  obj: TBaseObj;

objCls := TObjA;
obj := objCls.Create;

Таким образом, obj будет экземпляром класса TObjA.

Регистрация классов

Можно создать систему регистрации классов, которая позволит создавать экземпляры на основе идентификатора класса:

type
  TAncestor = class
  public
    constructor Create; virtual;
    class function CreateClass(const AId: string): TAncestor;
    class procedure RegisterClass(const AId: string; const AType: TAncestorClass);
  end;

class function TAncestor.CreateClass(const AId: string): TAncestor;
begin
  // Логика создания экземпляра на основе идентификатора
end;

class procedure TAncestor.RegisterClass(const AId: string; const AType: TAncestorClass);
begin
  // Регистрация класса по идентификатору
end;

Применение абстрактной фабрики

Одним из решений может быть применение паттерна проектирования "Абстрактная фабрика" или "Factory Method". Это проверенные и эффективные подходы в разработке программного обеспечения.

Реализация через метод класса

Также можно добавить метод в базовый класс, который создаст новый экземпляр текущего класса:

type
  TFoo = class
  public
    class function MakeAnother: TFoo;
  end;

  TFoo1 = class(TFoo)
  end;

  TFoo2 = class(TFoo)
  end;

class function TFoo.MakeAnother: TFoo;
begin
  Result := Create;
end;

Заключение

Для создания универсальной фабрики классов с общим предком в Delphi можно использовать различные подходы, включая регистрацию классов и применение паттернов проектирования. Выбор конкретного метода зависит от требований проекта и предпочтений разработчика. Важно помнить о гибкости и возможности расширения системы без изменения существующего кода (Open/Closed Principle).

Создано по материалам из источника по ссылке.

Вопрос касается создания универсальной фабрики классов в Delphi с общим предком, позволяющей создавать экземпляры различных классов без необходимости знать их конкретный тип.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: RTTI ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 20:56:35/0.0032010078430176/0