views:

590

answers:

3

I'm attempting to refactor an existing Winform application to use the MVP Passive View pattern. The application's UI, business logic and data storage code have been freely intermingled for years. It looks like it either started out with separate layers or someone attempted to separate it into layers. In any case the layer boundaries weren't respected.

Since the forms directly manipulate the domain objects and the data source(and vice versa), my first task is to create presenter/controller objects and delegate those responsibilities.

The application is a .NET 1.1 app and I'm developing in VS.NET 2003 with a rather limited refactoring add-in. I used a test generator for the existing code to create the boiler plate unit tests then went through and hand edited each test. Granted, this winds up testing what the code does, not necessarily what it's suppose to do. For new classes I'm doing TDD.

Any tips, resources, pitfalls to look out for with a refactoring effort of this scale?

A couple of resources I already have at my disposal:

  • Collection of programming books; Refactoring, PEAA, WELC
  • The internet (obviously)
  • Large quantities of caffeinated beverages

Update: As an example what steps would you take to turn this:

    private void OneOfManyFormEventHandlers(object sender, System.EventArgs e)
 {
  string LocalVariable;
  decimal AnotherLocal;
  if (!this._SomeDomainObject.SomeMethod(ClassField, out LocalVariable, out AnotherLocal))
  {
   MessageBox.Show("An error occurred calling method");
   return;
  }

  this.FormControl.Value = LocalVariable;
  this.AnotherFormContorl.Value = AnotherLocal;

  this.AnotherPrivateMethod();
 }

Into this:

    private void OneOfManyFormEventHandlers(object sender, System.EventArgs e)
    {
         this.FormPresenter.DoSomething();
    }
+2  A: 

The approach I've taken is too move the code out of the event handlers first. Essentially I've placed a class next to the form, which implements the event handlers and holds the UI state beside the controls.

Through this move I have gained a pretty clear seperation of the form and the actual interaction with the remaining app and was able to introduce tests at that level. Another result of this was that the view becomes passive pretty quickly.

I refactor the presenter (which now holds the event handlers) in a seperate step and introduce domain objects only after I've moved all uses of these objects out of all forms.

So my steps would be:

  1. Remove the UI dependency from the logic
  2. Create domain objects (if not available already)
  3. Refactor the presenters to use the domain objects
  4. Introduce services according to your design choice while you're at it

While I did this I started introducing tests at the newly introduced boundaries to ensure that I'm not breaking working code or to find bugs in the existing code I'm moving.

__grover
A: 

If you have the time, I'd recommend first writing some smoke tests using WinForms test frameworks like White on the existing application. This way you'll be able to check for any newly introduced bugs when you start refactoring the code.

Igor Brejc
@Igor: White didn't work well for me (at least for C++ based MFC applications).
Vyas Bharghava
A: 

You may find the answers to Implementing MVC with Windows Forms helpful as they talk about the different options when implementing MVC and MVP

Ian Ringrose