Clean Architecture – Do Interactors in Clean Architecture Violate the Single Responsibility Principle?

designdesign-patternssolid

The SRP states that a class (module) should have only one reason to change. The "duties" of an Interactor in Bob Martin's clean architecture are, per use case: receive requests/inputs from a controller; orchestrate domain entities to fulfil the requests; and prepare the output data.

Does this imply three reasons to change? (ie whenever inputs change or domain functionality is expanded or extra output fields are added.)
If necessary, what would be a good strategy to resolve this? (eg, CQRS?)

My current approach is to make a use-case Interactor module with three classes, one per each concern, and a fourth Facade/ Mediator class for orchestration and clients interfacing. However, doesn't this push SRP violation up onto the module level?


As pointed by @Robert Harvey, the term "duties" was used rather sloppily. The actual design issue has been the large changes to the interactor needed both when the domain changed, and the OutputData fields/formats changed (less so with input). Aren't these two distinct reasons for change?

As I realised from @Filip Milovanović and @guillaume31, SRP is not violated, esp. with three separate classes in the interactor module. Also, at the module level, the "Common Closure Principle" is perhaps more appropriate than the SRP. The CCP ("Gather into components … classes that change for the same reasons and at the same times.") might suggest to separate the interactor classes. (But then the classes corresponding to the same use case would be spread out between locations.) Thanks to the answers and comments, these trade-offs have become much clearer to me.

Best Answer

The "duties" of an Interactor in Bob Martin's clean architecture are, per use case: receive requests/inputs from a controller; orchestrate domain entities to fulfil the requests; and prepare the output data.

Does this imply three reasons to change?

You're confusing duties with responsibilities. More specifically, you're confusing "should have only one responsibility" with "should do only one thing."

The responsibility of an interactor is to "interact."

The responsibility of a data access class is to access data. It doesn't have four responsibilities because it creates, reads, updates and deletes; it has four duties.

If you're a short-order cook, your responsibility is to make meals. You don't split your duties into separate employees. You don't have one employee that cracks the egg, another employee that turns it over, and a third that puts it on the plate. You perform all three.

Related Topic