Too much abstraction or indirection will certainly lead you down that path, but that is not really what I would advocate at all. With Obvious the goal is to make it feel obvious what the system is doing. No big complicated inheritance systems. Instead it uses a bit of indirection via dependency injection and reflection to make the data plugs swappable. Nothing too crazy or complicated.