Backwards Compatibility

Make clear what is guaranteed and do this only via an explicit interface, that has no implementation specifics. Prefer backward compatible changes to backward incompatible changes. Make as much undefined as possible for not essential things in order to minimize the set of guarantees. Breaking other software, because it relied on implementation specifics is better, than breaking other software via incompatible API changes. Do not just break features, but also migrate its usage to other appropriate features before breaking said features. Feature flags are your friend.

Exceptions are not considered to be part of the API. Only unchecked exceptions are used.

If there are not many users of the affected function or if the migration costs for the code users are reasonable, the fast protocol can be considered. In this case, the removal should be done with a minimum amount of commits and time. After the removal is done, the rest of the main project's code still needs to work. Any required adjustments for the function removal are part of the function removal and should be done in the same time. In other words, do not break the build with a function removal. Other projects, that are using the removed functions and which are maintained by the people of the main project, should migrate to the new API as fast as reasonable possible.

When a function is to be removed, that is important for code users, prefer the following protocol:

  1. Mark function as deprecated and thereby create compile time warnings.
  2. Create warning log message, when the deprecated method is executed. Users, maintainers and developers are thereby warned about the deprecation.
  3. Create error log message, in order to create urgency.
  4. Create feature flag for function and enable function by default.
  5. Make the feature disabled by default via the feature flag.
  6. Drop support for the function and mark it as unsupported.
  7. Move the deprecated function to another project, so it's not included in the project. Instead the function will be injected into the project via the other project. This step may not be important and may be ignored.