сеттеры и геттеры с сильно вложенным составом - PullRequest
1 голос
/ 30 марта 2012

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

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

Вот типичный пример:

template <typename T>
class fooA {
  public:
   /* setters, getters, etc... */
  private:
    T w,x,y,z;
};
template <typename T>
class fooB {
  public:
  /* setters, getters, etc... and maybe ways to set/get private members of type class A */
  private:
 T d, e, f, g, h;
 fooA<T> i, j, k;
 };

Каков наилучший (или предпочтительный) способ настройки w, x, y, z, данных приватных i, j, k членов класса fooB? Написать сеттеры / геттеры в классе fooB, или вернуть ссылку, или что-то еще? Обычный вариант использования в моем приложении - это создание параметра для величин w, x, y, z члена i экземпляра fooB.

EDIT: Объект, который я моделирую, представляет собой велосипед, который я описываю в общей сложности с 31 параметром. 30 из этих параметров имеют передний и задний аналог, поэтому я решил создать класс для представления этих 15 параметров, а затем в классе велосипеда есть два из них как частные переменные-члены. 11 из этих 15 параметров могут быть сгруппированы в набор параметров, которые могут иметь смысл в свой собственный класс, поэтому я снова группирую их в класс и делаю его частным членом класса с 15 параметрами. И в пределах этого класса 6 из этих 11 параметров могут быть далее объединены в их собственный класс. Итак, у меня по сути четыре уровня вложенности. Итак, если клиент велосипедного класса самого высокого уровня хочет настроить один из параметров на самом низком уровне (что типично для моего приложения), он может:

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

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

Ответы [ 3 ]

1 голос
/ 30 марта 2012

«Обычный» способ сделать это, по крайней мере в тех местах, где я работал, состоял в том, чтобы использовать сеттеры и геттеры в соответствии с:

class A
{
    T myX;
public:
    T x() const { return myX; }
    void x( T const& newX ) { myX = newX; }
};

Как правило, однако, слишком много сеттерова добытчики - признак плохого дизайна.В этом случае, если я вас правильно понимаю, у вашего класса есть набор членов, которые можно охарактеризовать как «параметры», которые влияют на то, как он выполняет свою работу, но которые определяются и могут быть изменены пользователемучебный класс.В этом случае я бы предложил создать компонент для их представления;поскольку это чистые данные (без поведения), struct может показаться более подходящим.В этом случае у вас будет один сеттер и геттер.Или единственная функция, возвращающая ссылку на параметры.В этом случае я думаю, что возвращение ссылки было бы вполне уместным;того факта, что вы перегруппировали все, что клиентский код может изменить в отдельную сущность с семантически значимым именем типа, достаточно, чтобы прояснить общую логику.

0 голосов
/ 30 марта 2012

Для операций только для чтения вы всегда можете вернуть ссылку const.Например,

class fooB
{
public:

    fooA<T> const & get_i() const { return i; }

...
};

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

  1. Кто-то берет на себя ответственность за компоненты в централизованном подходе.В этом случае все установщики должны пройти через класс fooB, и он поддерживает согласованность (под) системы.
  2. Компоненты общаются друг с другом.В этом более сложном распределенном случае компоненты должны знать друг друга.Для настройки fooB может возвращать ссылку на компонент, поскольку компонент обязан отправить сообщение (т. Е. Вызвать функцию обновления) соответствующим другим, когда компонент был set.Настройка каналов связи между компонентами (например, шаблоны наблюдателей со слушателями и регистрация) может быть выполнена с помощью fooB.
0 голосов
/ 30 марта 2012

Если вам нужно проверять целостность каждый раз, когда w, x, y или z меняются, вам нужно использовать сеттеры.Все остальное создаст лазейку для изменения значения без проверки.

Кажется, что вы по какой-то причине неохотно пишете методы получения / установки, но это довольно стандартная методика ОО.

...