A lot has been said about when to use public/private/protected. Some say that you should never use private, while others say you should never use protected.

About the only thing that people can seem to agree on is that public should be used with caution. That your versioning should be based around your public API, and you have a responsibility to maintain that API.

The issue is mainly around the maintenance responsibility of protected vs private. Given that other developers can depend upon protected, it can effectively be considered to have the same overhead as your public API.

I personally very rarely use private properties, and I default to protected.

My thinking is thus:

  1. The public API is sacrosanct, following SemVer, breaking the public API shall bring a new major version. I will do my best to support an existing public API for as long as possible and only break backwards compatibility as a last resort.

  2. The protected API is important. It does not impact SemVer, though often accompanies changes at the X.Y level. However I pledge to document any changes in release notes and otherwise, to ensure that if you pay attention you will be able to track changes and avoid issues. I will make changes as necessary to the protected API. (n.b. as I write this, I’m considering making it a rule that X.Y should be incremented for protected changes, always)

  3. The private API is the wild west, and you’re on your own.

I think this is a pretty pragmatic approach, it preaches caution and engagement when extending third party libraries, yet does not needlessly prohibit the ability to extend entirely.