Это анти-паттерн?

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

Например networkUserManager а также localUserManager воплощать в жизнь IUserManager у которого есть метод getUser(), networkUserManager.getUser() ставит запрос на получение User в очереди и возвращает ответ. localUserManager.getUser() получает запрос из очереди, находит информацию о пользователе в некоторой базе данных, а затем отвечает данными пользователя.

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

6 ответов

Решение

Вы, кажется, описываете шаблон Decorator. В этом случае NetworkUserManager обеспечивает дополнительную функциональность по сравнению с LocalUserManager, Вы не говорите, какой язык вы используете, но этот шаблон появляется на протяжении java.io пакет.

С другой стороны, ваше описание LocalUserManager.getUser() извлечение сообщения из очереди кажется неправильным - оно отстает от пути NetWorkUserManager работает. Я бы посчитал это правильным декоратором, если LocalUserManager доступ к базе данных, в ответ на что-то еще (возможно, NetworkUserManagerService) ссылаясь getUser(),

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

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

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

Если я вас правильно понимаю, у вас есть очередь. Процесс A, независимо от имени, помещает вещи в очередь. Процесс B, независимо от имени, забирает вещи из очереди и обрабатывает их.

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

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

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

Вопрос здесь заключается в том, является ли getUser значимой абстракцией и инкапсулирует ли она вашу логику, которая выглядит для меня как многоуровневый доступ. Я бы сказал, что он скрывает больше, чем освещает. Например, декораторы java.io могут (в основном) быть привязаны друг к другу в любом порядке; Учитывая многоуровневый доступ, который вы описываете, имеет смысл LocalManager.getUser(NetworkManager.getUser()), а NetworkManager.getUser(LocalManager.getUser()) - нет.

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

Я бы не стал называть это антипаттерном, но определенно очень плохой реализацией интерфейса. ("Дурной запах", как упомянуто в этой теме?)

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

  • localUserManager.getUser() ожидает, что что-то уже находится в очереди
  • networkUserManager.getUser() - нет.
Другие вопросы по тегам