you are viewing a single comment's thread
view the rest of the comments
[–] 42 points 9 months ago (13 children)

Its the best/worst thing about OOP no matter what language.

We had a rule at work that if you are 3 levels or more down an inheritance tree, then you are too far. The cognitive load is just too much, plus everything stops making sense.

One level can be great (MVC all have great conventions, MCP as well). Two can be pushing it (Strategy pattern when you have physical devices and cant be connected all the time, Certain kinds of business logic that repeat hundreds of times, etc...) But even there you are kinda pushing it.

I need code that I can look at a month from now and know WTF is happening. And sometimes its better to have less DRY and more comprehension. Or maybe im just a forever mediocre dev and dont see the "light". I dunno.

  • source
  • parent
  • hideshow 13 child comments
  • [–] 19 points 9 months ago

    This is exactly how I feel too. A little bit of repetition is totally worth it, versus having inappropriate coupling, or code that jumps in and out of parent/child classes everywhere so you can hardly keep it in your head what's going on.

    I freely accept that I AM a mediocre dev, but if that lends me to prefer code that is comprehensible and maintainable then I think being mediocre is doing my team a favour, honestly.

  • source
  • parent
  • [–] 7 points 9 months ago (4 children)

    But if I have to make an Array I have to inherit from Indexable which inherits from Collection which inherits from Object! How else am I supposed to implement an Array?

  • source
  • parent
  • hideshow 4 child comments
  • [–] 4 points 9 months ago* (2 children)

    Admittedly this is why I like C#'s 'implements' paradigm. Doesn't have to inherit, it just has to fulfill the contract, and then you can pass it to anything that expects the interface it implements. Keeps you from building giant trees.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 3 points 9 months ago (1 child)

    As a rust developer I feel obligated by religion to make this comment:

    Then you'd love rust! Rust only has "interfaces" (called traits) but doesn't have inheritance. You just have traits that don't inherit from anything and structs (that don't inherit from other structs) that implement X amount of traits.

    So you can have the good things about OOP without the bad ones.

    And these traits allow you to make trait objects, which would be like regular objects in C# (with vtables for the methods). If 2 different structs implement the same trait, you can "downcast" them to a trait object and store them in the same array. Or pass it is an argument to a function that wants something that implements that trait but doesn't care about the specific struct. You can of course cast it back later to the original struct.

  • source
  • parent
  • hideshow 1 child comment
  • [–] 2 points 9 months ago

    I like interfaces as a supplement to inheritance. The strength of inheritance is getting all of the internal functionality of the parent class, while still allowing you to differentiate between children.

    Interfaces are useful for disparate classes which don't have much in common besides fitting within a specific use case, rather than classes that are very similar to each other but need specific distinguishing features.

  • source
  • parent
  • [–] 7 points 9 months ago (3 children)

    When I first started using Go I bemoaned the lack of true inheritance and classes. Now I love it.

  • source
  • parent
  • hideshow 3 child comments
  • [–] 1 point 9 months ago (2 children)

    I thought it didn't have classes in name only, isn't a struct with methods basically a class?

  • source
  • parent
  • hideshow 2 child comments
  • [–] 3 points 9 months ago

    Depends on what you mean by “basically a class”. If you mean inheritance, overriding, and more generally class/inheritance based polymorphism, no, it does not. Those require dynamic dispatch, which Go does not have (for concrete types, which is what we’re talking about here).

  • source
  • parent
  • [–] 3 points 9 months ago

    composition can help with all of that. factories, strategies, injections are all composition patterns that work fine.

    business logic that repeats? extract it to it's own thing (class, function, etc) and pass it as a param to the supposed childs.

    mvc? controllers don't need to extend anything, just have them accept the framework through the constructor and request and response as args. views? same. models? perhaps only if doing an active record, but a repo pattern with plain objects is a good pattern too.

    I never seen a clean inheritance implementation for a decently sized problem. it mostly works for tiny ones.

  • source
  • parent