Swing is dead! Long live Swing.

M

markspace

I've been frequently annoyed by tools that do their binding by matching
Strings to classes or component names, because every time you move,
refactor or mistype something you're bound to get screwed. And it likes
to happen in the worst possible moments. I'd rather avoid it, if I have
the choice.


I tend to agree, strongly. For situations where I might be tempted to
just use strings, I try to substitute enums. For example, instead of

bind( someComponent, "event-name" );

I'd use this:

bind( someComponent, Events.NAME );

It provides automatic syntax checking, and is much easier to refactor if
names need to be changed or moved around later.

Any thoughts on this idea?
 
L

Lew

Wanja said:
asandstrom3minus1 says...


Of course not, but in this case you've got the choice between letting
the compiler (or let's say the IDE's background compilation) take care
of something or not.
I've been frequently annoyed by tools that do their binding by matching
Strings to classes or component names, because every time you move,
refactor or mistype something you're bound to get screwed. And it likes
to happen in the worst possible moments. I'd rather avoid it, if I have
the choice.

+1

Why use string-based binding like that in Java, among whose main strengths is
rigorous type safety?

Sometimes in frameworks you'll do that, e.g., name an implementing class in a
properties or XML configuration file, but the cost is always deferral of
less-expensive compile-time safety to later, more costly run-time type
failures. The benefit had better be worth it, and also worth the fragmentation
of logic across more source artifacts.

I've seen the sacrifice made in code, too. That's just an execration. One
egregious example I saw used reflection and casting to obtain a no-argument
constructor based on matching class names to certain other class names, but
still requiring casting through those same types. They sacrificed type safety,
performance, simplicity and good sense to create a "factory" that had none of
the benefits of an actual factory.

Prefer compile-time type assertions to run-time matchups.
 
L

Lew

markspace said:
I tend to agree, strongly. For situations where I might be tempted to just use
strings, I try to substitute enums. For example, instead of

bind( someComponent, "event-name" );

I'd use this:

bind( someComponent, Events.NAME );

It provides automatic syntax checking, and is much easier to refactor if names
need to be changed or moved around later.

Any thoughts on this idea?

+1
 
A

Arne Vajhøj

I tend to agree, strongly. For situations where I might be tempted to
just use strings, I try to substitute enums. For example, instead of

bind( someComponent, "event-name" );

I'd use this:

bind( someComponent, Events.NAME );

It provides automatic syntax checking, and is much easier to refactor if
names need to be changed or moved around later.

Any thoughts on this idea?

The idea is perfect.

But I don't think it is possible for the Java-FXML scenario.

Arne
 
A

Arved Sandstrom

+1

Why use string-based binding like that in Java, among whose main
strengths is rigorous type safety?

Sometimes in frameworks you'll do that, e.g., name an implementing class
in a properties or XML configuration file, but the cost is always
deferral of less-expensive compile-time safety to later, more costly
run-time type failures. The benefit had better be worth it, and also
worth the fragmentation of logic across more source artifacts.

I've seen the sacrifice made in code, too. That's just an execration.
One egregious example I saw used reflection and casting to obtain a
no-argument constructor based on matching class names to certain other
class names, but still requiring casting through those same types. They
sacrificed type safety, performance, simplicity and good sense to create
a "factory" that had none of the benefits of an actual factory.

