SOA for Swing (event handling scalability)

Why UI event handling may not scale

Event handling using event sources and event listeners doesn't scale. Not at least if you don't take dependencies into account. That's a fact. Let me explain.

Think of a Swing application as composed of major "macro-components". Say you have an editor, a settings dialog, a status bar, a console window, a filesystem tree-view for displaying file info, whatever you may think of.

If your application is small then it's probably ok to keep a one-to-one integration between these macro-components. You make the editor a listener of the settings dialog. You make the status bar a listener of the editor. You make the editor a listener of the filesystem tree-view. Easy. Business as usual.

But if your application starts to grow then you're in trouble with a one-to-one integration. After all if your application has "n" major macro-components then you need "n times n" one-to-one integrations. If "n" is 10 then you need 100 one-to-one integrations. That's nightmare. It's easy to have loops of listeners between major macro-components because it's difficult for you to track dependencies, and you don't know who is sending what when. Order of events starts being problematic. You're in serious trouble.

The SOA equivalence

That's exactly the same situation most of our customers are facing inside datacenters. They're in trouble trying to integrate applications when the number of applications grow. It's difficult for them to extract information from those, it's difficult for them to keep information simple. Their information starts to be duplicated in different applications. They're in trouble too.

That's one of the reasons why we've adquired SeeBeyond. To help customers clarify the situation in the applications in their datacenters (and with the rest of the world too). To integrate their applications easily. To reduce their TCO. To make application development easier by using SOA, by easily orchestrating their services in a coordinated way.

The best way to integrate different applications is, of course, by using an Enterprise Service Bus, a major component of most SOA suites nowadays. By using one of these integration becomes scalable. "n" applications require just "n" connectors to the bus, and not "n times n" as before. Easier. Linear scalability in place. Let's grow.

This ESB is responsible for routing the message between zero, one or more applications. Either synchronously or asynchronously. And one application does not need to know to which other applications is connected. That's the way to grow.

The "Swing Event Bus" (and its events)

And the same solution may apply to your Swing applications as they grow. You need some sort of "Swing Event Bus" to integrate your macro-components. Your macro-components send events to this Swing Event Bus and forget. They don't know who is responsible for handling the event. There's not a one-to-one relationship between event sources and event listeners. These are decoupled. You can now scale linearly, you can now grow your application with another macro-component by attaching it to the event bus.

Of course the events transferred by such a "Swing Event Bus" are not "normal" events. I mean, you don't want to transfer ActionEvents from the "File System Viewer" to the "Editor" and the "Status Bar". "Normal" ActionEvents tell nothing to you. You don't mind what the action command of the event is. You don't even mind what the source of the event is. It may be an internal button of the "File System Viewer", a double click on a file or a popup menu.

Through that "Swing Event Bus" you probably want to deliver custom events. Say a "RequestFileOpenEvent", that contains (for instance) the name of the file. Then the "Editor" and the "Status Bar" will receive that "RequestFileOpenEvent" from the "Swing Event Bus" and react appropriately. The editor will probably try to open the file and the status bar will probably show a "Opening file XXX" message.

You can use both, of course!

Of course the "Swing Event Bus" may be used for intra-macro-component event handling. This is, you can use such a "Swing Event Bus" to communicate in-between the components (buttons, popups, menus, lists, tables) of your macro-component (the "editor", say). But that's probably not a good idea. It violates the KISS principle. There's no great benefit of having a loose-coupling between a button and a menu item inside the editor, right?

After all the "Swing Event Bus" should be used just to attain loose-coupling between major macro-components. Using it inside a macro-component makes no sense at all.

So, where is this Swing Event Bus?

Well, the idea of using event buses for Swing has been around for a long time.

The first that comes to my mind (and probably the older one) is the good, old, easy-to-use, withdrawn, almost-forgotten InfoBus specification (we even had some implementations at java.sun.com).

But there're may others out there. There is David Walend's Somnifugi, a lightweight JMS implementation. And werx, for instance.

