Вопрос по constructor, record, delphi – Delphi: конструктор записей и функция фабрики

17

Итак, что будет предпочтительным способом инициализации записей?

С «заводской функцией»:

TMyRecord = record
  valueX: integer;
  valueY: integer;
end;

function MyRecord(const AValueX, AValueY: integer): TMyRecord;
begin
  result.valueX := AValueX;
  result.valueY := AValueY;
end;

var
  myrec: TMyRecord;
begin
  myrec := MyRecord(1, 2);
end;

или конструктор:

TMyRecord = record
  valueX: integer;
  valueY: integer;
  constructor Create(const AValueX, AValueY: integer);
end;

constructor TMyRecord.Create(const AValueX, AValueY: integer);
begin
  self.valueX := AValueX;
  self.valueY := AValueY;
end;

var
  myrec: TMyRecord;
begin
  myrec := TMyRecord.Create(1, 2);
end;

Я чувствую, что конструктор более инкапсулирован, но при чтении кода легко запутаться. Это делает его похожим на класс, в котором отсутствует призыв к бесплатному. Это также больше, чтобы напечатать ...

Почему вы предпочитаете один другому?

Ваш Ответ

4   ответа
1

В проекте Delphi, который я создал, я использовал записи вместо классов, чтобы уменьшить количество накладных расходов в списке. У меня будет несколько сотен записей в динамическом массиве, поэтому я создал две записи. Первая запись была для самого предмета. Поля были сделаны закрытыми (да, вы можете использовать личные / защищенные с записями) и добавили свойства только для чтения в открытый раздел. Также был добавлен дополнительный конструктор для правильной инициализации записи. Эта настройка позволила мне защитить содержимое этой записи от других разработчиков. Вторая запись была просто оберткой вокруг динамического массива предыдущего типа записи. Массив будет закрытым, и я добавил методы для получения, добавления и удаления записей в этом списке. В результате весь список защищен от неправильного использования другими разработчиками, а также имеет гораздо меньше накладных расходов, чем обычное решение TList / TObjectList.

Имейте в виду, что записи не являются классами. Вы не можете наследовать конструкторы и другие методы. Они имеют меньшую функциональность, чем настоящие классы в средах WIN32. В .NET они просто снова повышены до классов. И не очень полезно использовать конструктор add, когда разработчики могут легко изменять содержимое каждого поля в вашей записи. Вместо этого вы должны использовать конструкторы для защиты этих полей.

0

Я обычно не создаю конструкторы для записей. Он не совместим со всеми версиями (и FPC). Более того, как правило, они используются только в одном месте, и часто достаточно заполнителя.

Немного сложно использовать FillChar () для инициализации записи значениями, не так ли? Vegar
11

Я предпочитаю классы, но если мне нужно использовать записи, мне нравится относиться к ним как можно ближе к классам. Поэтому я использую конструктор записей.

Но есть досадная ошибка с записями и единицами. Если функция возвращает запись (с методами), она выдает внутреннюю ошибку, если вы хотите получить доступ к этим методам. Вы можете обойти это, назначив его другой переменной:

type 
  TMyRec = record
    ..
    procedure X;
  end;


function GetRec: TMyRec;



procedure Test;
var
  r1, r2 : TMyRec;
begin
  r1 := GetRec;
  r1.X; // internal error
  r2 := r1;
  r2.X; // No internal error;
К вашему сведению, проблема с внутренней ошибкой, о которой вы упоминали, по-видимому, исправлена в D2010.
Я также использую конструкторы записей. Вы можете назвать это как-то иначе, чем & quot; Создать & quot; если вам нравится, значит, вы знаете, что это запись.
Вопрос о конструкторе, а не только о методе. Если мы будем следовать той же записи для конструктора, то из кода будет трудно понять, является ли это записью или экземпляром класса. Для класса это означает утечку памяти, поэтому любой, кто увидит этот код, должен будет проверить, действительно ли это запись или класс. Так что я думаю, что это плохой путь.
2

Я предпочел бы "фабричный метод" лайк

  function TMyRecord.CreateRec(const AValueX, AValueY: integer): TMyRecord;

Отдельные фабричные функции утечек инкапсуляции и конструкторы записей просто запутывают ИМХО.

Похожие вопросы