Saturday, May 30, 2009

Separate Domain from Presentation – part III

Cross post from IRefactor

This is a third post in the series of posts about “Separate Domain from Presentation” Refactoring.

Previous Posts:
Separate Domain from Presentation – part I
Separate Domain from Presentation – part II

Last time we explained how to refactor towards MVP – Supervising Controller pattern.
We left our project in the following state:
In this post I will complete the required refactoring steps and will suggest more steps to even deepen the separation of UI and BL concerns.

Refactoring Steps:
  • "Extract Interface" – in order to have a better encapsulation and separation of concerns, the CoursesPresenter shouldn’t access CoursesView directly. After all, the only functionality of interest to the CoursesPresenter is the CoursesView Courses property. Therefore, we will extract an interface from CoursesView class as follows: right click on the CoursesView class » Refactor » Extract Interface and select Courses property as shown in the figure below.
  • Compile the Solution and execute the Unit Tests.
  • In the CoursesPresenter class change all the occurrences of CoursesView to ICoursesView.
  • Compile the Solution and execute the Unit Tests.
  • Last time we indicated that the presenter should handle complicated user events by subscribing to the view. After introducing the ICoursesView interface it’s simple. Add to the interface the following code:
event Action LoadCourses;
event Action SaveCourses;
  • Implement the newly added events in the CoursesView class:
public event Action LoadCourses;
public event Action SaveCourses;
  • In the CoursesPresenter class rename the Load and Save methods to LoadCoursesEventHandler and SaveCoursesEventHandler respectively. Use right click » Refactor » Rename tool to rename it easily.
  • Wire-up the events in the CoursesPresenter constructor as follows:
public CoursesPresenter(ICoursesView view)
{
this.view = view;
view.LoadCourses += LoadCoursesEventHandler;
view.SaveCourses += SaveCoursesEventHandler;
}

  • Compile the Solution and execute the Unit Tests.
  • In the CoursesView class add the notification code:
private void NotifyObservers(Delegate del)
{
Delegate[] observers = del.GetInvocationList();
foreach (Delegate observer in observers)
{
try
{
Action action = observer as Action;
if (action != null)
{
action.DynamicInvoke();
}
}
catch
{
// graceful degradation.
}
}
}
  • Change the CoursesView.Load and CoursesView.Save methods to call NotifyObservers respectively:
private void FrmMain_Load(object sender, EventArgs e)
{
//...
NotifyObservers(LoadCourses);
//...
}
private void Save()
{
//...
NotifyObservers(SaveCourses);
//...
}
  • Compile the Solution and execute the Unit Tests.
  • Now it is the time to remove all the temporary instantiations of the CoursesPresenter class in the Load and Save methods. Remove all the occurrences.
  • In the Program.cs class instead of Application.Run(new CoursesView()) write the following:
static void Main()
{
//...
CoursesView coursesView = new CoursesView();
CoursesPresenter coursesPresenter = new CoursesPresenter(coursesView);
Application.Run(coursesView);
}


This concludes the “Separate Domain from Presentation” refactoring.
We ended with the following:
For next possible steps, consider the following:
  • Go over the CoursesView.Designer.cs and remove all the TableAdapter instances.
  • Create DAL and move Save and Load methods further more, from the presenter to the DAL.
  • Create the CoursesView and CoursesPresenter using Abstract Factory or using Dependency Injection.

Thursday, May 28, 2009

Var{i-able;}

Cross post from IRefactor

Here is a scoop; The good software engineer is lazy!
You don’t believe me? Then ask yourself this: If a good software engineer was not lazy why would he:
  • Automate processes?
  • Reuse a function instead of duplicating its code?
  • Explicitly name a function for its behavior instead of naming a function F1 and providing a non descriptive (and possibly long) documentation?
Yet, here is another scoop; The bad software engineer is lazy too!
While this statement clearly isn’t a shock to you, it immediately pop-ups the question:
What is the difference?
The difference is that a good software engineer is lazy in a constructive way (which allows to build reusable software and automated processes) while a bad software engineer is lazy in a destructive way (which destroys any chance for a reusable software and dooms you for long hours of struggling to understand and fix the bad code).

And here is a short example:
The var keyword allows implicitly typed variable declaration.
To tell the truth, it doesn’t allow to be a bad lazy software engineer!
Why bad? Take a look at the code below:

var database = DatabaseFactory.CreateDatabase();

What is the meaning (meaning = type) of the database object in this context? Do I really need to guess that? Does somebody expect me to go to its definition to find out?

//...
foreach(var observingStore in wareHouse.Stores)
{
//...
}
//...

What is the meaning of the observingStore object in this context? Was it named observingStore due to its implementation of the Observer pattern (which implements IObserver), or is it just an object name of a Store, ObserverStore or even ArgicultureStore class type?

