Design Patterns

D

dougmmika

Hi to all

I'm writing an application and I have the following problem. When I write EventListeners I write them in seperate classes (and seperate files) for reasons of clearity. But these event listeners I want to modify other classes that aren't defined in the EventListeners. They already exist in the main program. The problem I have is how best to get these eventlisteners to know of these classes (which are also in seperate files)? Up to know I have used Singletons (I made the classes the event listeners were to modify global) but this seems ugly. How are java applications written to let the eventlisteners see the classes they are to modify (sometimes these classes are seperate application components in seperate files)?

I hope this makes sense
Doug
 
A

Arne Vajhøj

I'm writing an application and I have the following problem. When I
write EventListeners I write them in seperate classes (and seperate
files) for reasons of clearity. But these event listeners I want to
modify other classes that aren't defined in the EventListeners.
They already exist in the main program. The problem I have is how
best to get these eventlisteners to know of these classes (which are
also in seperate files)? Up to know I have used Singletons (I made
the classes the event listeners were to modify global) but this seems
ugly. How are java applications written to let the eventlisteners
see the classes they are to modify (sometimes these classes are
seperate application components in seperate files)?

If you don't use the nested anonymous classes, then you will need
to send the refs you need over in the constructor.

Do not use singletons for this.

Arne
 
S

Stefan Ram

When I write EventListeners I write them in seperate classes
(and seperate files) for reasons of clearity.

This expresses the underlying assumption that writing them
in separate classes and files is more clear. I am not so
sure about this!
But these event listeners I want to modify other classes that
aren't defined in the EventListeners.

In Java SE, you usually do not modify classes at runtime.
The problem I have is how best to get these eventlisteners to
know of these classes (which are also in seperate files)?

Well, by »class«, I assume, you mean reference values
(vulgo: objects).

Usually, this results from the OOD, for example:

- you can give static or non-static idenfiers or getter
methods public visibility (which you do not seem to like)

- you can pass the references when creating the instances
(as arguments of the instance creating expressions)

- you can insert them later via setters or
dependency injection

- or you an write the event listeners as inner
classes of the classes they need to access
(which you also do not seem to like, but which
I like)

You might look up Swing code from Oracles Java examples
and tutorials and see how those things are solved there.

You might read the book Applying UML and Patterns by Craig
Larman.
 
A

Arne Vajhøj

You might look up Swing code from Oracles Java examples
and tutorials and see how those things are solved there.

If it is good enough for Oravle, then it should be good enough
for OP.
You might read the book Applying UML and Patterns by Craig
Larman.

That is a very good book.

But much broader than this discussion.

Arne
 
D

Doug Mika

What I mean is the following:
I have a file MainWindow.java class
I have a file MenuBar.java class which instantiates a MenuWindow.java
MenuWindow.java is to make changes to MainWindow.java object.

MainWindow.java and MenuBar.java are instantiated in Program.java
How can events in MenuWindow.java cause changes in MainWindow.java
ie. what's the cleanest way to do this?

I know this is explained in a lacklustre way, but I hope it gets the point across. Any free resources on the web would be appreciated.
 
M

markspace

MainWindow.java and MenuBar.java are instantiated in Program.java
How can events in MenuWindow.java cause changes in MainWindow.java
ie. what's the cleanest way to do this?

The thing is, this is called "programming." There's a very large number
of ways to do this, and they all are valid, given various design
assumptions.

Static variables, "globals" as I think you mentioned, are OK if the
program is small and not going to be maintained (i.e., a small school
assignment). More robust methods all make some assumption as to rates
of code change, presence of frameworks, team size, total costs of
ownership, etc.

Your immediate problem could be solved by using constructors, and just
hiding and showing various windows, rather than destroying them and
re-creating them.

public static void main( String... args ) {
// startup
...
createAndShowGui();
...
}

private void createAndShowGui() {
SwingUtilities.invokeLater( new Runnable() {
MainWindow mw = new MainWindow();
MenuBar mb = new MenuBar();
MenuWindow menuw = new MenuWindow( mw );
mw.pack();
mw.setVisible( true );
}; );
}

Now MenuWindow has a reference to mw so it can manipulate mw. But I
can't think of at least three other ways to do this, and they all have
advantages and short-comings, so you have to decide what is best for
your programs.
 
D

Doug Mika

So passing MainWindow to MenuWindow is one possible solution. But what are the other three. No, this is not to be a school assignmennt, I'm looking for a clean and proper way to do this.
 
