Swing and Design Patterns – Part 2. Delegate Pattern

Lets look at our diagram again and examine another pattern.

Delegate Pattern (aka Facade)

The delegate or facade pattern should be the backbone of all java Swing application (for that matter, not just Swing, but any desktop application that needs to communicate over a network such as SWT, C# apps, etc. should also use this pattern). The pattern aggregates all application calls to the outside world within one class. This has a number of advantages.

  • The delegate pattern presents a clear snapshot of communication from the front end to the backend, or the inside to the outside world, making the system more understandable and maintainable to other developers.
  • It decouples the client side application from other systems. The application does not need to know any details about the externally interfacing server or servers, and does not need to understand the modes of communication.

The delegate pattern should consist of a class that looks something like this :

…which can have dozens (if not a hundred plus) other method calls.

The delegate is a thread safe singleton created via a thread-safe static getInstance() method. As Swing applications can have many threads running at the same time, it is important to make this thread-safe.

The remote interface class variable in the previous example is intended to be an abstract placeholder (You would generally have to make a decision on how to implement this remote interface). But generally the remote interface is stub code that communicates with an external system.

RMI Example

Assuming that the delegate hooks up to a single delegating EJB session bean, a simple RMI Example would look something like :

Pretty messy.. huh? What happens if you want to interface to more session beans? What happens if some methods call a web service?





Web Services Example

Web services offers a much cleaner interface in respect to service creation, however it contains a lot of generated code that may not be compatible with the client business code. It is always important not to let these generated artifacts contaminate further past the delegate and into the client code.

Notice how the generated response (ie. patientResponse) is converted to the local domain code.

Service Locator

If you are dealing with diverse external systems, generally you would want to use a J2EE pattern called a service locater.

This can add another layer of abstraction to your delegate, so make sure you only use the service locater pattern if you need to. If you are just communicating with one session bean on the server side then it is probably not necessary.

Example :

The service locater uses lazy loading to cache service connections as they are needed. The benefit of the service locator is that the delegate is under the illusion that it is still only communicating with only one external interface.

Exception Handling and Caching

Before polluting the Swing GUI with unexpected behavior, the delegate can cleanly intercept all exceptions and throw out an error dialog in an appropriate manner.

Of course my code here is a simplification. You could have a single catch if you wanted. If you are dealing with transactions on the client side (An example of a GUI transaction would be displaying two lists – or tables or whatever – from two different calls. If either fails, then nothing should be shown), then showing an error dialog should be managed outside of the delegate layer.

The delegate is a good place to place exception handling, and it is also a good place to put any necessary caching. For example

If caching gets out of control inside your delegate class, then consider abstracting that responsibility into another layer.

Final Points

  • If the delegate needs to communicate with multiple service points, consider a Service Locater pattern
  • Consider making the delegate the point where exceptions will stop, be logged, and converted into a GUI notification.
  • Avoid placing transactional code in the delegate calls. Transactions for data integrity should exist on the servers inside persistence layers and such. Transactions in the GUI (yes transactions can exist in the applications!), should be handled deeper within the GUI code, and not in the delegate class.
  • Put any reasonable caching inside the delegate. If the caching becomes excessive, abstract it into a CacheManager class.
  • At the end of the day the delegate should be clean, cohesive, and present an unambiguous snapshot of what goes in and out of the client.

I hope this article makes sense. Flame me or love me in the comments section.

Further reading:

Posted in Design Pattern, Swing Design Pattern | Tagged , , , , , , | Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">