I’ve recently been spending a lot of my time coding in ruby, where the rules for private and protected methods are different to how they are in C++ (and ABAP). I would say that ruby is more ‘relaxed’ and people don’t often make something private in ruby as part of usual practise. In ruby accessors do behave differently by design, and this difference is well described by this quote from Lovable Lyle, “…in C++, “private” means “private to this class”, while in Ruby it means “private to this instance”.” ABAP is like C++ in this regard.
In ABAP, especially for developers who don’t work for SAP, PRIVATE methods and attributes in SAP standard code often are a source of difficulties.
Here is an example that I’d like to explore, taken from a CRM system:
Especially note the private attributes for constants. One almost could anthropomorhphize things, and say SAP must be really scared that I would want to change the values of those constants in child classes. That’s why they must be private!
I would make the argument that declaring these attributes protected would provide the best of both worlds, it wouldn’t stop usage by child classes, and would provide the encapsulation desired.
The example above is for a CRM controller. Such controller classes often have child classes, because when one enhances a view of a component, the system will automatically create a Z-controller (in my case it created ZL_CRMCMP_I_HIDDENVIEW_IMPL) which inherits from the parent controller.
For the example, I needed to use the CODE_MESSAGE constant (‘AbapErrorMessage’) in my custom logic so that it behaved similary to SAP standard. These were the choices I could think of, all of which have drawbacks:
- Enhance the parent class to make it a friend of the child
- Enhance the parent class to provide a protected or public accessor method for the attributes required
- Modify the parent class to make the attribute public
- Create an enhancement spot in the parent method, and insert the custom logic that I want there
- Make my code not behave like SAP standard
- Make my own local constant
I tend to avoid SAP standard code enhancements. Especially enhancements that are static. Such as making the parent a friend specifically of ZL_CRMCMP_I_HIDDENVIEW_IMPL, as this name might change if a new enhancement set were to be created.
It seems to me therefore that the latter option (“make my own local constant”), is the superior choice. The major worry with this approach is that if SAP had to change the value of the attribute in a future release to something like ‘AbapNewErrorMessage’ my code would silently break in a way that would be difficult to detect. If the parent attribute wasn’t private, but public, and could be referred to directly there would have been no concerns about upgrade changes causing breakage.
Now, one could make the argument that my example chosen has been cherry picked. Unfortunately, this is something that I have encountered many times, most commonly with the visiblity of methods rather than attributes.