robotlegs/robotlegs-framework — Issue #51: RL2 Protected Members
Author: darscan
Created: 2011-11-04 12:47:49+00:00
State: open

Robotlegs v1 enabled framework extension by exposing protected methods that could be overridden. I believe this was a fundamental design flaw.

Firstly, those protected members then became part of the API and we couldn't change them in minor or patch releases without breaking our semantic versioning.

Secondly, encouraging extension in itself was a mistake as it lead to inheritance lock-in nightmares. Think: SignalEnabledCovariantMediationMacroCommandContext.

As Robotlegs v2 focuses on Composition Over Inheritance, I propose switching to private members wherever possible.

"But what if I want to make a specialised MediatorMap/CommandMap etc?"

If extension by inheritance seems like the only answer, then we've designed those extensions incorrectly. They should be flexible enough to have new features installed without requiring extension.

For example, with the CommandMap we now have CommandTriggers that decouple the CommandMap itself from the specific requirements of Events/Signals. One does not need to extend CommandMap to add Signal support.

Guards and Hooks should also allow for greater flexibility without requiring extension.

Another way to look at it is like this:

RL1 provided interfaces for the core framework apparatus and default implementations. Users coded against those interfaces expecting things to work in the documented fashion. If somebody came along and provided a modified (or completely different) implementation that conformed to the same interface, then the behaviour of that apparatus would be different without being explicit.

For framework apparatus we want provable, reliable *behaviour*. By providing an Interface and a default implementation with protected members we're effectively saying: "Here, this API is perfect, but the implementation might not be, so feel free to extend/modify/replace the implementation". But if the implementation provided by the framework is wrong, surely we should fix it at the source directly?