Proposal: Deprecate Builders
Tom Eugelink
tbee at tbee.org
Mon Mar 25 23:55:54 PDT 2013
Since I do not develop frameworks much, all these problems are not familiar to me, so probably your experience is much more insightful. Suppose the following steps:
1. create a AbstractClass of every end node and let the end node extend that: Node extens AbstractNode<Node>
2. use a one time pass over all classes to add a wither method for each setter (this is not something that is done on every build).
That would result in the following example class hierarchy. Let's also assume an interface NewNode2 with default methods having been added to Node:
abstract class AbstractNode<T> implements NewNode2<T> {
final public void setName(String v) { ... }
final public T withName(String v) {
setName(v);
return (T)this;
}
}
Node extends AbstractNode<Node>{
...
}
Region extends AbstractRegion<Region> {
...
}
AbstractRegion<T> extends AbstractParent<T> {
...
}
AbstractParent<T> extends AbstractNode<T> {
...
}
interface NewNode2<T> {
final public void setDescription(String v) default { ... }
final public T withDescription(String v) default {
setDescription(v);
return (T)this;
}
}
How would this hold up?
Tom
On 2013-03-25 22:55, Richard Bair wrote:
> I don't follow? I think I need to see a concrete example of the inheritance / abstract class issue to. Also have you tried to maintain it with backwards binary compatibility with arbitrary 3rd party libraries? All the generic use cases that burned us were in this vein.
>
> How do you generate the setters? Annotation processors don't let you modify the incoming source file.
>
> It seems like if you were going to do it, you'd have to manually add the "wither" methods, and they must not be final so that subclasses can override them to return the covariant type. I've been told many times over the years of various solutions to these inheritance problems and not a single approach so far has stood up to the test of time. They've all failed on one or another of these (in fact , our current pain stems from these)
>
> - I must be able to add new methods in new releases and old code must still link and run against the new release
> - I must be able to add a new parent class into the inheritance hierarchy, and old code must still link and run against the new release
> - I must be able to move methods from the subclass to a super class and the old code must still link and run against the new release
> - I must be able to define "wither" methods on interfaces which, when implemented on a class, can return the right type
>
> That's a least a starting point. Do you have a proposal that satisfies these use cases?
>
> Richard
>
> On Mar 25, 2013, at 2:08 PM, Tom Eugelink <tbee at tbee.org> wrote:
>
>> LOL. Than I won't mention that I've been using this casting-generic approach for years without problems. I also won't mention that you can pretty much generate withers from setters using a bit of regexp pattern matching. The only thing real step are the abstract classes.
>>
>> To react to the points Michael makes in the issue:
>> 1. Inherited properties are solved by the casting-generics thingy.
>> 2. Setting readonly properties... Interesting concept. I figure that's what constructors are for?
>> 3. Well, it's not like lamba's or anonymous constructors are examples of insightful coding ;-) I think there are far more confusing concepts in Java than dual setter methods. Usually people catch on pretty fast.
>>
>> Tom
>>
>>
>> On 2013-03-25 21:31, Richard Bair wrote:
>>> Ya it was a good read (thanks Ali). I think Michael does a good job recounting the problems with this approach. I wouldn't use generics for it (I don't trust them for this kind of thing -- stay in the mainstream usage and generics are great, start getting clever and we've been burned over and over. I don't believe anybody when they tell me it will work any more :-)). Instead override with covariant return types.
>>>
>>> I think that is possible, but it would be painful to add all the withers to all the properties for the entire public API. But I do think that once we've got the builders deprecated, we can then take a long look at what to do instead -- using lambdas for example. There might be other ways to get what we want that are much less intrusive. Or maybe just have an annotation processor that will auto-generate the builders of your choice and let it be a 3rd party thing.
>>>
>>> Richard
>>>
>>
More information about the openjfx-dev
mailing list