Нарушает ли рисунок фасада SRP?


Принципал СРП говорит:

Класс или модуль должен иметь одну и только одну причину для изменения

У меня есть некоторый класс Facade в качестве классов слоя обслуживания. например, SaleService, что он предоставляет некоторые методы, например SaveOrder(), CancelOrder(), CreateOrder(), GetAllOrders(), GetAllPlannedOrders(), ...

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

3 ответа:

Рисунок фасада не нарушает SRP как таковой. Часто за фасадным рисунком скрывается сложное взаимодействие между лежащими под ним объектами. В этом случае "единственная ответственность" за фасад-это управление этими взаимодействиями. До тех пор, пока эти взаимодействия не изменятся, не должно быть никаких причин для изменения вашего фасада. Если взаимодействие становится действительно сложным, может быть, стоит снова разделить реализацию вашего фасада на несколько объектов.

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

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

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

Каковы причины перемен? В Примере с отчетом мы имеем два совершенно разных вида изменений: возможно, там, где данные поступают из изменений, или, возможно, изменения желаемого формата. В вашем примере можно утверждать, что существует также несколько возможных причин: "форма" объекта Порядок мог измениться, желаемый интерфейс мог измениться (напр. добавьте метод queryCancelledOrders (), бэк-энд, для которого вы являетесь фасадом, может измениться. Однако я не считаю, что это признаки того, что вы нарушаете SRP: все они относятся к задаче представления интерфейса для манипулирования ордерами.

Если бы мы приняли "единственную причину для изменения" полностью буквально, то я не верю, что мы когда-либо могли бы написать какой-либо класс. У нас всегда есть интерфейс и реализация, и обычно также некоторые зависимые классы. Любой из них может измениться, поэтому у нас всегда есть по крайней мере две, а возможно, и три причины для перемен.

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

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

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

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

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