Design Patterns

A

Arne Vajhøj

Logging is another one. They thing about all those is that there is a
globally accessible shared instance, but that doesn't have to be
enforced by the class itself. Rather, the life-cycle of the object is
managed externally.

Self-managed life-cycles should be very rare. For instance, something
which actually manages external resources may need to enforce some
invariants about its life-cycle, in order to manage external state in a
sane manor. This isn't something an application programmer need worry
about on a frequent basis.

It does not need to enforce it by itself. But I do not see a real
problem of it doing it.

If one is already using a framework that can provide the functionality
then fine. But I would not add a framework to avoid writing the
singleton boilerplate.
I'm *not* a fan of a global Configuration object for many reasons. One
is that the configuration class becomes overly involved with the rest of
the application. At least, if they treat it as a place to "go grab some
settings". If the settings are injected, then that's a different story.

Up to a certain level I would prefer a single configuration
over multiple configurations.

Arne
 
A

Arne Vajhøj

Here's two patterns I see in JEE programming a lot.

1. Global context. All of your important objects are put into a global
context object and then are accessible. In JEE this is similar to a
Map: you put in objects identified by strings and retrieve them the same
way.

globalContext.put( "my window", object );
thing = globalContext.get( "my window" );

In a less general framework, I'd divide this into major sections (GUI,
business logic, config, maybe logging, persistence, etc.) and possibly
provide some specialized logic for each.

The global context should passed into objects somehow, similar to the
ctor we discussed earlier.

It is common.

But I would hesitate using it for OP's problem.
2. Factories. You can also just have a factory object, which is
ultimately a static method.

thing = GuiFactory.getWindow( "main window" );
- or -
thing = GuiFactory.getMainWindow();

In larger frameworks it's common for the static method to fetch another
factory, which then does the work of making objects for you. Obviously,
you have to load the main window into the factory at some point.

That is used all the time everywhere.
Personally I think factories are harder to work with, as they making
testing more difficult.

Typical factories are considered more test friendly than new.

Arne
 
A

Arne Vajhøj

AFAIK nested is sufficient.

A plain nested class does not have access to the local
variables.

If that is not needed then fine.

If that is needed then it has to be either a local
or anonymous class.

And local classes are very rare in the real world.

Arne
 
L

Lew

Arne said:
A plain nested class does not have access to the local
variables.

If that is not needed then fine.

If that is needed then it has to be either a local
or anonymous class.

Nitpick: or inner class.
And local classes are very rare in the real world.

Sort of. Named local classes are indeed rare. Anonymous local classes
are rather common.

public List<File> getFiles()
{
final FileFilter filter = new FileFilter()
{
@Override boolean accept(File f) { return f.isDirectory(); }
};
// instance of an anonymous local class implementing FileFilter
...
}

This is good Java idiom because the 'FileFilter' instance is GCable when
done. It hasn't got state so its cost is virtually nil. So the local class
feature gives you good control of a program's memory requirements.

In less educated programmers' code I've seen such implementors scoped at
instance or even (gasp) static member level. And then people wonder at the
heap requirements.

Java has a funky and nuanced type structure. If you take advantage of
the nuances you get a lot in return.

It helps to use JLS (Java Language Specification) terminology in its
exact, narrowest framing. Really. Some call all nested classes "inner"
classes. Nope. And anonymous classes can be member or local types. It's
all about scope and context.

The JLS has a detailed treatment, and somewhere out there floats a
brilliant infographic going back to 1.2-ish days, but here's a brief
taxonomy.

top level * {public, package},
nested {static, inner {member, local}} * {any access}

This is off the top of my head, so any corrections welcomed.

There's a lovely corner case involving

public class Containing
{
private void doSomething() {...}

public class Within extends Containing
{
// @Override // ?
public void doSomething()
{
Containing.this.doSomething();
// super.doSomething(); // ?
...
}
}
}
 
L

Lew

Arne said:
A general inner class does not - only local and anonymous classes
has.

That is untrue.

From the JLS:
"The scope of a declaration of a member m declared in or inherited by a class
type C (§8.1.6) is the entire body of C, including any nested type
declarations."

"It is a compile-time error if a static class contains a usage of a non-static
member of an enclosing class."

So all inner classes, being non-static, have access to all members of their
enclosing type.

Try it.
I don't call them "named local class" and "anonymous local class"
just "local class" and "anonymous class".

Well, that's just fine for you all by yourself, then.
But that is just terminology.

You say that as though terminology were anything less than crucial.

Look, this is Java. Use the Java terms, OK?

And as a service to everyone else trying to understand Java, do try not to
promote non-standard usage. You will only confuse people.
 
L

Lew

Lew said:
And as a service to everyone else trying to understand Java, do try not to
promote non-standard usage. You will only confuse people.

My bad, you are right and I am wrong.

From the JLS:
"A local class is a nested class (§8) that is not a member of any class and that has a name (§6.2, §6.7)."
 
A

Arne Vajhøj

That is untrue.

From the JLS:
"The scope of a declaration of a member m declared in or inherited by a class
type C (§8.1.6) is the entire body of C, including any nested type
declarations."

"It is a compile-time error if a static class contains a usage of a non-static
member of an enclosing class."

So all inner classes, being non-static, have access to all members of their
enclosing type.

Try it.

Why?

Local variable are not members!

Arne
 
A

Arne Vajhøj

Well, that's just fine for you all by yourself, then.


You say that as though terminology were anything less than crucial.

Look, this is Java. Use the Java terms, OK?

And as a service to everyone else trying to understand Java, do try not to
promote non-standard usage. You will only confuse people.

That is good advice.

I suggest you take it.

As I am using the terminology used by JLS.

Arne
 
L

Lew

Arne said:
That is good advice.

I suggest you take it.

As I am using the terminology used by JLS.

Indeed you are. As I admitted and corrected already.

I shall endeavor to do better.
 

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,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top