Remember, you want to be lazy in a constructive way; You want to read those lines of code without wondering. You want to immediately grasp the meaning (types) of the objects you are dealing with, without switching the context and jumping to a different location just to refresh your memory.

The var keyword was introduced for one and one purpose only; To allow usage of anonymous types. Therefore, this is the only place you should use it! Unless you are a bad lazy software engineer (which clearly is not the case :) ) you will follow the rule!

Monday, May 25, 2009

Scientist Office Grant

The Scientist Office provides support to Israeli hi-tech companies in the field of innovative research and development (R&D). A month ago we applied for such a support and I was advised (thanks to Avi) to summarize the experience for those who might be interested in the future.

Here is a short list of Don’ts and Dos from the technology perspective.

DON’Ts and DOs:
  • Don’t use external consultants:

    • All the information is freely available here.
    • The application forms are easy to follow and easy to understand.
    • Using an external consultant only adds complexity, sometimes due to his eagerness to “contribute” to the process.

  • Don’t write a lengthy application; Summarize your technology scantily, mainly describing the following:

    • What are the key points of the current technology (if exists any).
    • Why the current technology (or current market’s technology) doesn’t work for the required problem.
    • How your technology innovative development will address the required problem. Here you can broaden your key points and explain in more details what the technology steps you will apply. Any algorithmic or technology innovative solutions must be described in a high to mid level (All the Scientist Office’s inspectors should keep confidentiality).

  • Do provide a Block Diagram (possibly Component Diagram in UML) that describes in a high level the architecture of your future product.

    • Provide a short description for each component and emphasize the innovation in each component if exists.

  • Do provide R&D Tasks break down as follows:

    • Don’t break down the tasks to Design, QA or DB support. It’s obscure. Incorporate those inside the tasks themselves.
      For example:


      Don’t

      Do
      Task A = 6.5 months (resource time)

      • Design=0.5M
      • Dev=4M
      • DB=1M
      • QA=1M
      Task A = 6.5 months (resource time)

    • If you have a task that spans over 2 years (2-year application), divide the task by meaningful milestones.
      For example:


      Application

      Don’t

      Do

      Year 1
      Visual Studio Integration IVisual Studio Toolbar Integration

      Year 2
      Visual Studio Integration IIVisual Studio Property Plug-In Integration

  • Do a realistic estimation of the development tools and licenses:

    • Chief Scientist supports only development; don’t provide any production costs.
    • Chief Scientist supports one computer per R&D team member.
    • Chief Scientist encourages the use of local sub-contractors during the development phase.

  • Do be prepared to stand by your application:

    • To explain why your technology is needed.
    • To justify the feasibility of your solution; Show you have enough resources (or that you plan on hiring them) and demonstrate any technological proof of concept.
    • To justify any development cost or use of a sub-contractor.

I hope that this short list helps you, but if you still have questions you are most welcome to write me and I’ll gladly try to assist.

Monday, May 18, 2009

Separate Domain from Presentation – part II

Cross post from IRefactor

This is a second post in the series of posts about “Separate Domain from Presentation” Refactoring.

Previous Posts:
Separate Domain from Presentation – part I

Last time we discussed the ways to disconnect the Presentation (FrmMain) from the Domain Object (CoursesDS) in the IRefactor.CoursesView project. As a consequence, instead of the bloated all-in-one initial project we ended with the following:
  • IRefactor.CoursesView – represents the View (CoursesView) without the domain object.
  • IRefactor.Common – represents the domain object (CoursesDS) without the UI elements.
It’s time to continue the UI and BL separations further more. For that purpose I will use the MVP pattern. It seems that there are a lot of misunderstandings regarding definitions of the UI/BL separation patterns (take a look here), I will focus on the following definitions:

In my post, MVP = Model-View-Presenter will basically stand for:
  • Model – Hey, I am the domain model;
    I know how to manipulate model objects in order to perform required application logic and persistency.
    I don’t know how to visualize to the user any information or how to respond to any action the user may take.
  • View – Hey, I am the view model;
    I know how to visually represent to the user information (that will be provided for me by the Presenter).
    I know how to perform simple data binding and possible simple UI actions that modify the visual layout of the screen.
    I don’t know what to do when an application logic or persistency are required.
  • Presenter – Hey, I am the presenter model;
    I know how to handle user requests to the View (which are more complicated than a simple data binding) and how to delegate those requests to the Model.
    I know how to query the Model in order to delegate information to the View, if any should be displayed to the user.
    I don’t know how to draw widgets graphically (that’s View’s concern) and I don’t know how to perform any application logic in order to derive that information (that’s Model’s concern).