R

Roedy Green

How are java applications written to let the ev=
entlisteners see the classes they are to modify (sometimes these classes ar=
e seperate application components in seperate files)?

I can think of three ways to link to a class.

pass an X.class parameter

call a X.somestatic method

pass a reference to an X object and call a X.someinstance method

I mean "pass" in the more general sense of pass parm or leave ref in
package scope var.

Event handlers have no extra properties. See
http://mindrod.com/jgloss/anonymousclasses.html
--
Roedy Green Canadian Mind Products http://mindprod.com
The first 90% of the code accounts for the first 90% of the development time.
The remaining 10% of the code accounts for the other 90% of the development
time.
~ Tom Cargill Ninety-ninety Law
 
M

markspace

So passing MainWindow to MenuWindow is one possible solution. But
what are the other three. No, this is not to be a school
assignmennt, I'm looking for a clean and proper way to do this.

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.

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.

Personally I think factories are harder to work with, as they making
testing more difficult.


In a modern app, you also have to consider synchronization, especially
if your app has special threading requirements, like Swing GUI code.
This applies to both the factory and the global context.
 
M

Marcel Müller

If you don't use the nested anonymous classes, then you will need ^^^^^^^^^^^^^^^^
to send the refs you need over in the constructor.

AFAIK nested is sufficient.


Marcel
 
L

Lew

Marcel said:
AFAIK nested is sufficient.

So is extrinsic. Whether the class is top-level, nested or inner is a choice,
any of which is valid and each of which induces idioms to handle them.

Top-level types and static nested event-listener classes share the need to
receive everything from the client, i.e., the widget, explicitly. That
means constructor and method calls, including perhaps getters and setters,
which are a bugbear for some.

Inner types have the danger and advantage of direct insight into the innards
of the enclosing instance. This makes anonymous classes handy little parasites,
special-purpose little listeners that know only of the button or edit box
off which they feed.

Most people prefer them, if they do, for the intimacy and locality of
reference to the thingies they help.

OP, this was mentioned upthread, but your frame of reference for Java
programming is off kilter. You don't have "classes (which are also in
seperate [sic] files)". Once in the JVM, classes and all the other
artifacts of a program live in computerland as types and objects and
attributes and behaviors.

The separate-file perspective applies to source code, but not conceptually
to classes and such.

Also, you don't really "want to modify other classes" usually. You want to
inform objects (instances) of state changes and requests for state changes
and invocations of services and so on.

So the perspective is of objects that have types and all that having a type
implies, not of files and classes.

This helps clear thinking. Now you have this idea of an instance of an
event listener type that listens for event instances that emanate from
a GUI widget instance.

"Emanate?" you ask. Fair question. Emanation, communication, messaging,
invocation, prayer - whatever you call it, instances communicate with each
other in Java through constructors and methods, or via manipulation of
an instance's state that's accessible to the instance doing the messing
around.

Which brings us back to anonymous classes, and inner classes generally.

Inner class *instances* have direct access to all the state of their
enclosing *instances*.

So it's handy when a color-changing event is caught and the event listener
instance can just update the color of its enclosing instance. *

Non-inner-class instances have to go the regular route to communicate with
the client instance.

Anonymous classes, named inner classes, static nested classes or top-level
classes - instances of each kind communicate according to the access they have.

:::

*
But messed up if the listener takes a really long time to do so while
tying up the EDT.

No, not Eastern Daylight Time.
 
J

Joerg Meier

I'm writing an application and I have the following problem.
When I write EventListeners I write them in seperate classes (and
seperate files) for reasons of clearity. But these event
listeners I want to modify other classes that aren't defined in
the EventListeners. They already exist in the main program.
The problem I have is how best to get these eventlisteners to
know of these classes (which are also in seperate files)? Up to
know I have used Singletons (I made the classes the event
listeners were to modify global) but this seems ugly. How are
java applications written to let the eventlisteners see the
classes they are to modify (sometimes these classes are seperate
application components in seperate files)?

While we are talking about design patterns, you should be aware that a lot
of people now consider Singletons an antipattern. Your usage of them
certainly sounds like the justly despised "global variable" replacement
many people abuse them for. Might be a good idea to reconsider that design.

Liebe Gruesse,
Joerg
 
S

Stefan Ram

Joerg Meier said:
While we are talking about design patterns, you should be aware that a lot
of people now consider Singletons an antipattern. Your usage of them
certainly sounds like the justly despised "global variable" replacement
many people abuse them for. Might be a good idea to reconsider that design.

