JavaFX and the Missing Interfaces
Randahl Fink Isaksen
randahl at rockit.dk
Wed Nov 7 13:27:53 PST 2012
Thanks, Daniel. Well said.
R.
On Nov 7, 2012, at 21:19 , Daniel Zwolenski <zonski at gmail.com> wrote:
> Hi Randahl,
>
> I agree with your idea and would prefer if jfx followed your design. There's no doubts it would make for a much nicer code on the developers end in many situations (such as the example you gave).
>
> I think the big difference between JFX and a normal third party library that we're used to (ie that we bundle into our app as a jar) is that jfx is built in to the JRE. As such it has a lot more restrictions and caveats around it. Decisions around changing jfx are going to be as constrained as those to change the collections API, etc. Touch nothing, break nothing.
>
> Once something is in the JFX codebase I think we will be largely stuck with it (or at least it will be very hard/slow to change). It's different to a normal library like, say, Hibernate or Struts, where they can just say "version 3 has some incompatibilities with 2, sorry. Here's the steps to upgrade your code when you're ready". Applets are a great example, essentially dead but Richard is stuck supporting them for the next 10 years.
>
> Swing was the same and this was one reason why we saw so little improvements to Swing at the API level over the last 13 years. Jfx will likely have to be just as slow and cautious to evolve (Project Jigsaw may allow some loosening here, but it's hard to say).
>
> So in this context, while I totally agree with you, I think that unfortunately Richard has the right of it and being painfully over defensive in this area is a necessary evil, even at the cost of making a less elegant and versatile system to use. The class hierarchy restricts us as developers but gives Richard just a tiny bit of room to make changes/enhancements without breaking running code out there. It's the cost of being part of the JRE.
>
> Not sure if that helps you at all but I've had a lot of frustration around stuff like this with jfx and it took me a long while to get where Richard was coming from. Sometimes it's just good to hear that essentially your proposal was a good one with a lot of merit, etc, and it's just the unusual context that rules it out. For my money, in this case, your proposal is exactly that.
>
>
>
>
>
> On 08/11/2012, at 4:23 AM, Randahl Fink Isaksen <randahl at rockit.dk> wrote:
>
>> Fair enough.
>>
>> Thanks for taking your time to review my suggestion.
>>
>> Randahl
>>
>>
>> On Nov 7, 2012, at 16:51 , Richard Bair <Richard.Bair at oracle.com> wrote:
>>
>>> In my opinion the use case doesn't justify the additional complexity in API or guaranteed future API breakage. In particular, I am sure that the proposed solution would never past muster with the policies on compatibility with the JRE (it isn't enough to document that the only legitimate implementations of these interfaces are our own concrete node types). Java isn't know for its brevity, and since there is another way of enforcing your requirements, that is probably the best way to go.
>>>
>>> Thanks
>>> Richard
>>>
>>> On Nov 7, 2012, at 3:02 AM, Randahl Fink Isaksen <randahl at rockit.dk> wrote:
>>>
>>>> Apologies Richard, I accidentally switched two words in my last mail which totally confused my point, so here is what I meant:
>>>>
>>>>
>>>> We don't need Java 8 for this. With any version of Java you can create interfaces and helpful base classes which implement them, so people don't have to. What I would like to see is
>>>>
>>>> class Node ---- implements ----> interface SceneNode
>>>>
>>>> Since everyone always extend Node (directly or indirectly) you can evolve SceneNode with new methods without breaking anything, as long as the method is implemented by class Node, and thereby transitively by everyone else.
>>>>
>>>> I am aware that this is not important for JavaFX internally, but it is very important to me as a third party framework developer, because the SceneNode interface allows me to invent new kinds of nodes while still guaranteeing that they are in fact nodes, e.g.
>>>>
>>>> InternationalizedNode extends SceneNode {
>>>> void somethingRelatedToI18n();
>>>> ...
>>>> }
>>>>
>>>> Without the SceneNode interface, there is no way I can guarantee that an InternationalizedNode is indeed a real Node and not just a HashMap or a URL or what not.
>>>>
>>>> Today my framework works like this
>>>>
>>>> class SomeClass {
>>>> public void doSomethingWithAnInternationalizedNode(InternationalizedNode node) {
>>>> if(!(node instanceof Node))
>>>> throw TheNodeIsNotANodeException();
>>>> Node indeedANode = (Node) node;
>>>> double width = node.getWidth();
>>>> }
>>>> }
>>>>
>>>> If you added the SceneNode interface I could let InternationalizedNode extend the SceneNode interface and all of the code above could be replaced with
>>>>
>>>> class SomeClass {
>>>> public void doSomethingWithAnInternationalizedNode(InternationalizedNode node) {
>>>> double width = node.getWidth();
>>>> }
>>>> }
>>>>
>>>> Cheers yourself
>>>> Randahl
>>>>
>>>>
>>>> On Nov 6, 2012, at 15:48 , Richard Bair <Richard.Bair at oracle.com> wrote:
>>>>
>>>>> But that approach would only be feasible in Java 8. Default methods really only work well though if the new method requires no state or can be a no-op by default (because the default method is static). For other types of methods you may add, you will break compatibility. I don't see the advantage to having interfaces cluttering up the namespace if in reality nearly everybody is just going to extend from Node anyway (which they'd have to, because Parent returns Nodes not SceneNodes, and that couldn't be changed).
>>>>>
>>>>> Cheers
>>>>> Richard
>>>>>
>>>>> On Nov 5, 2012, at 2:54 PM, Randahl Fink Isaksen <randahl at rockit.dk> wrote:
>>>>>
>>>>>> There is a solution to the problem of breaking compatibility when introducing new methods to an interface. That's what the default implementation is for. If you have class Node implement interface SceneNode, then it is my bet that virtually everyone will be extending Node when implementing SceneNode rather than starting from scratch. So you can add method x() to Node while adding an overridable default implementation of x() in SceneNode, and virtually no one will notice. You could even document that extending Node is a prerequisite fore ensured forwards compatibility for an application, and the burden would be off your shoulders.
>>>>>>
>>>>>> Randahl
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Nov 5, 2012, at 21:41 , Mark Fortner <phidias51 at gmail.com> wrote:
>>>>>>
>>>>>>> I guess the benefit of doing it this way is that it would make it easier to
>>>>>>> swap out implementations, and do unit testing/mocking. The downside if the
>>>>>>> API is changing frequently then every release is liable to break something.
>>>>>>> But that's why people have continuous integration servers. :-)
>>>>>>>
>>>>>>> Mark
>>>>>>>
>>>>>>> Cheers,
>>>>>>>
>>>>>>> Mark
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Nov 5, 2012 at 12:33 PM, Daniel Zwolenski <zonski at gmail.com> wrote:
>>>>>>>
>>>>>>>>> Maybe somebody can show how this would work in more concrete terms? I
>>>>>>>>> don't even see how it would be practical at all.
>>>>>>>>>
>>>>>>>>
>>>>>>>> As in how it would be used by end developers and to what benefit, or as in
>>>>>>>> how to make it workable in the current JFX codebase?
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>> Richard
>>>>>>>>>
>>>>>>>>> On Nov 5, 2012, at 12:20 PM, Daniel Zwolenski <zonski at gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> +1
>>>>>>>>>>
>>>>>>>>>> I think we've had this conversation before. Maybe something to do with
>>>>>>>>> interfaces being too brittle where if you add a method anyone
>>>>>>>> implementing
>>>>>>>>> it will now be missing a method, whereas with a base class they can add a
>>>>>>>>> stub method?
>>>>>>>>>>
>>>>>>>>>> Other frameworks use interfaces extensively though (eg Spring,
>>>>>>>>> java.util.Collections), generally with positive outcomes.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 06/11/2012, at 5:50 AM, Randahl Fink Isaksen <randahl at rockit.dk>
>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> I have been struggling with a number of problems stemming from the way
>>>>>>>>> JavaFX is designed – specifically the lack of interfaces for many of the
>>>>>>>>> extension points in the class hierarchy.
>>>>>>>>>>>
>>>>>>>>>>> It takes some thorough explaining with code examples, so instead of
>>>>>>>>> just an unformatted e-mail I posted a more readable explanation of the
>>>>>>>>> problem on-line:
>>>>>>>>>>> Please read
>>>>>>>>> http://blog.randahl.dk/2012/11/javafx-and-missing-interfaces.html
>>>>>>>>>>>
>>>>>>>>>>> I hope we could have a constructive discussion on this matter on this
>>>>>>>>> list before I go ahead and file a Jira, so the Jira issue becomes the
>>>>>>>> best
>>>>>>>>> possible basis for solving the design problem.
>>>>>>>>>>>
>>>>>>>>>>> Thanks
>>>>>>>>>>>
>>>>>>>>>>> Randahl
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
More information about the openjfx-dev
mailing list