Prefer compile-time type assertions to run-time matchups.
I agree with you guys in general, but I'm not sure I see the problem for
the situation we are discussing. Whether it's FXML or Facelets XHTML in
JSF, or XAML over in .NET land [1], you're talking about things that
have strong mappings to the code-behind (whether Java or C#).

There is no need to discover only at _runtime_ that your "strings" were
wrong. Both JSF Facelets XHTML and FXML are amenable to having a great
deal of rigorous checking done by hypothetical toolsets before the
underlying Java ever gets compiled. If a particular method in a
particular Java class is called for, that can be checked in principle
before building.

If your hypothetical tool is "screwing you" every time you make a typo
or other mistake when moving, renaming or otherwise refactoring things,
then I suggest that the hypothetical tool sucks...to use technical
terminology. As an example, let's say I've got EL in a JSF Facelets page
that references a couple of managed beans. So you've got references to
the @ManagedBean or @Named names, to the getters/setters in those
classes, and to action methods. You're seriously telling me that a
decent tool couldn't solidly track the reference bindings and do proper
refactorings for that stuff?

Same goes for FXML: where elements of FXML are references to Java
things, a proper tool can clearly maintain the mappings between FXML and
Java.

Surprise, surprise: you actually do have some tools out there that
competently do stuff like this, like IntelliJ IDEA for JSF 2.0.

And you know, you can thoroughly mess up when renaming, moving or
otherwise refactoring in a pure Java environment too, and all your
compiler will tell you is in how many places you now have a mistake.
I've seen plenty of cases where developers - myself included - thought
they knew all the usage sites of something, and figured to manually
refactor. In more than just a few cases that manual refactoring resulted
in something that *compiled* just fine, but was now erroneous, maybe
because you typo'd something. It can absolutely happen, easily actually.

So using *tool*-assisted refactoring makes much sense. In which case,
why is one kind of tool-assisted management OK and another kind bad?

AHS

1. XAML not the same thing as the other technologies I mention, but in
one of its uses, as a UI markup language in WPF, there are strong
similarities.
 
L

Lew

Arved said:
I agree with you guys in general, but I'm not sure I see the problem for
the situation we are discussing. Whether it's FXML or Facelets XHTML in
JSF, or XAML over in .NET land [1], you're talking about things that
have strong mappings to the code-behind (whether Java or C#).

There is no need to discover only at _runtime_ that your "strings" were
wrong. Both JSF Facelets XHTML and FXML are amenable to having a great
deal of rigorous checking done by hypothetical toolsets before the
underlying Java ever gets compiled. If a particular method in a
particular Java class is called for, that can be checked in principle
before building.

This approach works well, and tool choice is an important part of programming.

The key principle is to catch problems early and even earlier.
Compilation-level type safety is the strongest tool for that, when applicable.
Post-deployment tools are the weakest. What you describe is between those
extremes.

As I said in my post, there are use cases for offloading type checking from
the compiler. Your suggestions reduce the cost of that decision, making the
cost-benefit analysis tilt more in favor of doing such offloading.
If your hypothetical tool is "screwing you" every time you make a typo
or other mistake when moving, renaming or otherwise refactoring things,
then I suggest that the hypothetical tool sucks...to use technical
terminology. As an example, let's say I've got EL in a JSF Facelets page
that references a couple of managed beans. So you've got references to
the @ManagedBean or @Named names, to the getters/setters in those
classes, and to action methods. You're seriously telling me that a
decent tool couldn't solidly track the reference bindings and do proper
refactorings for that stuff?

I haven't seen anyone make that claim here. Have you? To whom is that question
addressed?

The egregious example I cited was not a case of a tool screwing them. It was a
case of custom fubaration of something simple into a right mess.

One claim I do make is that the further down from compilation to customer use
you go, the worse it is to catch and fix problems. I compared the endpoints;
you provided a midpoint in that spectrum. I do not claim, in fact explicitly
disclaimed that one should never pay such a cost. It's a question of what you
can afford and what it buys you, always.

The problem is that people often unwittingly pay more than they should, and
worse, get no benefit thereby. You must be aware.

With Java you are certain to have a compiler and a runtime. I certainly would
never espouse relying only on those two tools as if none others exist, but the
more you can get the compiler to do, without sacrificing what you need, the
cheaper it is to be right.
Same goes for FXML: where elements of FXML are references to Java
things, a proper tool can clearly maintain the mappings between FXML and
Java.

Surprise, surprise: you actually do have some tools out there that
competently do stuff like this, like IntelliJ IDEA for JSF 2.0.

Does it work with FXML?
And you know, you can thoroughly mess up when renaming, moving or
otherwise refactoring in a pure Java environment too, and all your
compiler will tell you is in how many places [and precisely where! - ed.] you now have a mistake.

Right, but at least you know at compilation and not later.
I've seen plenty of cases where developers - myself included - thought
they knew all the usage sites of something, and figured to manually
refactor. In more than just a few cases that manual refactoring resulted
in something that *compiled* just fine, but was now erroneous, maybe
because you typo'd something. It can absolutely happen, easily actually.

Doesn't IntelliJ reduce the cost of refactoring? Why not use its capabilities
for that?

No one is claiming that compilers and type safety solve all problems. What are
you hoping to prove? The fact remains that errors that *are* caught at
compilation are cheaper to fix than those caught later. The ones that are
missed don't change that.
So using *tool*-assisted refactoring makes much sense. In which case,
why is one kind of tool-assisted management OK and another kind bad?

I'm on your side with this question.
 
A

Arne Vajhøj

Arved Sandstrom wrote: ....
One claim I do make is that the further down from compilation to
customer use you go, the worse it is to catch and fix problems. I
compared the endpoints; you provided a midpoint in that spectrum. I do
not claim, in fact explicitly disclaimed that one should never pay such
a cost. It's a question of what you can afford and what it buys you,
always.
No one is claiming that compilers and type safety solve all problems.
What are you hoping to prove? The fact remains that errors that *are*
caught at compilation are cheaper to fix than those caught later. The
ones that are missed don't change that.

I agree with the principle of earlier is better.

But note that an inconsistency between Java and FXML will
cause an exception every time the scene is attempted to be
displayed.

I will expect GUI developers to try and run their GUI at least once
before considering a change to be done.

So the practical difference between compile time error and runtime
error in this specific case is not as big as in many other cases.
Does it work with FXML?

I would assume not.

I would also assume that tools for FXML will show up if/when
JavaFX becomes popular.

Arne
 
L

Lew

Arne said:
I agree with the principle of earlier is better.

But note that an inconsistency between Java and FXML will
cause an exception every time the scene is attempted to be
displayed.

I will expect GUI developers to try and run their GUI at least once
before considering a change to be done.

So the practical difference between compile time error and runtime
error in this specific case is not as big as in many other cases.

I was careful to use the term "compilation to customer". You're still talking
about a point well before customer exposure. You do illustrate that there's a
continuum involved.

I reiterate that compile-time checks are not going to catch everything. I
reiterate the point others including you make that there are stages between
compilation and customer. I reiterate that along that continuum are many
useful steps, and I concur that they're all needed.

Everything is about cost-benefit. You have so much time and energy in a
project to fix bugs, refactor, add features, and do QA. QA cannot be all
manual and catch everything after the fact, even at the penultimate stage
before customer deployment. As much as possible (but no more) must be pushed
to compilation and other early at-developer-desk stages. As much as possible
(but no more) of what's left must be pushed to early integration testing. As
much as possible (but no more) of what's left must be pushed to later
pre-deployment testing. As much as possible (but no more) of all that testing
must be automated. As little as possible (and even less) must go wrong at the
customer site.

Some might argue that "must" is too strong; "should" will suffice. To those I
say sure, if you aren't motivated to do the most good for the least effort and
cost, by all means use "should".
I would assume not.

I would also assume that tools for FXML will show up if/when
JavaFX becomes popular.

The whole point of the "use tools!" rant is sort of moot if the tools aren't
ready yet.
 
A

Arne Vajhøj

I was careful to use the term "compilation to customer". You're still
talking about a point well before customer exposure. You do illustrate
that there's a continuum involved.

I reiterate that compile-time checks are not going to catch everything.
I reiterate the point others including you make that there are stages
between compilation and customer. I reiterate that along that continuum
are many useful steps, and I concur that they're all needed.

Everything is about cost-benefit. You have so much time and energy in a
project to fix bugs, refactor, add features, and do QA. QA cannot be all
manual and catch everything after the fact, even at the penultimate
stage before customer deployment. As much as possible (but no more) must
be pushed to compilation and other early at-developer-desk stages. As
much as possible (but no more) of what's left must be pushed to early
integration testing. As much as possible (but no more) of what's left
must be pushed to later pre-deployment testing. As much as possible (but
no more) of all that testing must be automated. As little as possible
(and even less) must go wrong at the customer site.

Some might argue that "must" is too strong; "should" will suffice. To
those I say sure, if you aren't motivated to do the most good for the
least effort and cost, by all means use "should".

Many words.

And it is correct.

It is just not going to make much difference in this case.

Arne
 
A

Arne Vajhøj

It is true that we do not know what version of Java SE it will be in.
Nor do we know when that version will be available as a standard. And
we obviously do not know when all Java implementations has implemented
that standard (for some server platforms 1-2 years delay is common).

But Oracle has said that it will be part of SE.

And as I read the docs then Oracle has started distributing
JavaFX with JRE from 7u2.

http://www.oracle.com/technetwork/java/javafx/downloads/index.html

<quote>
Starting with Java SE 7 Update 2 and JavaFX 2.0.2, the JavaFX Runtime is
co-installed every time the JRE is installed.
</quote>

(that must be for Windows only)

To me that is about as good as it an be for a non-paying customer.

Actually Oracle has announced something now.

http://www.infoworld.com/slideshow/28552/java-roadmap-oracles-two-year-plan-185238

Slide 7

<quote>
Summer 2013: JDK 8

This release features modular capabilities via Project Jigsaw, as well
as JavaScript interoperability, Java Virtual Machine convergence, JavaFX
3.0, and Java closures capabilities and bulk parallel operations via the
Lambda project.
</quote?

So JavaFX 3.0 - Java SE 8 - summer 2013.

If everything works out as planned. Software projects
has been delayed before! :)

Arne
 
L

Lew

Wanja said:
I think the same way.
I'm even going further and strongly propose preferring Enums to boolean
parameters and this is why:
http://brixomatic.wordpress.com/2010/02/24/boolean-harmful/

+1

This might irritate those who already find Java verbose, since 'String's are
more compact to declare, but type safety and refactorability [sic] is a payoff
in many situations.

I'm even worse, because I pump a "friendly" string representation into the enum.
<http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#toString()>
«An enum type should override this method when a more "programmer-friendly"
string form exists.»

Necessitating a corresponding 'public static E fromString(String rep)'.

'fromString()' compares 'toString()' strings first; if those fail it delegates
to 'valueOf()'.

<sscce source="eegee/Essential.java">
package eegee;
/**
* Essential {@code enum} implementation with "friendly" representation.
*/
public enum Essential
{
FOO("foo"),
BAR("bar"),
FANCY("fancy form"),
ANOMALY("useful to hold log or error messages"),
;
private static final long serialVersionUID = 1L;

private final String representation;

/**
* Constructor setting the friendly representation.
* @param rep String friendly representation of constant.
*/
private Essential(String rep)
{
this.representation = rep;
assert this.representation != null;
}

@Override
public final String toString()
{
return representation;
}

/**
* Look up enum constant from String representation.
* @param rep String representation of enum constant.
* @return Essential constant matching the representation.
*/
public static Essential fromString(String rep)
{
if (rep == null)
{
return null;
}
for (Essential value : values())
{
if (rep.equals(value.toString()))
{
return value;
}
}
return valueOf(rep);
}
}
</sscce>
 
A

Arved Sandstrom

I think the same way.
I'm even going further and strongly propose preferring Enums to boolean
parameters and this is why:
http://brixomatic.wordpress.com/2010/02/24/boolean-harmful/

Kind regards,
Wanja
This little sub-thread I would have re-declared a few posts ago. You
guys are advancing good ideas, but confusing the issue by making it
sound like, in the context of the original discussion, that the end-user
developer of FXML is going to be worried about these details when in
fact he or she is not: it's the tools builder who is.

That changes the discussion radically. Tools often use techniques and do
things which sometimes cannot be recommended for the developer pool at
large, because they are tricky and/or dangerous, and only above-average
programmers ought to be doing things like that.

I happen to agree in general that you use enums when you can. I don't
see what these recommendations for Joe Average Coder have to do with a
discussion of potential tool support for FXML.

AHS
 
D

Daniel Pitts

Wanja said:
I think the same way.
I'm even going further and strongly propose preferring Enums to boolean
parameters and this is why:
http://brixomatic.wordpress.com/2010/02/24/boolean-harmful/

+1

This might irritate those who already find Java verbose, since 'String's
are more compact to declare, but type safety and refactorability [sic]
is a payoff in many situations.

I'm even worse, because I pump a "friendly" string representation into
the enum.
<http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#toString()>
«An enum type should override this method when a more
"programmer-friendly" string form exists.»
I'm even worse than that. My designs often include replacing a boolean
with an Enum that has *logic* in it. Flyweight strategy pattern.

public enum FooStrategy {
ONE_WAY {
public void handle(Foo foo) {
foo.doItOneWay();
}
},

ANOTHER {
public void handle(Foo foo) {
foo.doItAnother();
}
}
;
public abstract void handle(Foo foo);
}

This is more verbose but ends up being more flexible and easier to
maintain. Enums can even implement interfaces, so you could add
additional layer of abstraction which allows custom or statefull
implementations alongside the the enum implementations.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top