Вопрос о классовом взаимодействии - PullRequest
0 голосов
/ 10 июня 2011

У меня есть классы, как показано ниже

class A
{
 private:
   B b;
}

class B
{
private:
  C c;
  D d;

}

C и D - класс хранения, который в основном содержит структуры и структуру данных. B обернуть оба вместе. Мне интересно, что является лучшим подходом в получении данных C и D или выполнении функции, если у меня есть объект A?

 For example:
 class A
{
 private:
   B b;
 public:
   B* GetB() { return &b;} 
};

class B
{
private:
  C c;
  D d;
public:
  C* GetC() {return &c;}
  D* GetD() {return &d;}
};

class C
{
 public:
  functionA();
};


A a;
B* b = a.GetB();
C* c = b->GetC();
c->functionA();

OR

Я вообще не должен выставлять объект B:

 class A
{
 private:
   B b;
 public:
   C* GetC() { return &b.GetC();} 
   D* GetD() { return &b.GetD();}
};

A a;
C* c = a.GetC();
c->functionA();

OR

Я не должен выставлять объекты B, C и D

 class A
{
 private:
   B b;
 public:
   void performFunctionA() { b.performFunctionA(); }
};

class B
{
private:
  C c;
  D d;
public:
  void performFunctionA() { c.functionA();}
};

class C
{
 public:
  functionA();
};


A a;
a.performFunctionA();

Почему мы выбираем одно над другим?

Спасибо

Ответы [ 3 ]

1 голос
/ 10 июня 2011

Мне больше нравится ваш последний вариант.Рассмотрим вещи с точки зрения ваших пользователей.Когда кто-то использует объект A, проще всего знать, что он хочет performFunctionA.Они не должны знать или заботиться о том, что A содержит B, который содержит C и D. Кроме того, если вы когда-либо измените внутренние детали B, пользователям класса A не придется перекомпилировать.

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

1 голос
/ 10 июня 2011

Хорошая инкапсуляция говорит о том, что вы должны раскрывать как можно меньше деталей реализации.В вашем случае это означает, что вы предпочитаете последний вариант и не выставляете B, C или D.Таким образом, любые изменения B, C и D могут быть изолированы от пользователей A.

0 голосов
/ 10 июня 2011

Закон Деметры говорит, что

  • Каждая единица должна иметь только ограниченное знание о других подразделениях: только единицы "тесно", связанные с текущим блок.

  • Каждый юнит должен разговаривать только со своим друзья; не разговаривай с незнакомцами.

  • Поговорите только со своими ближайшими друзьями.

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

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

Недостаток закона Деметры это то, что иногда требует написания большое количество маленьких «обёрток» методы для распространения вызовов методов компоненты.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...