tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Wyraz <michael.wy...@evermind.de>
Subject Re: Make more fields/methods of service classes protected
Date Mon, 12 May 2014 08:54:31 GMT
> for extending tapestrys internal service classes it's often required to
>> copy a lot of code because almost everything is private. Why not
>> changing it to protected to allow others to extend those classes?
> Because it makes keeping backward-compatibility way harder and that's 
> very important for the project.
Protected methods are normally not part of the official stable api. So 
there's no difference for maintaining backward compatibility. I don't 
see any drawback here

> Not to mention that protected fields are something to be avoided in OOP.
That's true for fields in some cases, right. But IMO does not apply to 
most methods. Especially in service classes where certain functionality 
is moved to methods - here one of the most powerful oop concepts is to 
override those methods to change behaviour. Of course the most advanced 
way would be to have an abstract basic implementation of each service 
plus implementions of each aspect of that service. But that would be 
much overhead in most cases.

> In addition, you can use advise or overriding for dealing with most 
> problems. 
Sure, one can use advice to achieve basically the same. But this will 
cause much more problems:
- same backward compatibility issue as if you would override internal 
- but you would not get a compiler message about this. Instead the 
behaviour would silently fall back to the default. Bad thing!
- Much more (and much less readable) complex code for trivial changes.

Overriding is only a solution if you have a drop-in replacement for a 
service. That means in most cases that you have to copy a service and to 
a change there.

Another similar problem are final methods. Last week we created a few 
custom form field components and we started with extending AbstractField 
which contains most required stuff. All was fine until we wanted to 
change the label behaviour:
- if a "label" parameter is bound, use this
- otherwise check a custom service
- otherwise check the bound parameter for a label annotation
- otherwise use defaultLabelProvider

But... defaultLabel() is package protected + final. So we cannot:
- override the method
- test if the parameter is bound (bound is always true when a 
defaultParam() method exists)

So I had to copy the whole AbstractField component to do the simple 
change. Alternatively I'd have to change/decorate 
ComponentDefaultProvider but this would change the behaviour in all 
components, not just those special ones.

So how should one solve such problems if so many methods are private (or 
package protected) and/or final?

Kind regards,

To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org

View raw message