And I'm not the first one to talk on this either. Berin Loritsch, David Walend, Ryan's Scraps, Lair Nelson and probably tons of others have talked on this before.

So, why talking on this now?

Well, you know I suffer badly from frameworkfobia, so I try to do things myself as much as I can. That, and because I need working out my annotations in Java 5, is the reason why I'm working on UITopics. (Yeah, still waiting for java.net approval :-().

Next posts

This looks interesting, doesn't it? Now let me ask one question: should events transferred through the Swing event bus contain any logic at all or not? What does the SOA simile suggest?

Food for thought. Cheers,
Antonio

Comentarios:

Interesting thoughts...

Before we go down the road of creating a bus like system I think it is important to differentiate between the two basic types of events : CommandEvents and StateEvents (i.e. OpenFile and the resulting FileOpened). These two types of events indicate action (which may be vetoed) and reaction in a application and it is important to understand that the objects listening for CommandEvents will (most likely) not be the object listening for StateEvents. The objects that listen for CommandEvents would be the generators of state events. This is akin to having controllers (mediators) that handle the interactions of macro-components and their effect upon the state of the application via a system of categorized events. The events would be delivered to sinks which can be hooked into the bus, as a place to register for or deliver a specific type of event.

Here's an example:

SystemCommandEvent OPEN_SYSTEM, CLOSE_SYSTEM, SAVE_SYSTEM, REFRESH_SYSTEM, etc...

SystemStateEvent SYSTEM_OPENED, SYSTEM_CLOSED, SYSTEM_SAVED, etc...

ModeCommandEvent CHANGE_MODE, START_MODE, STOP_MODE, etc...

ModeStateEvent MODE_CHANGED, MODE_STARTED, MODE_STOPPED, etc..

CursorCommandEvent START_CURSOR, STOP_CURSOR, etc...

Each Command event has an associated State event. Each event type (Mode, System) has an associated sink or support object (i.e. - ModeSupport, SystemSupport) that handles the delivery and registry of Command and State events possibly via the bus. The support object can then determine whether it needs to deliver the event via the bus (i.e. a START_CURSOR event may be delivered via the EventQueue), and how it should be delivered (sync, async). This allows the macro-components of the application to communicate CommandEvents to each other and have macro or micro components listen to the resulting StateEvents, while allowing and orderly means or components to access events, and allowing each category (even each type) of events to determine how it will be dispatched via the sink.

This architecture is fairly simple to create and allows for greater flexibility when those unexpected requirements pop up. Let me know what you think...

Enviado por Tim Osten en septiembre 20, 2005 a las 03:11 PM CEST #

Hi Tim!!

Thanks for your comment!! Sorry for my late reply but I can't blog as frequently as I would like to :-(

I was thinking that it could be a good idea having different bus lines. Say topics (JMS) or channels (werx). So we could have a command topic and a state topic, and route the command events through the first and the state events through the second. What do you think?

Regarding the support object I think it's a great idea. I think it's an application of the Mediator Pattern:

The Mediator pattern uses an object to coordinate state changes between other objects. Putting the logic in one object to manage state changes of other objects, instead of distributing the logic over the other objects, results in a more cohesive implementation of the logic and decreased coupling between the other objects

Don't you think?

I'll try to post later on these ideas to try to see how well they fit together. This is something like brainstorming.

I just hope to be up to the task of discussing all these issues with you all!

Cheers
Antonio

Enviado por Antonio en septiembre 21, 2005 a las 01:35 PM CEST #

sounds interesting, i hope to hear more. can't wait for UITopics on java.net!

Enviado por codecraig en septiembre 22, 2005 a las 07:30 AM CEST #

Take a look at SwingForms, same idea (no listeners) but different approach (asynchronous events). Works great! - no gui freezes - no dependencies - very scalable Will

Enviado por Will en septiembre 23, 2005 a las 05:51 AM CEST #

Enviar un comentario:
Los comentarios han sido deshabilitados.
About

swinger

Search

Archives
« abril 2014
lunmarmiéjueviesábdom
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Hoy