1. 21

  2. 6

    But, don’t make things huge and complex because of SOLID. Also see YAGNI.

    1. 3

      I would have put the spork vs. spoon and fork for interface segregation, not for single responsibility. A spork is really useful outdoors. Also the multi-plug cable being ‘worse’ than multiple single-plug cables seems wrong.

      1. 2

        Yeah, multi-plug cables are great. You can keep just one cable instead of 3, and they take up fewer USB slots for charging.

        In addition to those two, the power socket example is off, too: you drew a type C power outlet, the kind that’s common in Europe. In the US, we use type A power outlets instead, which use a different plug shape. That’s why you need outlet converters when you travel internationally! A great example of depending on concretions.

      2. 2

        SOLID always feels like it’s advice about how to handle “promises” properly in a typed system. If I offer you some value of type T then that comes attached with a number of “promises” in terms of what you may do with values of type T, what you may expect from them.

        SOLID, or S_LID at least, implores me to (a) take those promises seriously, (b) offer only promises I am confident I can keep, and (c) offer as many promises as I can while demanding as few as I can get away with.

        • Single Responsibility drives for the separation of promises into groups, allowing enough richness in the subtyping hierarchy to even discuss “offering a lot” or “asking for a little”.
        • Liskov Substitution is a mandate on treating the subtyping relationship as the arbiter of these promises and, I feel, essentially protects against “subclassing” hierarchies which only carry convenience in construction, not consistency of properties
        • Interface Segregation essentially says, alongside S, that our functions should only ask for exactly what they need
        • Dependency Inversion is again a practice of demanding as little as possible (thus, abstract interfaces are more durable).

        From this perspective, the thing that is missing to my eye is that the types you generate should be the aggregations of all of the promises you can afford to make about them. Your clients can always choose to use less than you offer, but once a promise is made it must be kept (for backwards compatibility purposes).

        Another way to look at it is a given function A1 => B1 can also be treated as a function A0 => B2 for A0 < A1 and B1 < B2. So to make the highest utility interface, we should ask for the most abstract/least demanding input A and offer the most concrete/least abstract output B.

        The limitation is that every thing I refuse to ask for on the input side I must be confident I will never need and every thing I offer on the output side I must be willing to support “forever”.

        This idea, plus Liskov Substitution which gives teeth to the idea of “promises” all together, feel like it generalizes most of what S_LID is talking about.

        1. 1

          This is a good introduction to SOLID… and also a good reminder for people like me who often forget what the I stands for (I tend to mistake it for Inversion of Control).