Those who have sharp eyes, will probably spot here the use of a Supervising Controller (that doesn’t introduce right away drastic changes to the code in the spirit of Refactoring. Later on, one could turn the View into the Passive View while continuing to refactor).

MVP - Supervising Controller

Refactoring Steps:
  • Rename the IRefactor.CoursesView.FrmMain class to CoursesView. Go to FrmMain, right click on it and use Refactor » Rename command to rename it easily.
  • Create a class CoursesPresenter in IRefactor.CoursesView.
SeparateDomainFromPresentation.CoursesPresenter
  • Add to CoursesPresenter class a pointer to the CoursesView (pay attention to the fact that the view is readonly)
public class CoursesPresenter
{
private readonly CoursesView view;
}
  • Add to CoursesPresenter a constructor that receives CoursesView instance.
public CoursesPresenter(CoursesView view)
{
this.view = view;
}
  • Compile the Solution and execute the Unit Tests.
  • Now we need to delegate user’s interactions from the view to the presenter. We can do it rather by inheriting the EventArgs and creating a CoursesEventArgs class, or we can let the CoursesPresenter query directly the CoursesView and grab the required data. Here I’ll grab the CoursesDS domain object directly. Add to the CoursesView the following:
public CoursesDS Courses
{
get { return coursesDS; }
}
  • Let’s start with the Save event delegation. If you look closely at the coursesBindingNavigatorSaveItem_Click event handler, you will notice that the method has two different responsibilities. It treats the required data binding and then performs data access operation in order to save the CoursesDS domain object. To separate the concerns, let's use another Refactoring step called “Extract Method”. Select the data access code, right click on it and use Refactor » Extract Method command to extract the code into a new method called “Save”.
SeparateDomainFromPresentation.SaveItem
// ...
this.Validate();
this.bsCourses.EndEdit();
// Changed from auto generated code.
Save();
// ...
private void Save()
{
if (coursesDS.HasChanges())
{
CoursesDS.CoursesDataTable changes =
this.coursesDS.Courses.GetChanges() as
CoursesDS.CoursesDataTable;
if (changes != null)
{
taCourses.Update(changes);
}
}
}
  • Compile the Solution and execute the Unit Tests.
  • After breaking the coursesBindingNavigatorSaveItem_Click method we suddenly realize that the Save method doesn’t belong to the CoursesView class as it does a data access operation. By all means this operation should be inside the domain model (business logic). In the meanwhile we will push the method inside the presenter.
  • In CoursesPresenter create a new method called Save. The method will retrieve the CoursesDS domain object from the CoursesView and save the object into the DB.
public void Save()
{
CoursesDS coursesDS = view.Courses;
//...
}
  • Compile the Solution and execute the Unit Tests.
  • Copy all the code from the CoursesView.Save method into the CoursesPresenter.Save method and adjust the new code to its new “place” (pay attention to the CoursesTableAdapter that needs to be redefined).
public void Save()
{
CoursesDS coursesDS = view.Courses;
if (coursesDS.HasChanges())
{
CoursesDS.CoursesDataTable changes =
coursesDS.Courses.GetChanges()
as CoursesDS.CoursesDataTable;
if (changes != null)
{
using (CoursesTableAdapter taCourses = new CoursesTableAdapter())
{
taCourses.Update(changes);
}
}
}
}
  • Compile the Solution.
  • Now, for the fun part; Put all the code within the CoursesView.Save method inside remarks and declare CoursesPresenter object that calls to its Save method.
private void Save()
{
//if (coursesDS.HasChanges())
//{
// CoursesDS.CoursesDataTable changes =
// this.coursesDS.Courses.GetChanges()
// as CoursesDS.CoursesDataTable;
// if (changes != null)
// {
// taCourses.Update(changes);
// }
//}
CoursesPresenter presenter = new CoursesPresenter(this);
presenter.Save();
}
  • Compile the Solution and execute the Unit Tests.
  • Walla! You have successfully moved a data access method from the view to the presenter. With continuous refactoring you can push that method even further in the data access layer.
A quick summary:

  • We introduced a new presenter class, called CoursesPresenter.
  • We moved the Save method (which does a data access operation) from the view into the presenter class. (Don’t worry we will eliminate the Save method from the CoursesView in the next post.)
  • The same should be applied to the Load method (FrmMain_Load). I won’t show it here, just use the same principle.
Here is the schematic view of the current IRefactor.CoursesView project.

SeparateDomainFromPresentation.MVP
Clearly, it’s not the same as the MVP pattern we depicted earlier. Future postings will explain additional steps to refactor towards the MVP pattern, by applying:
  • Events – the presenter handles complicated user events by subscribing to the view.
  • Interfaces – the presenter should manipulate the view only via an interface.Failing to do so, will break the view’s encapsulation.
References:
Take a look here for a good summary on Smart Client development.