Hi folks,

I dipped into the RCP source-code just for relaxation from another project and I started with the org.springframework.richclient.application.Aplicat ion class.

Since this is the core class of the framework, I was a bit humbled since I got the feeling that the design smells by first gaze.

Here is why:

First of all what is a suitable definition of application?

Using google "define: application" we get:

- "a program that gives a computer instructions that provide the user with tools to accomplish a task"
- "a diligent effort; "it is a job requiring serious application"
- "the work of applying something;"
- "lotion: liquid preparation having a soothing or antiseptic or medicinal action when applied to the skin; "a lotion for dry skin"
- "Application is short for application program, which is a program designed to perform a specific function."

Ok that should provide us enough to think about applications:

We can agree that an application in our bounded context is:

- short form for application program
- designed to accomplish a certain task (tool aspect)
- designed to perform specific function

We can also agree that an application in our bounded context is not a lotion for dry skin!!


Ok lets take a look at the Application class. The Application class is a class and therefore implicates a type. The type Application looks like this:

Code:
public class Application implements InitializingBean, ApplicationContextAware {
    public static void load(Application instance);

    public static Application instance();

    public static boolean isLoaded();
    public static ApplicationServices services();
    
    public void setDescriptor(ApplicationDescriptor descriptor);
    public void setServices(ApplicationServices services);

    public void setApplicationContext(ApplicationContext context);
    public void afterPropertiesSet();

    public ApplicationLifecycleAdvisor getLifecycleAdvisor();
    public ApplicationServices getServices();

    public String getName();
    public Image getImage();

    public void openWindow(String pageDescriptorId);

    public WindowManager getWindowManager();
    public ApplicationWindow getActiveWindow();
    public void close();
}
Ok this is a type. Now we have to resolve some hazard coming from the aspect the class is also an implementation.

So we have to question the super types first... .

It implements ApplicationContextAware and InitializingBean.
From the import statement we learn:

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAwar e;

So being in the package *.springframework.richclient, these types are not relevant for our application type so we can drop them.

By simplifying our type, we end with this:

Code:
public class Application {
    public static void load(Application instance);
    public static Application instance();
    public static boolean isLoaded();
    public static ApplicationServices services();
    
    public void setDescriptor(ApplicationDescriptor descriptor);
    public void setServices(ApplicationServices services);

    public ApplicationLifecycleAdvisor getLifecycleAdvisor();
    public ApplicationServices getServices();

    public String getName();
    public Image getImage();

    public void openWindow(String pageDescriptorId);

    public WindowManager getWindowManager();
    public ApplicationWindow getActiveWindow();
    public void close();
}
Ok now lets question the methods.

public static void load(Application instance);
public static Application instance();
public static boolean isLoaded();
public static ApplicationServices services();

Boy! Static methods in a type? Misplaced, gotta be moved for sure!

public void setDescriptor(ApplicationDescriptor descriptor);
public void setServices(ApplicationServices services);

Looks like dependency injection -> Implementation detail not type detail. Leave out.

Actual version:

Code:
public type Application {
    public ApplicationLifecycleAdvisor getLifecycleAdvisor();
    public ApplicationServices getServices();

    public String getName();
    public Image getImage();

    public void openWindow(String pageDescriptorId);

    public WindowManager getWindowManager();
    public ApplicationWindow getActiveWindow();
    public void close();
}
This is the type Application. So the question goes to the semantic meaning. An application is designed for performing certain tasks. So instances of Application are designed to perform any function/task possible - right generic.

So what kind of features do we have within our Application and how are they related to applications in a generic viewing?

public ApplicationLifecycleAdvisor getLifecycleAdvisor();
public ApplicationServices getServices();

Um looks something supportive but I lack some knowledge to be sure. A lifecycle advisor looks like an processing detail and may be an implementation detail and should be hidden for non autorized eyes. Not sure.

ApplicationServices concept looks sweet if you ask me. It looks like a way to iterate the services the application may provide. So we have an application which can be described by the services it offers. Is this right thinking? I like the idea, so I buy it up to now.

public String getName();
public Image getImage();