Pattern or anti-pattern, I never encountered a situation where I felt a
need for »singletons«. Maybe this is related to being in Java, where we
have static clas^H^H^H^H^H^H^H^H^H^H^Hclasses with static methods and
fields. After all, we would not frown upon things our expert language
inventors came up with - static public variables like java.lang.System.out
(»globals«), which is used in every Java class, often even within the
first »Hello World« program.
 
L

Lew

Stefan said:
Pattern or anti-pattern, I never encountered a situation where I felt a
need for »singletons«. Maybe this is related to being in Java, where we
have static clas^H^H^H^H^H^H^H^H^H^H^Hclasses with static methods and
fields. After all, we would not frown upon things our expert language
inventors came up with - static public variables like java.lang.System.out
(»globals«), which is used in every Java class, often even within the

first »Hello World« program.

Right, and we all know that Java devotés are pure fanboys who never bitchand moan
about the language's imperfections or how it should have been done, and simply take
everything given them as emanating from the forehead of the gods, Perls of wisdom all.

It rivals COBOL that way.
 
A

Arne Vajhøj

Pattern or anti-pattern, I never encountered a situation where I felt a
need for »singletons«.

Other have.

GoF has it.

Spring has had it since 1.x.

EJB got it in 3.1.

Implementations and usage are very different, but the idea of
everybody using the same object is the same.

Arne
 
A

Arne Vajhøj

While we are talking about design patterns, you should be aware that a lot
of people now consider Singletons an antipattern. Your usage of them
certainly sounds like the justly despised "global variable" replacement
many people abuse them for. Might be a good idea to reconsider that design.

Yes.

I don't see Singleton as an anti-pattern.

But it is certainly bad design if Singleton is used
as global variable that all code is writing to and
reading from making it very hard to figure out
what is going on.

And the description could sound like this is
indeed the case.

I don't see a problem if it is well defined who
writes and who reads. Having a Singleton load
config information and expose readonly API
is fine.

I don't see a problem if usage is independent
of other usage. With a connection pool you don't
care who else is using the connection pool. With
a statistics collector you don't care who else is
updating statistics.

Arne
 
L

Lew

Peter said:
_Needed_ is situation-specific, but examples generally will include
situations where multiple callers require access to some shared resource
abstracted by the singleton class. In some cases, a static class suffices.

Nitpick: "static class" is the wrong term. I figure you mean a "utility class",
or class with only static members.
But in other cases it's either useful or required to have a singleton (e.g.
because you need the singleton to implement an interface, something static
classes in Java can't do).

Static classes certainly can implement interfaces. It's non-instantiable
classes that can't, and classes containing only static methods.
But even in absence of _need_, there is the class of examples where one
needs an implementation of an interface that can be shared by multiple
callers. One approach is to keep creating new instances of the implementor
every time a caller needs it, but this has obvious efficiency issues. In

Sometimes has efficiency issues. The "obvious" ones often aren't actually
issues at all.

To "keep creating instances" is actually a situation for which Java is
optimized.
some cases, those issues can actually be a problem, in which case it's nice
to implement a singleton.

Isn't "issue" a synonym for "problem"?
Each caller can "solve" the efficiency problem by caching their own copy of

Yes, "solve" in quotes, because quite often something labeled a "cache"
simply isn't. Also, there's that aforementioned optimization for short-lived
instances.
the class, but it's generally better to do the work once in the singleton
class rather than making each caller duplicate the effort. Good API design

And this is the heart - not whether the instance hangs around but whether the
work needs to be repeated. It's the latter that helps decide on whether to keep
an instance (singleton or otherwise) lingering.
means the client of the API has a minimum of work to accomplish needed
functionality, without a bunch of extra busy work.

Another class of examples involve classes where it's useful to have a
"default" instance. Again, callers could use a default constructor and
create a new instance every time they needed the default one. But it's
convenient to have a singleton instance representing that default.

Strictly speaking, that's not a singleton unless it's the only possible
instance.
Frankly, I'm amazed any experienced programmer would argue against the
pattern solely on the basis of perceived lack of "need". Almost everything
in a high-level language and framework is there not because of need, but
rather convenience and simplicity (which often in turn leads to code that
is easier to get correct, always a nice feature of one's code). Everything
you can do in Java, you can do in assembly language. You don't _need_ Java
at all.

And yet, we use it.

Now that is a salient point indeed.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top