Это хорошая идея, чтобы сделать поля защищенными? - PullRequest
7 голосов
/ 17 января 2012

Пример кода:

unit Foo;

  TFoo = class
  protected
    FList: TList; // Lifetime is managed by constructor and destructor
  public
    property List: TList read FList;
    constructor Create;
    destructor Destroy; override;
  end;

unit Bar;

  TBar = class(TFoo)
    procedure MyMethod;
  end;

procedure TBar.MyMethod;
begin
  // Access of FList goes here
end;

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

Должен ли я сделать FList частным и использовать свойство для доступа к нему из TBar?

Как вы справляетесь с подобными делами?Есть ли какие-то соображения по поводу производительности?

1 Ответ

3 голосов
/ 17 января 2012

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

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

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

В этом случае, поскольку TBar наследуется от TFoo, Protected является допустимым уровнем видимости, поскольку он зарезервирован для унаследованных классов.Кроме того, поскольку TBar унаследован от TFoo, возможно, вы думаете, что он должен иметь некоторые дополнительные привилегии для внутренней работы TFoo, потому что это, в конце концов, его дочерний класс.Почему мы должны предоставить TBar такой же низкий уровень доступа, как и другим классам?

Ответ зависит от того, является ли FList фактическим членом класса TFoo, поскольку мы рассматриваем то, что представляет модель TFoo, или это простодеталь реализации.Кроме того, какой уровень доступа требуется?Мы просто обращаемся к нему или меняем реализацию?

Я предполагаю, что вам не нужен доступ к FList, и вы не меняете реализацию, в этом случае, даже если дваклассы были в том же модуле, я все равно сделал бы FList Private over Protected.

Если бы вы просто обращались к члену класса из классов-потомков в том же модуле, я все равно оставил бы его закрытым.

Однако, если FList был чем-то, что вам нужно переопределить в TBar (вероятно, нет, так как это не метод), или был спроектирован как нечто, что унаследованные классы должны или будут переопределять, было ли это в том же модуле или нет, тогда выхотел бы сделать его Защищенным.

Вам также необходимо повысить видимость Защищенного, если вам необходимо получить доступ к FList из классов-потомков за пределами того же модуля.

...