Ok that looks descriptive. Application please identifiy yourself. Name, image, ok. Can be brought, but I am in doupt if an application need to know its name and its image to identify itself. Maybe this should be moved to a type ApplicationDescription and this is outside of the scope of our Application type for sure -> extract.

public void openWindow(String pageDescriptorId);
public WindowManager getWindowManager();
public ApplicationWindow getActiveWindow();

Ok this looks interesting! Windows! So we don't talk about an application in general, we talk about applications using windows. We got also an ApplicationWindow type and a window manager and it can open a window.

First of all, shouldn't the type name of type Application reflect, that we are thinking about applications having windows? Is every application needed to have a window within the rich client framework?

I wouldn't make openWindow a thing the application should provide as normal function. Also having control about its window manager, I am deeply in doupt. The next thing is getActiveWindow. Should the application care about its view?? We have an intermixing between View and Controller I guess.

If I would be an application I wouldn't like to fuzz with window details. Opening a window means also solving the problem, no proper window can be opened, so what to do? - throwing an exception?

As an application I don't like to think about this. I just don't care! And when you ask me, what window is the current active one, I just would say: "I don't care, just look for yourself!". This is view-stuff! I am an application! I am about do-stuff!

Ok now and finaly:
public void close();

What does this mean? Applications don't get closed. Windows, streams etc. get closed. There is no state of an application being named closed. An application may be active or deactive, alive or dead, created or destroyed, new or old. So whats a more abstract verb of close? Well how about dispose? Disposing may be translated to trashing something. Isn't this what this method means (I dont know yet).

so we and up with:

Code:
public type Application {
    public ApplicationLifecycleAdvisor getLifecycleAdvisor();
    public ApplicationServices getServices();
    public void dispose();
}
Looks better doesn't it?

We also get:
Code:
public type ApplicationDescription {
    public String getName();
    public Image getImage();
}

Also we need to handle the static one.
Remember we talk about this:
Code:
    public static void load(Application instance);
    public static Application instance();
    public static boolean isLoaded();
    public static ApplicationServices services();
This is higher level stuff. A normal application do not deal with it. So we need an object to put those methods in. Eclipse got it's Platform. The platform can be translated to Runtime or Environment. What we need is an object being responsible for application handling and providing the environment the applications swim in.

Platform sounds good, ApplicationEnvironment would also be nice, ApplicationPlatform sounds and Runtime isn't as sexy as the other three are. Up to you.

Lets call it ApplicationPlatform for the moment.

Code:
type ApplicationPlatform {
    //public static void load(Application instance);
    //We dont load an application object being already created!
    public void initialize(Application instance) 

    //public static Application instance();
    //we got singleton behaviour so this may be translated
    public Application getActiveApplication();

    //public static boolean isLoaded();
    //This translates to isInitialized() but no its not mmm.
    public boolean isAnyApplicationActive(); //What is this good for?
   
    //Oro? Whats this good for in this context, I dont know... .
    public ApplicationServices services(); 
}
Now we have seperated most of the responsibilities.

The ApplicationPlatform handles the lifecycle of the Application. Maybe the dispose method should go to the ApplicationPlatform, too.

ApplicationPlatform.dispose(Application) - or destroy, end how ever you call the last state in an application lifecycle (anyone having a state diagram?)

