Создание взаимозависимых объектов - PullRequest
3 голосов
/ 07 августа 2010

У меня проблема с дизайном, я не могу найти чистое и хорошее решение. Я занимаюсь разработкой на PHP, но считаю, что это может произойти на любом языке. Моя основная проблема состоит в том, что у меня есть два объекта, которые имеют круговую взаимозависимость на некотором уровне косвенности. Это означает, что у меня есть класс (назовите его F), реализующий шаблон Facade, который содержит объект (класса B), которому сам по себе нужен объект класса A. Самому конструктору класса А. для создания необходим фасад F => У меня круговая взаимозависимость объектов.

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

  1. Пусть класс A реализует метод setFacade (F $ facace), удаляет весь фасад из конструктора и просто устанавливает его после создания A и фасада. Объекты класса A не могут работать без фасада, так что это фактически создаст объект класса A, который не сможет ничего делать, пока не будет вызван setFacade, и это уменьшит инкапсуляцию и позволит заменить фасад во время выполнения объекта, что я также надеваю не нравится.

  2. Реализуйте что-то вроде Обещания, которое передается А вместо фасада, который сможет разрешить фасад позже, как только он будет создан. Я не хотел бы вводить этот дополнительный уровень косвенности, особенно потому, что у меня нет хорошего места для фактического разрешения обещания, чем в методах, которые обрабатывают бизнес-логику внутри A, которые могут а) вызывать ужасные ошибки и (что более важно) б) бесполезную потребность я должен проверить, было ли обещание уже разрешено или мне нужно будет разрешить его сейчас, всякий раз, когда вызывается логика бизнеса. Это просто ужасный дизайн в моих глазах.

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

Ответы [ 3 ]

2 голосов
/ 07 августа 2010

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

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

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

1 голос
/ 07 августа 2010

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

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

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

Спасибо всем за помощьмне по этому вопросу.

1 голос
/ 07 августа 2010

Если вы используете Фасад, как он обычно определяется (как упрощенный интерфейс, который управляет зависимостями и упрощает использование сложного API), то ни один из «скрытых» (фасадом) классов не должен знать о классах, использовать фасад. По сути, думайте об этом как об одной точке входа, что означает, что B не должен зависеть от A, или A не должен зависеть от Фасада.

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