Yes, if you always used the same builder
and networkManager
, you could hide their instantiation within the facade’s initializer. This would indeed lead to a simpler initializer, init
.
However, there’s a trade-off made here: what if you use multiple types of builder
and networkManager
objects? If so, you’d want to inject these instead.
The point is: protocols protect objects against change. If you need something to change (e.g. you use multiple or different instances at run time), depend on a protocol, not a concrete class implementation. This corresponds to the Dependency Inversion Principle.
By the way, in the example shown, the view controller that uses the facade doesn’t know about the facade’s dependencies- it actually doesn’t even know about the real facade, but rather, only a protocol.
Instead, whenever the view controller is setup, it has the facade injected into it (via setting its property).
Thereby, the facade would be setup by whatever object that sets up the view controller.
This would most sense if the user is required to make some choice that affects the facade setup.
For example, imagine a “movie service” that allows you to rent from different services-- Netflix, Redbox, whatever-- and on the first screen, you select which service you’d like to query.
In this case, it would make perfect sense for a SelectRentalServiceViewController
to setup the facade, as it would have to know about the different concrete networkManager
and builder
objects based on the user’s selection.