Замена объекта Бога

Теперь я пытаюсь избавиться от объектов бога из кода моего сервера.

В начале разработки моего сервера я решил сделать объекты контейнеров World и const одноэлементными.

Но мой сервер многопоточный, и синглтоны не являются хорошим решением.

Так что мне это удалось, и я переместил эти классы как экземпляр класса Core.

Например:

class Core
{
...
private:
World world;
CExpTable exptable;
...
};

Core при новом соединении дает ссылки на объект для класса Session.

new Session(io_pool.getService(), world, exptable ...);

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


person user3126089    schedule 13.01.2014    source источник


Ответы (1)


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

Что касается вашего рефакторинга: лучше всего идти шаг за шагом. Большие обороты обычно создают ошибки. По моему опыту, демонтировать божественный объект не очень сложно.

Вы можете действовать следующим образом:

  • определите небольшую ответственность, которую вы хотели бы снять с объекта-бога
  • design a new interface for this responsibility:
    • start writing unit-tests for the new class implementing this new interface. Make tests passing by an instance of the god-object enclosed in the new object, and just forward the calls
  • имея набор юнит-тестов можно вырезать куски кода из бога-объекта в новый объект

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

Если у вас есть какое-то состояние, которое должно использоваться/обрабатываться этими обязанностями (например, экземпляр World в вашем примере), вам придется сделать его общим. Вы можете преобразовать его в shared_ptr например, чтобы его можно было оставить в бог-объекте на время рефакторинга, а также использовать его в новых классах.

person BartoszKP    schedule 13.01.2014
comment
Итак, я хочу создать только один экземпляр класса World, но я понятия не имею, где хранить ссылку/указатель на него, прежде чем я сохранил все в классе бога под названием Core. Можете ли вы объяснить мне, как я могу хранить экземпляр мирового класса без бога или синглтона? Спасибо. - person user3126089; 13.01.2014
comment
@user3126089 user3126089 Я обновил свой ответ одним из возможных решений. - person BartoszKP; 13.01.2014
comment
Будет ли хорошо дать указатель на него из «божественного класса», чтобы он понравился новому сеансу (..., указатель мира,...)? - person user3126089; 13.01.2014
comment
да. Или к методам Session, если ему не нужно постоянно это помнить. - person BartoszKP; 13.01.2014