Remote versus local clients
As we have previously seen in this chapter, our clients were defined by using interfaces. The main motivation for this added level of abstraction is so that we can substitute a remote implementation for a local one. Let's say that component A depends on component B. If these components were deployed on separate servers, we would want to use an implementation of B's client that makes remote calls to the component. If, however, both components co-existed within the same JVM, using a remote client would incur unnecessary network latency. Substituting the client for one that directly invokes component B's Java implementation ensures that no networking takes place, thus reducing latency.
Note
This pattern is commonly used in Microservice architectures (https://en.wikipedia.org/wiki/Microservices), which are becoming very popular. This style of architecture advocates the breaking up of complex applications into small, independent components.