Использование имущества против геттеров/сеттеров в бизнес-классах

При работе с классами бизнес-класса, такими как типичные классы клиентов и сотрудников, лучше ли использовать только геттеры и сеттеры или использовать свойства?

Я переводил в Delphi (для самостоятельного изучения) некоторые примеры OO из java-книг, в этих примерах всегда есть GetName() и SetName(), свойства не используются.

Теперь я вижу, что если я создаю компонент с опубликованными свойствами, у меня есть веская причина для использования свойств, но в обычных классах, какой подход лучше? Является ли код более читаемым с помощью геттеров и сеттеров (которые подчеркивают тот факт, что мы читаем/записываем свойство) или со свойствами (которые на первый взгляд можно путать с беспараметрированными методами)?

Ответы

Ответ 1

Нет. Getters и seters доступны только на Java, потому что у него нет свойств. Это позволяет использовать более чистый код для использования свойств. И тогда, если вам нужен геттер или сеттер, вы можете создать его в свойстве, но вам не нужно замаскировать код доступа кучей вызовов функций.

Ответ 2

Ого. Для свойств намного больше, чем "они просто обертки для методов getter и setter".

Свойства - это элегантный, но мощный способ провоцировать контролируемый доступ к полям класса.

Доступ к полям

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

TMyClass = class
private
  FValue: String;
public
  property Value: String read FValue write FValue;
end; 

Позже вы можете перепроектировать свой класс для проверки и управления доступом к полю с помощью методов. Открытый интерфейс будет по-прежнему тем же.

TMyClass = class
private
  FValue: String;
  procedure SetValue(AValue: String);
public
  property Value: String read FValue write SetValue;
end; 

procedure TMyClass.SetValue(AValue: String);
begin
  if AValue = '' 
  then FValue := 'No value!'
  else FValue := AValue;
end;

Управление доступом

Свойства дают вам простой обзор полей readonly/writeonly. Например. класс readonly/immutable:

TClient = class
private
  FName: String;
  FSite: String;
  FMail: String;
public
  constructor Create(AName, ASite, AMail: String);
  property Name: String read FName;
  property Site: String read FSite;
  property Mail: String read FMail;
end; 

Полиморфизм

TClient = class
private
  FName: String;
protected
  function GetName: String; virtual; abstract;
public
  property Name: String read GetName write FName;
end; 

TImportantClient = class(TClient)
protected
  function GetName: String; override;
end; 

TArgumentativeClient = class(TClient)
protected
  function GetName: String; override; 
end; 

function TImportantClient.GetName: String; 
begin
  Result := '+++ ' + FName;
end; 

function TArgumentativeClient.GetName: String; 
begin
  Result := ':-( ' + FName;
end; 

{----- ----- ----- ----- -----}
var
  ClientA,
  ClientB: TClient;
begin
  ClientA := TImportantClient.Create;
  ClientB := TArgumentativeClient.Create;

  ClientA.Name := 'Mr. Nice';
  ClientB.Name := 'Mr. Dumbhead';

  ShowMessage(ClientA.Name);
  ShowMessage(ClientB.Name);
end;
{----- ----- ----- ----- -----}

Свойства по умолчанию

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

A := MyStringList[i]:
MyStringList[i] := B;

{ instead of }

A := MyStringList.Strings[i];
MyStringList.Strings[i] := B;

{ or }

A := MyStringList.GetString(i);
MyStringList.SetString(i, B);

Индекс

С помощью ключевого слова Index Delphi передаст постоянное значение в качестве аргумента методам getter/setter.

TMyRect = class
private
  FValues: Array[0..3] of Integer;
  function GetTop(Index: Integer): Integer;
  function GetLeft(Index: Integer): Integer
  function GetWidth(Index: Integer): Integer
  function GetHeight(Index: Integer): Integer
public
  property Top    Index 0 read GetTop;
  property Left   Index 1 read GetLeft;
  property Width  Index 2 read GetWidth;
  property Height Index 3 read GetHeight;
end;


function TMyRect.GetTop(Index: Integer): Integer;
begin
  Result := FValues[Index];
end; 

Некоторые ресурсы

Есть еще некоторые темы для охвата (реализация интерфейсов, сохраненных значений, свойств времени RTTI/дизайна и т.д.), но этот пост начал немного длиннее...

Подробнее можно прочитать на этих сайтах:

Ответ 3

Свойства - большое преимущество Delphi. Я сделал довольно много Java и Delphi и определенно поеду на "Свойства". Практически оба подхода в конечном итоге будут делать то же самое, с той лишь разницей, что свойства выглядят намного аккуратнее, чем геттеры/сеттеры.

Я предлагаю вам перейти к свойствам и в полной мере использовать их!

Ответ 4

Это действительно вопрос вкуса и использования.

Для pascal, таких как программисты, очень ясно, что вы читаете или записываете значение, поэтому я считаю, что код более читабельен, если вы не используете геттеры и сеттеры в java-подобном стиле, где вы пишете GetXXX или SetXXX в каждое предложение вашей программы.

Для меня, и я предполагаю, что для большинства программистов на языке pascal код более читабельен, если вы просто поместите имя свойства, которое вы читаете/пишете, и все мы знаем, что будет вызван метод Getter или Setter ( если необходимо).

Кроме того, я думаю, что это огромная выгода (и элегантность) из модели свойств delphi, которую вы можете получить/установить значение свойства непосредственно из поля. Чтобы иметь множество методов Get/Set с помощью только строки кода, значение присваивается или считывается из поля - это полная потеря усилий/времени.