Accessors против публичных участников - PullRequest
5 голосов
/ 22 марта 2009

У меня есть класс с большим количеством встроенных членов типа с доступом для чтения / записи. Должен ли я сделать их открытыми членами и предоставить методы get / set для каждого из них? Как насчет структур?

Ответы [ 5 ]

19 голосов
/ 22 марта 2009

Вся причина иметь аксессоры (геттеры) и модификаторы (сеттеры) состоит в том, чтобы обеспечить себе дополнительный уровень косвенности.

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

Установщики позволяют вам выполнять специальную проверку ошибок, проверку и исправления, когда значение установлено. Например, setDirectory (const std :: string & strPath), вы можете убедиться, что есть косая черта, если пользователь не указал ее. Это гарантирует, что ваше состояние класса всегда будет действительным.

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

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

С помощью метода получения вы также можете получать различные представления ваших данных, например: getMinutes, когда ваш элемент данных фактически сохраняется в секундах.

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

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

13 голосов
/ 22 марта 2009

Если есть инвариантов , которые нужно сохранить, то да. В противном случае, не беспокойтесь.

4 голосов
/ 22 марта 2009

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

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

1 голос
/ 22 марта 2009

Вы должны использовать только общедоступные элементы данных

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

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

  • наблюдая за изменениями в члене
  • заставить члена играть любую роль в инварианте класса
  • отключение доступа к члену
  • изменение реализации элемента (например, вычисление по сравнению с кэшированием и сохранение), если это необходимо для производительности
0 голосов
/ 22 марта 2009

Использование методов get / set для закрытых / защищенных членов данных - плохой дизайн.

Это заставляет код клиента зависеть от деталей реализации вашего класса.

Изменения в вашем классе вызывают изменения в коде клиента.

Однако можно использовать методы get / set для открытых членов. Но всегда хорошо их избегать.

...