Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding violation of Reused Abstraction Principle

In Dependency Injection we program against an abstraction.

From my experience, I can state that most of the abstractions in an application have a 1:1 relationship with their implementations. This is a violation of Reused Abstraction Principle.

Mark Seeman suggested in some of his posts that we can have a Null Object Implementation for the abstractions in order to avoid RAP violation ( This suggestion from Mark Seeman could be my inference. Please correct me if I am wrong to quote Mark on this). My question here is.

  1. How to do Null Object implementation?
  2. Is it ok to violate RAP?
like image 999
Rajkumar Vasan Avatar asked Jun 05 '12 09:06

Rajkumar Vasan


1 Answers

Personally I find it useful to program to an abstraction even if there is only one production implementation. In particular:

  • Even if you only have one production implementation, you may well have other implementations in tests, either full-blown fakes or dynamically created mocks
  • It's a clearer expression of dependencies than depending on the concrete class in many cases. For example, the concrete class may expose some other public members which you don't depend on, for various reasons.

Mind you, this is a false statement to start with:

In Dependency Injection we program against an abstraction.

You can use dependency injection with concrete classes perfectly easily. There's nothing to say you have to create interfaces for your dependencies. Dependency injection is more about how your class obtains its dependencies than about what level of abstraction it uses to express them.

So basically:

  • Don't underestimate the importance of "test doubles" to implement abstractions, even if you only have one production implementation
  • Don't be afraid to depend on the concrete implementation if you really want to, but injecting that dependency is still cleaner than creating it within your class, where it really is a "proper" dependency
  • Don't try to inject everything - if the behaviour of the dependency isn't really an interaction then you may well not want to inject it. For example, don't start injecting "collection providers" just to avoid creating instances of List<T> - you don't need to isolate your class from the behaviour of List<T> for test purposes, for example.
like image 148
Jon Skeet Avatar answered Dec 29 '22 12:12

Jon Skeet