Generic Design for an iManager Plugin
22 Dec 2004
Problem:
Many plugins have a huge Class which extends, executes and
implements all handlers. There are a host of Utility files which are copied for
every plugin.
Objective:
- Introduce layers.
- Implement Design patterns in this existing design.
- Arrive at a generic design which can be used for any plugin development.
Maximize reuse.
- Come out of Method handlers - Procedure Oriented programming to Object
handlers - Object Oriented Programming.
- Allow easy code generation from plugin specification.
Existing design has a controller class which is tightly
coupled to all details. To write a new plugin, a lot of changes are
required.
So, the new Controller is designed for minimal
responsibilities. The class which extends dev.Task has these
responsibilities
- Implement Execute, it is the purpose of this class
- Handle Should Run, as it is the first Expert to get the
HttpServletRequest
What needs to be done in the execute? Execute
should make this task a Controller. Execute should send the request to next
controller based on a criteria.
Criteria may be the JSP page which submitted the
form. Hence execute diverts the request to Page Handler. Task Controller has
all pages in the Task. So every page when added to the plugin results in a LOC
addition only in task controller.
PageHandler Should divert the request to
Button/Action Handler. PageHandler has all action Handlers for a page. An action
is a submitting action in browser. It may be OK, CANCEL, REFRESH… All actions
need not be user-generated, there may be periodic REFRESH done by JavaScript
thread. Every action requires 1 LOC addition only to the PageHandler.
ActionHandler Needs to do some action, involving
state change and error handling. Action handlers consider state information
and invoke appropriate workers.
Worker Performs a specific task. After the task,
sets the Next JSP page. ActionHandlers exist in Application layer, while workers
are in Domain layer.
This chain of responsibility design needs to answer these
Qs:
Who is responsible to maintain state? Where is session
specific info stored? How are the handlers made thread safe?
What may be session specific info -Task context, tree
logged in, user logged in, server logged in, browser info These can be
handled by a SessionHandler which creates a SessionBean. SessionHandler
should be called by dev.Task.
Obviously, state is maintained in SessionBean by
Handlers-Workers.
We make handlers thread safe by creating different sessions
for different threads.
All the Workers will have a lot of common
responsibility. These should be part of a singleton Utils. Design should
ensure that everything in Utils is stateless.
Session Bean is visible to all handlers and workers, in plugin
terms, it is the PanelInfo. Session bean removes global variables in classes in
Application layer. It provides a way for session tracking.
Error handling The worker handles the error and
abstracts as WorkCannotBePerformed Handler handles the error and abstracts as
RequestCannotBeHandled Pagehandler further abstracts the error as
PageSubmissionCannotBeHandled dev.Task further abstracts as
TaskExecutionFailed
So, we do not see a NullPointerException, but which action in
which page by what task caused the null pointer exception.
This is the Exception pattern
Thus the generic design applies Chain of
responsibility SessionFacade Exception Singleton patterns
A session in a plugin is different from HttpSession. Every
invocation of task may start a new session. This may be from same
browser/client.
Hence SessionBean needs some identification for this task's
session.
Every JSP page has 3 hidden parameters:
- pageid
- actionid
- sessionid
This should be present in every request, response of task.
Instead of making servlets get created for every request, all
state information should be stored in Session Bean.
I am presenting a DeleteContainer task, which uses this
generic design:
All handlers are singletons, never 2 instances of any handler
is created. Workers can run in threads, so that handler does not hang.
All workers are stateless; all state information is passed in
SessionBean which is not shown.
|