Monday, November 19, 2007

How OTK Custom dbInstaller 2.0 achieves high flexibility and stability with MVP

As some of you may already know that, Model-View-Presenter (MVP) is a design pattern that cleanly separate the concerns between UI (View), UI-data interaction logic (Presenter), and your data logic (Model). If you came across with Web Client Software Factory (WCSF), you may notice that when you added a specific business module, guidance automatioin will create a presenter class for you for each page view. However, that doesn't mean that in MVP, you can only have one presenter for one view. In fact, you can have one presenter for multiple views. This is what dbI 2.0 alpha is currently implementing now.

If you browse through the OTK Web Community photos, you will notice quite easily that dbI 2.0 is actually providing a wizard-like database installer to facilitate the database deployment tasks of your enterprise applications. What you may not notice is that, one of the great features that dbI wanted to achieve is to allow the developers to easily take out/incorporate in any wizard dialog steps with any combinations for different usage and target users. Developers can decide which steps they want to allow the users to customize for the installation of their application's database and which they do not.

In order to achieve that, dbI 2.0 needs to find a way to separate the concerns between the dialog specific logics and cross-dialog standard logics so that the common logics do not need to be repeated on each form. Duplicating the same logic across multiple forms may introduce bugs as well as making the programs very hard to maintain.

(NOTE: The 'cross-dialog standard logics' involve the manipulation of those common form controls together with some function calls from the data object, which may not be easily achieved a clean SoC by creating common class.)

Therefore, to tackle this issue, we do the following:

  1. First of all, we got to identify what are standard UI components that available on every wizard dialog. Then we create an interface called IWizardView that exposes these standard UI objects as properties.

  2. Then we implement IWizardView on each of the wizard dialog boxes. Now every form will have all these common controls exposed as its public properties.

  3. We now create a presenter class called InstallerPresenter, having one of its property as the type of IWizardView and its associated private variable called _wizardView.

  4. Meanwhile, we also make the presenter's constructor to accept a parameter of type IWizardView and get the parameter value assigned to _wizardView.

  5. Back to each wizard form, we want the presenter class to be created once the Form object is created. Hence, on each form's contructor, we do the following:

    _presenter = New InstallerPresenter(Me)

    where 'Me' is the form itself.
Since the constructor's parameter is just an interfance but not the form, we can say that the presenter does not have the knowledge of the specific form but just the "rules" that it can accept, i.e. the IWizardView interface. Through this way, the presenter will therefore can serve multiple forms with its logic as long as each form is implementing the IWizardView interface.

Here, I also want you to take note that, in order to implement MVP design pattern, it is not necessary that you need the ObjectBuilder (for Dependecy Injection purposes) as proposed by WCSF. It is optional and just a nice-to-have feature that will further pushing the loosely-coupled practices into extreme.