Нарушает ли шаблон Facade SRP?

Директор SRP говорит:

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

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

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




Ответы (3)


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

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

person Matthijs P    schedule 23.07.2013
comment
Спасибо, вы сказали, поэтому может быть интересно пересмотреть использование шаблона фасада здесь. каково ваше предложение? - person Masoud; 23.07.2013
comment
К сожалению, это трудно сказать, не зная больше о вашей системе; хорошая отправная точка для вас — подумать, почему, по вашему мнению, вам вообще нужен шаблон фасада. Есть несколько веских причин для его использования. Если ваша причина не входит в их число, возможно, вы просто усложняете систему. - person Matthijs P; 23.07.2013

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

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

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

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

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

person djna    schedule 23.07.2013
comment
Спасибо, как вы думаете, что такое хорошее предложение для моего класса SaleService? - person Masoud; 23.07.2013

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

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

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

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

person guillaume31    schedule 23.07.2013