And ApplicationLifecycleAdvisor may be seen as an aspect describing the application lifecycle behaviour. So it isout of the scope of an Application instance for sure (exists before and after the application's own life). So the application should not know anything about it. So why not making the lifecycle advisor part of the loading process.

ApplicationPlatform.initialize(Application application, ApplicationLifecycleAdvisor applicationsLifecycleAdvisor).

Now how does ApplicationDescription fits this into? Uhm this is something the ApplicationPlatform should know, too.


ApplicationDescription ApplicationPlatform.getDescription(Application application)

So it should know the application's description. An Application enters the scope (knowledge space) of a ApplicationPlatform within the initialize method (now I would rename this method to something more specific). Since the description should be inmutable we can also extend the initialize method by this detail.

ApplicationPlatform.initialize(Application application, ApplicationDescription applicationDescription, ApplicationLifecycleAdvisor applicationsLifecycleAdvisor).

Looks sweet, but what is about the window manager?

Well a window manager manages the application windows (view aspect). Windows are somewhat related to the ApplicationPlatform.

WindowManager ApplicationPlatform.getWindowManager(Application application)

This sounds crazy. A window manager is depending on a single application? Not in my world. Lets rename it to ApplicationWindowManager.

ApplicationWindowManager ApplicationPlatform.getWindowManager(Application application)

So the application window manager knows how to open and close ApplicationWindows. Nice isn't it? Also this manager knows what the active window is. It provides a listener service to listen for open/close window events.

The ApplicationPlatform is not stupid, that's why it listens for all those events the application window managers provide. So the application can be disposed by the platform once once the last window gets closed.

Now the question? If all windows are closed, the application gets disposed automatically. Nice rule, but we need an exception, don't we?

When the platform initializes an application, it does not have any windows. Guys you know what? During the initialization of an application we open a default window! If no default window can be opened, we dispose the application right out of the box. No window, no meaning, no life! -> we should rename Application for sure, my guts arn't lying, I guess!

So how can we give the ApplicationPlatform.initialize method the knowledge about the default window to open? Well what about the ApplicationDescription? It describes the application. I can think of creating an application supporting many diffrent application window perspectives. The application shouldn't care if any of it's windows are initial ones. So it is sure somewhat descriptive and out of the application's scope.

So now we got a problem. ApplicationDescription is a description now holding informations about the initial application process (initial window to open). This information is only needed once during the initial phase of the application, so it shouldn't be accessible by the ApplicationDescription.

How about this design:

Code:
type ApplicationContext {
    getApplicationDescription
    getInitialWindowToOpen
}


Hmm an ApplicationContext. Maybe this is not the right name. We also got already deal with an application context with diffrent meaning.

The Spring framework seams to deal with applications itself (why else should the framework have objects called ApplicationContext?). So thinking further we know the Spring framework deals with web-applications and generic applications as well.

RichClient API uses the spring framework to support its special kind(!) of application. This means we are talking about special applications here!

How about renaming Application to ClientApplication or RichClientApplication? And ApplicationPlatform becomes ClientApplicationPlatform. Boy that sounds! Would solve some of our worst curses poisioning our thinking.

So now that I described a (in my oppion) clearer design, a typical question is normally thrown at me:

Your type of ClientApplication is a way too abstract, it would make my implementation quite ugly and complicated.

Well add support for often needed methods to the AbstractClientApplication service implementation stub. The application's window manager may be visible by its View implements etc. This is implementation detail we are talking about architecture here, so this is nothing which should state against this design.

Now I have to review my hipshot thoughts! Urgh, long! --- Ok some problems solved. If you have questions or something to add I would like to hear. First of all remember I just reviewed my first type and didn't look for the other types to not poison my first impressions.

Final Code structure:

Code:
type ClientApplication {
    //empty? how did you changed?
}
Code:
public type ClientApplicationDescription {
    public String getName();
    public Image getImage();
}
Code:
type ClientApplicationPlatform {
    public void initializeApplication(ClientApplication, ClientApplicationContext);
    public void disposeApplication(ClientApplication);

    public boolean isAnyApplicationActive(); //What is this good for? 
    public ClientApplication getActiveApplication();
    public ClientApplicationDescription getDescription(ClientAppliaction);
    public ClientApplicationWindowManager getWindowManager(ClientApplication);
}
Code:
type ClientApplicationContext {
    ClientApplicationDescription getApplicationDescription();
    getInitialWindowToOpen();
    ClientApplicationLifecycleAdvisor getLifecycleAdvisor();
}
Code:
 
type ClientApplicationWindowManager {
    openWindow(String windowId); //boy must get rid of the String later!
    closeWindow(ApplicationWindow);
    ApplicationWindow getActiveWindow();
    addWindowManagerListener(WindowManagerListener);
    removeWindowManagerListener(WindowManagerListener);
}
By seeing this ClientApplicationWindowManager I am questioning my self if ClientWindowManager wouldn't be enough?! ....

By the way, ApplicationServices was taken out since I don't know what it is up to. (Next target of investigation :-)


Cheers,

Martin (Kersten)