This principle “feels” right, but I’m working through trying to formulate it properly.
Consider a point class (in pseudo-code because lazy):
class Point private x, y construct(x, y) draw(Drawable surface)
(Instead of surface, it could also be a save-function with a database connection as argument (or indeed any type of persistence)).
If the surface was instead injected into the constructor, the point would look like:
class Point private x, y, surface constructor(x, y, surface)
Isn’t that weird, to have two properties related to state, and then a third property related to something completely different? Especially when it’s something effectful, like drawing or writing to disk.
On the other hand, you can imagine a command object class like this:
class InstallApp private db, io, logger, mailer constructor(db, io, logger, mailer) execute(app)
In this case, all dependencies are effectful classes. Makes more sense, right? And then the app class has only “pure” properties, like
A rectangle depending on points is also OK, since the points are pure:
class Rectangle private bottomLeft, topRight constructor(Point bottomLeft, Point topRight) // draw, save, etc
Another way to phrase it is that classes should only depend on other classes in the same layer (domain layer vs “effectful” layer).
We also want to enable polymorphism, like:
shapes = [ new Point(1, 2), new Rectangle(new Point(2, 3), new Point(3, 4)) ] surface = new Surface() forall shapes as shape shape.draw(surface)
The major drawback is that no language can actually distinguish between a dependency and “normal” class property. Possibly they should have different semantics? Or the possibility to separate pure and effectful classes.