The fireValueChangedEvent method is a protected, non final method found in all the *PropertyBase classes and the ReadOnly*Wrapper classes and is part of public API.
It is used in three ways:
1) Internally by these classes to trigger listeners when the property becomes invalid. In these cases `invalidated` is called just before it calls `fireValueChangedEvent`. Note that `invalidated` is an empty protected method that be overridden to be informed of invalidations without needing to allocate an InvalidationListener.
2) To trigger the firing of listeners on demand (whether there was a change or not) which will always fire invalidation listeners regardless of whether the property was valid or not. This is used for light-weight read only properties, or linked properties (like the dual property read only wrapper implementations). These are properties that don't have an actual value of their own, but get their value from another property or a field directly.
3) To be informed of invalidations by (carefully) overriding the method (carefully because not calling super() means you break basic functionality of the property class, see case 1).
The three different usages are limiting the evolution of the property classes; the property classes can't change the implementation or parameters of `fireValueChangedEvent`
# Alternatives to Provide
Case 1. No alternative needed, after removal of `fireValueChangedEvent` the affected classes can use a more direct approach of firing listeners or use a private method
Case 2. The primary use case requiring the external triggering of listeners is for light-weight read-only property implementations. They all merely use a read only property for its listener tracking functionality, and to fire these listeners on demand. The actual value for these implementations is stored in a field directly, saving having to use a heavier ReadOnly*Wrapper.
In order to facilitate this use case, only property implementations that have no state of their own, should offer a new **final** `fireValueChangedEvent(T oldValue)` method. This method should be protected and require providing the old value in order to fire listeners without having to track the old value in the listener management code. This makes these properties even lighter as the old value is readily available for all these cases. This also makes more sense, as firing listeners should not be done arbitrarily but there should be a real reason and change to do so.
Case 3. For this purpose an alternative already exists in the form of the empty protected `invalidated` method. It can be overridden without breaking basic functionality of the class involved.
# Deprecation steps
1. Deprecate `fireValueChangedEvent` on all the above classes and implement the alternative described in case 2. Update docs and point to the appropriate alternatives.
Internal properties that use this functionality that can't be publicly subclassed can and should be switched immediately to use the new alternatives. For most cases this will provide immediate benefits as a simpler method can be used to inform listeners that does not require tracking old values.
2. After an appropriate time, remove the deprecated methods. Now the *PropertyBase classes can also start using a simpler method of informing listeners without old value tracking.
# Net Result of this change
- The entanglement of the various concerns and use cases of `fireValueChangedEvent` is resolved allowing more freedom to evolve the classes involved. The alternatives provided do not suffer the same problems, as a good API design rule is now followed (protected methods should not have essential functionality in their default implementations unless final).
- Listener notification becomes simpler and less error prone, leading to simpler code, less memory usage and performance improvements:
- Tracking old values when listeners are added/removed while listener holders can morph from lists to single listeners is a complicated process which had various bugs since its inception
- Tracking old values effectively stores state twice (in the listener manager and in the property itself) which is wasteful
It is used in three ways:
1) Internally by these classes to trigger listeners when the property becomes invalid. In these cases `invalidated` is called just before it calls `fireValueChangedEvent`. Note that `invalidated` is an empty protected method that be overridden to be informed of invalidations without needing to allocate an InvalidationListener.
2) To trigger the firing of listeners on demand (whether there was a change or not) which will always fire invalidation listeners regardless of whether the property was valid or not. This is used for light-weight read only properties, or linked properties (like the dual property read only wrapper implementations). These are properties that don't have an actual value of their own, but get their value from another property or a field directly.
3) To be informed of invalidations by (carefully) overriding the method (carefully because not calling super() means you break basic functionality of the property class, see case 1).
The three different usages are limiting the evolution of the property classes; the property classes can't change the implementation or parameters of `fireValueChangedEvent`
# Alternatives to Provide
Case 1. No alternative needed, after removal of `fireValueChangedEvent` the affected classes can use a more direct approach of firing listeners or use a private method
Case 2. The primary use case requiring the external triggering of listeners is for light-weight read-only property implementations. They all merely use a read only property for its listener tracking functionality, and to fire these listeners on demand. The actual value for these implementations is stored in a field directly, saving having to use a heavier ReadOnly*Wrapper.
In order to facilitate this use case, only property implementations that have no state of their own, should offer a new **final** `fireValueChangedEvent(T oldValue)` method. This method should be protected and require providing the old value in order to fire listeners without having to track the old value in the listener management code. This makes these properties even lighter as the old value is readily available for all these cases. This also makes more sense, as firing listeners should not be done arbitrarily but there should be a real reason and change to do so.
Case 3. For this purpose an alternative already exists in the form of the empty protected `invalidated` method. It can be overridden without breaking basic functionality of the class involved.
# Deprecation steps
1. Deprecate `fireValueChangedEvent` on all the above classes and implement the alternative described in case 2. Update docs and point to the appropriate alternatives.
Internal properties that use this functionality that can't be publicly subclassed can and should be switched immediately to use the new alternatives. For most cases this will provide immediate benefits as a simpler method can be used to inform listeners that does not require tracking old values.
2. After an appropriate time, remove the deprecated methods. Now the *PropertyBase classes can also start using a simpler method of informing listeners without old value tracking.
# Net Result of this change
- The entanglement of the various concerns and use cases of `fireValueChangedEvent` is resolved allowing more freedom to evolve the classes involved. The alternatives provided do not suffer the same problems, as a good API design rule is now followed (protected methods should not have essential functionality in their default implementations unless final).
- Listener notification becomes simpler and less error prone, leading to simpler code, less memory usage and performance improvements:
- Tracking old values when listeners are added/removed while listener holders can morph from lists to single listeners is a complicated process which had various bugs since its inception
- Tracking old values effectively stores state twice (in the listener manager and in the property itself) which is wasteful