Global Apex classes and methods are really troublesome in managed packages. Once you create the class or method and include it in a managed package you are stuck with it. This is really troublesome when developing a managed package in an agile way.
The platform needs to be updated to introduce a mechanism that doesn't require any intervention by Salesforce and that can be applied by the ISV who created the managed package.
My suggestion is as follows:
- Allow the vendor to mark a class or method as deprecated, setting a termination threshold - this threshold could be "at version X" or "after date Y". There would be specific constraints applied to these values by Salesforce (e.g. for version-based it may require a major version change, whilst for date-based it may require the date to be at least 6 months away, for example)
- Permit deprecated classes/methods to be modified during this period (e.g. for bug fixes)
- Once the period has elapsed (or the version has been reached) the class or method can be deleted from the managed package (or can be changed from global to public, for example).
The current mechanism is, to me, an anti-pattern as it does not allow the software to cleanly evolve with changing requirements and customer needs. Clearly, it has the benefit that a customer's usage of a global from a managed package will continue to "compile", but this doesn't mean that the customer's usage will actually function as expected (it is common to work around this limitation by basically retaining the global but emptying its body so it becomes a "no op").
By introducing this process, managed package developers are more likely to maintain out-of-date code in the short-term (e.g. with bug fixes) knowing that there is an horizon after which it can be cleanly expunged from the managed package. Additionally, the customer could automatically receive a report of newly deprecated or removed globals each time they install a version of the managed package so they can plan accordingly.