Tuesday, November 28, 2006

Team work

As I started working at my new job, I noticed that the biggest problem was team work. The problem consisted in the fact that the project was pretty big and the team was also pretty big, and distributed across the entire floor. From the programming point of view, the problem was that the modules were tightly coupled, for example in order to develop my module, I had to use a library for a hardware external device, and a library for web service calls.
Almost all programmers were complaining that they can’t work because some module which they had to use isn’t working properly. Sometimes, I saw some developers just waiting the whole day, just because some web service which they used wasn’t working, or they needed for someone to write a web service so they could call it in their application.

And they thought it’s something normal that they should be provided with the perfect libraries and perfect working code and working conditions so they could work. When the project deadline approached, they started to work till midnight.

So what I have learned from this, is that you shouldn’t expect a provided module to work perfectly, and you shouldn’t wait for some problem to be resolved in order to continue your work. Your application architecture should provide a method so that the “integration” with other modules could be delayed to an indefinite moment in the development cycle. Using this architecture, if you develop for example a windows application, you don’t have to wait until the database architect designs the tables, or some specific web service is created for you.

I developed my own architecture to prevent all these issues, and I must say I’m pretty pleased with it until now. In fact I can’t call it “my own” because it is based on a series of design patterns, like MVP (Model – View – Presenter), and Dependency Injection.

I’m not going to discuss about the MVP in details here (maybe in some future post). The main idea is that MVP is a modified MVC, more loosely coupled. The “design by contract” is the main technique that stands at the base of MVP, and also helps us to defer the integration with other modules.

The presenter is the main business entity, and it is usually concrete (not abstract/interface). All other entities can be interfaces. The presenter is given a view and a model. It should take the data from the model and “give” it to the view, and also it should listen to events coming from the view or the model. Usually, the presenter works with abstract views and sometimes with abstract models. So, “design by contract” means that we have a “view contract” – an interface which the presenter will work with. The same pattern applies to the services which are used by the presenter business.

Let me give you an example: a simple windows forms application which calls a web service to give a list of persons, displays them, and saves some of them in a local database/file. How should we develop our application, considering that the web service isn’t developed yet, and your boss hasn’t decided yet whether to use a local database, or some xml files. If you don’t like programming more than 10 hours a day or in weekends, then don’t wait for your boss to make the decision, or the other person to develop the web service, in order to start programming.

Presenter First, a variant of MVP, means developing the presenter first (doh…), and then the services and views.

So, we start with our presenter:

public class PersonsPresenter
{
private ILocalDataAccessService localDAL;
private IPersonsView personsView;

public PersonsPresenter (IPersonsView personsView,

IOnlineService onlineService, ILocalDataAccessService localDAL)

{

this.personsView = personsView;

personsView.Persons = onlineService.GetPersons();

personsView.SaveButtonPressed +=

new EventHandler<EventArgs>(personsView_SaveButtonPressed);

this.localDAL = localDAL;

}

void personsView_SaveButtonPressed(object sender, EventArgs e)
{
localDAL.SavePersons(personsView.SelectedPersons);
}

}

The presenter should be provided with a view (IPersonsView), an online service (IOnlineService) and a local data access service (ILocalDataAccessService). The business is very simple, the presenter takes a person list from the online service and puts them in the view. When the save button is pressed, the selected persons from the view are saved in the local database. Now we can implement our services and view. The view is a windows form which implements the IPersonsView interface, the online service implementation could return a default list of 3-4 persons for example, and the local data access service could save the persons in a in-memory list until our boss decides between xml files, isolated storage, and sql server database. So we can work with mocks for an undefined period of time.

The manner of constructing the presenter is based on dependency injection – constructor injection.

We could also make a mock for the view, and make automated tests for the presenter (This is a major advantage of using MVP, perhaps in a later post I will talk more about TDD – Test Driven Development).

In conclusion, we succeeded in developing our main application business and interface, without knowing the exact implementation of the local data access layer and the web service.

Now, if the programmer responsible for the online service gives us a library representing the service proxy, we just have to implement an adapter for our interface of that proxy. Don’t forget to catch and rethrow all possible exceptions from that library, belive me it will help you. Especially when you are developing a module which has a visual interface, it will spare you of a lot of problems if you display “Web service proxy error: Object reference not set…” rather then just “Object reference not set…”. When you will be asked by your boss about this error, you can respond “Can’t you see??? It’s a web service proxy error, it’s not my fault!” : )