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

Как создавать классы с множеством полей в Delphi: Использование сеттеров и геттеров, а также объявление записей внутри классов

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

 

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

Основы работы со свойствами в классах

Свойства (properties) в Delphi предоставляют удобный способ доступа к данным класса, позволяя скрыть реализацию и добавить дополнительную логику при чтении или записи значений.

Рассмотрим базовый пример класса с одним полем:

type
  TEmployee = class
  private
    FName: string;
    function GetName: string;
    procedure SetName(const Value: string);
  public
    property Name: string read GetName write SetName;
  end;

implementation

function TEmployee.GetName: string;
begin
  Result := FName;
end;

procedure TEmployee.SetName(const Value: string); 
begin
  if Value = '' then
    raise Exception.Create('Name must have a value');
  FName := Value;
end;

В этом примере мы видим: - Приватное поле FName для хранения данных - Методы GetName и SetName для доступа к полю - Публичное свойство Name, которое использует эти методы

Проблема множества полей

Когда в классе много полей (например, 50), написание отдельных геттеров и сеттеров для каждого становится утомительным. Рассмотрим возможные решения.

Решение 1: Прямой доступ к полям

Если ваши поля не требуют дополнительной логики при чтении/записи, можно сделать их публичными:

type
  TEmployee = class
  public
    Name: string;
    Salary: Currency;
    // и другие поля
  end;

Преимущества: - Простота реализации - Нет необходимости в дополнительных методах

Недостатки: - Невозможно добавить проверки при установке значений - Меньшая гибкость для будущих изменений

Решение 2: Прямое связывание свойств с полями

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

type
  TEmployee = class
  private
    FName: string;
    FSalary: Currency;
  public
    property Name: string read FName write FName;
    property Salary: Currency read FSalary write FSalary;
  end;

Этот подход сохраняет возможность в будущем добавить методы доступа, не меняя интерфейс класса.

Решение 3: Индексированные свойства

Если поля однотипные, можно использовать индексированные свойства:

type
  TEmployee = class
  private
    FNames: array[0..49] of string;
    function GetName(Index: Integer): string;
    procedure SetName(Index: Integer; const Value: string);
  public
    property Names[Index: Integer]: string read GetName write SetName;
  end;

implementation

function TEmployee.GetName(Index: Integer): string;
begin
  Result := FNames[Index];
end;

procedure TEmployee.SetName(Index: Integer; const Value: string); 
begin
  if Value = '' then
    raise Exception.Create('Value must not be empty');
  FNames[Index] := Value;
end;

Решение 4: Использование констант для индексов

Для разнотипных полей можно использовать константы и один метод доступа:

const
  NameIndex = 0;
  SalaryIndex = 1;

type
  TEmployee = class
  private
    FValues: array[0..49] of string;
    function GetValue(Index: Integer): string;
    procedure SetValue(Index: Integer; const Value: string);
  public
    property Name: string index NameIndex read GetValue write SetValue;
    property Salary: string index SalaryIndex read GetValue write SetValue;
  end;

Решение 5: Обобщенные методы (Generics)

В современных версиях Delphi можно использовать Generics для создания универсальных методов доступа:

type
  TEmployee = class
  private
    FName: string;
    FSalary: Currency;
    FAcNo: Integer;
    function Gett<T>(var Field: T): T;
    procedure Sett<T>(var Field: T; const Value: T);
  public
    property Name: string read FName write SetName;
    procedure SetName(const Value: string);
  end;

implementation

function TEmployee.Gett<T>(var Field: T): T;
begin
  Result := Field;
end;

procedure TEmployee.Sett<T>(var Field: T; const Value: T);
begin
  var lComparer := TEqualityComparer<T>.Default;
  if lComparer.Equals(Value, Default(T)) then
    raise Exception.Create('Field must have a non-default value')
  else
    Field := Value;
end;

procedure TEmployee.SetName(const Value: string);
begin
  Sett<string>(FName, Value);
end;

Объявление записей внутри классов

Delphi позволяет объявлять записи (records) внутри классов, что может быть полезно для группировки связанных полей:

type
  TEmployee = class
  private
    FPersonalDetails: record
      FirstName: string;
      LastName: string;
      BirthDate: TDate;
    end;
    FWorkDetails: record
      Position: string;
      Department: string;
      HireDate: TDate;
    end;
  public
    type
      TContactInfo = record
        Phone: string;
        Email: string;
        Address: string;
      end;
    var
      Contact: TContactInfo;
  end;

Такой подход улучшает организацию кода и делает его более читаемым.

Рекомендации по проектированию классов

  1. Принцип минимального доступа: Делайте поля приватными, предоставляя доступ только через свойства.
  2. Группировка полей: Объединяйте связанные поля в записи или вложенные классы.
  3. Инициализация в конструкторе: Для обязательных полей устанавливайте значения в конструкторе.
  4. Использование свойств: Свойства предоставляют гибкость для будущих изменений.
  5. Документирование: Комментируйте назначение каждого поля и свойства.

Пример комплексного класса

type
  TEmployee = class
  private
    FBasicInfo: record
      FName: string;
      FEmail: string;
      FPhone: string;
    end;
    FFinancialInfo: record
      FSalary: Currency;
      FBankAccount: string;
      FTaxCode: string;
    end;
    function GetName: string;
    procedure SetName(const Value: string);
    function GetEmail: string;
    procedure SetEmail(const Value: string);
  public
    constructor Create(const Name, Email: string);
    property Name: string read GetName write SetName;
    property Email: string read GetEmail write SetEmail;
    property Phone: string read FBasicInfo.FPhone write FBasicInfo.FPhone;
    property Salary: Currency read FFinancialInfo.FSalary write FFinancialInfo.FSalary;
  end;

implementation

constructor TEmployee.Create(const Name, Email: string);
begin
  inherited Create;
  SetName(Name);
  SetEmail(Email);
end;

function TEmployee.GetName: string;
begin
  Result := FBasicInfo.FName;
end;

procedure TEmployee.SetName(const Value: string);
begin
  if Value = '' then
    raise Exception.Create('Name cannot be empty');
  FBasicInfo.FName := Value;
end;

function TEmployee.GetEmail: string;
begin
  Result := FBasicInfo.FEmail;
end;

procedure TEmployee.SetEmail(const Value: string);
begin
  if not Value.Contains('@') then
    raise Exception.Create('Invalid email format');
  FBasicInfo.FEmail := Value;
end;

Заключение

При работе с классами, содержащими множество полей, важно выбрать подход, который обеспечивает баланс между удобством разработки и гибкостью к изменениям. Использование свойств, группировка полей в записи и применение современных возможностей Delphi, таких как Generics, помогут создать поддерживаемый и расширяемый код.

Помните, что нет единственно правильного решения - выбор подхода зависит от конкретных требований вашего проекта. Начинайте с простых решений и усложняйте их только тогда, когда это действительно необходимо.

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

Статья описывает различные подходы к созданию классов с множеством полей в Delphi, включая использование свойств, сеттеров и геттеров, а также группировку полей в записи для улучшения организации кода.


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

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




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


:: Главная :: Классы ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-06-04 06:11:33/0.0059719085693359/0