Design patterns: Dependency Injection and its variations