2009-03-22 6 views
5

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

ответ

13

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

+1

К downvoters: Я принял совет от самого Страустрапа: http://www.artima.com/intv/goldilocks3.html «Bjarne Stroustrup: мое эмпирическое правило: у вас должен быть настоящий класс с интерфейсом и скрытым представление тогда и только тогда, когда вы можете рассматривать инвариант для класса ». –

+0

Это точно. Позже в том же тексте: «Да. Если у каждого из данных может быть какое-либо значение, то нет смысла иметь класс. Возьмите единую структуру данных, которая имеет имя и адрес. Любая строка - хорошее имя, и любая строка является хорошим адресом. Если это то, что есть, это структура. –

+0

Продолжение: «Не нужно ничего приватного. Не делайте ничего глупого, как наличие скрытого поля имени и адреса с функциями get_name и set_address и get_name и set_name. Или, что еще хуже, создать виртуальный базовый класс с виртуальными функциями get_name и set_name и т. Д. » –

4

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

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

0

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

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

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

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

+0

Зачем -3 downvoting? – anand

+1

Я его поддержал, так что это было как минимум 4 downvotes :) Серьезно, я думал, что общеизвестно, что геттеры/сеттеры - плохой дизайн. Страшно. –

+0

OKay вопрос был, если геттер/сеттеры могут быть использованы? Его плохая конструкция много раз и то, что я ответил. Из большинства ответов выше того же вывода. Я не уверен, что это общее знание для всех. – anand

19

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

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

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

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

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

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

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

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

1

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

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

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

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