Split communication logic from implementation details.

This allows us to handle the ZMQ communication between components
independently of the details of the demo-app itself.