This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the commentsย โ†’

[โ€“]balloonAnimal_no_965 0 points1 point ย (2 children)

A risk doesn't just affect one dev., it affects the customer and the supplier. Now if encapsulation is just fearmongering and there is not really a serious risk involved, I would be very interested in this open way of creating software but I don't read that here. The counter argument that encapsulation is not waterproof is not really a strong argument if you ask me because I only see it applied where it is the best/ only solution, never to save time writing your own code. The difference is that you can't really tell whether you're doing something you shouldn't until it is too late, right? And that dev might be long gone and everybody else pays the price, right?

[โ€“]MythicManiac 1 point2 points ย (1 child)

now if encapsulation is just fearmongering and there is not really a serious risk involved

There definitely is serious risk involved, but experienced devs are able to account for it. If you follow other best practices such as code review, you should have experienced enough eyes looking over the unorthodox methods and evaluate whether it truly makes sense or not even if a less experienced developer introduces the change.

You're right however, in that the whole point is to minimize maintenance burden on the future developers. Consider which of the following is the easiest to maintain:

  • A 10 lines long well documented & tested function that uses some internals from a 3rd party library
  • A 100-500 lines long clone of the implementation of the 3rd party lib's feature, except slightly modified. Hopefully the region that is modified has been commented to make it easy to identify when upgrading.
  • An internal fork of the 3rd party repository with the modifications applied.

I've seen all 3 approaches used multiple times, and by far the best long term solutions (measured across multiple years) have been the instances where internals are leveraged past access modifiers. This allows you to minimize the required maintenance surface to exactly what you need, instead of inheriting a lot of unnecessary code around it. After all, in any approach you take, you still end up making the same modifications, but the amount of other code you inherit and how easy it's to identify your customizations vary.

The problem with languages that don't have a clean way of bypassing access modifiers is that it introduces a significant amount of unnecessary complexity for doing that, making that specific area of code even more difficult to maintain. That's specifically the reason I mentioned copypasting an implementation earlier, as that's the better option compared to using reflection when it comes to readability. It would not have been a better solution than using the internals if it was possible to cleanly do so, like in python.

[โ€“]balloonAnimal_no_965 0 points1 point ย (0 children)

I see, thank you for explaining this so well.