I am Robert C. Martin (Uncle Bob). Ask me anything.

View original thread
Kapralov Sergey's photo

Hi Robert.

I am a fan of your design metrics (linux.ime.usp.br/~joaomm/mac499/arquivos/re..) and the "Zone of Pain" term you described in "Clean Architecture". It changed my vision on what is maintainable code drastically.

However, originally you outlined those concepts for a set of classes, calling it "class categories". My question is: why can't the same metrics be applied to classes and interfaces per-se. They are a subject of reuse in OO code as well, and stable-concrete classes will inevitably be the source of pain and regressions, when the time to change something comes.

Also, what do you think about DI frameworks, which do injections by means of annotations (like Spring's 'Autowired' or CDI's 'Inject')? Aren't they break stable dependencies/abstractions principles, making implicit direct dependencies between our components?

Show all replies
Kapralov Sergey's photo

Daniel Hiller

OTOH in my experience you seldom need more than one concrete implementation, and if you do, you have a strategy and their implementations.

I disagree. You are right, interfaces are often designed in "service" way, and usually implemented once or twice, but IMO it is severe mistake. Interface is meaningless if it is designed for just a few implementations. Only the interfaces which has potentially infinite number of implementations truly enable OCP. For example:

interface Light {
    void on();
    void off();
}

Interface Light from example. It can have plenty of implementations, which are able to turn on and off smart lights from different vendors. Also, it can be implemented as a fake object for test purposes. It can have composite implementation, which enable management of group of lights in one shot. Any customer's demand related to turning on and off the lights can be implemented behind this interface. Such characteristic is achieved because Light is completely purified from technical details. It is true stable abstraction, the one that is always safe to depend on.

In such curcumstances, if all interfaces in a system are designed with this consideration in mind, the strategy pattern, spring profiles and autowired injections become really crooked and inflexible.