Question

Assuming you have an application that requires 2 services, eg. Application, Service1, Service2

Should you build an extra level of indirection and promote 1 of the services to application service, and demote the other to domain service, following this onion architecture.

Or should you have the Application directly connect to both Service1 and Service2?

With another level of indirection, you can reduce dependency on the Application layer, especially towards external services eg. 'Paypal', 'Facebook', 'CyberSource' and create application service adapters that is more suitable for your programming paradigm. Afterall it is really detrimental to productivity having all developers familiarize themselves with all these widely varied APIs. A Façade/Adapter will make things easier to develop while shielding the application from infrastructural changes. eg. The company had a failing out with CyberSource and decided to go with Paypal instead, luckily your application is shielded, and you only needed to change the adapter and nothing else.

That said, the adapter definitely creates inflexibility. As the application grows in complexity, the adapter also becomes leaky. Then you potentially have 3 problems: leaky abstraction, a lazy layer (a layer that's not doing enough due to having too many holes), and a violation of common closure principle, as anytime you need the UI changed, you have to modify not only your application, but also your adapters.

And what happen when Service2 is already an internal service within the same company? Should you still create an adapter for each subsystem? What if your team is small? What if you have tens of teams with diverse set of technology? Is there any guidance for the propriety for adding another layer of indirection vs. just calling the service directly?

Was it helpful?

Solution

I think you should design your application so that it depends on interfaces that are convenient to your application, independent of any consideration of using outside services. Your idea of using adapter/facade is a good one, but I don't see any reason to treat Service1 any differently than Service2.

If my app is making widgets, then I should just call MyService.MakeWidget(args); The fact that this operation coordinates the behavior or 2 different external services is an implementation detail.

I think the convenience factor is more important than the goal of substituting external dependencies (although both are enabled by OA). Convenient interfaces improve the narrative of your application at the cost of indirection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top