callback cohesion component container dependency encapsulation flexibility listener modularity observer