Tuesday, October 18, 2011

Applying SRP to WebForms

Most applications based on ASP.Net WebForms fall foul of good OO design practices because of the page life cycle and the plethora of events exposed by the many web controls. One of the key principles of good OO design is the Single Responsibility Principal (SRP). I often find that this is either completely ignored or not used enough when an application is based on ASP.Net WebForms. SRP states that every object should have a single responsibility and that responsibility should be encapsulated by its class.

With WebForms, business logic is written in the many event handlers which are part of the WebForms model. This is a hang over from the Visual Basic days when true client server applications were being built. Here the UI was a procedural wrapper over a set of Stored Procedures.

SRP forces you to ask if the code you are writing belongs in that class. If it does not, then a new class is needed for the job. Following this practice leads to a well factored code base, full of objects doing one job. In the case of the WebForm it is now only responsible for building the UI and handling the HTTP requests and response. This avoids complex and overly long WebFoms that are hard to understand and difficult to debug.

Violating SRP

In this example, the Page is a form gathering contact details from the visitor. The visitor could have arrived from a marketing campaign. The tracking codes for the campaign are a comma list of key value pairs stored in a Cookie. The four values extracted from the cookie must be included when submitted to the process which writes to the database.

A common implementation is to extract the values from the Cookie in the page load event and store them in a field on the form. When the event fires to save the form, the values are passed to the method which writes to the database.


I feel this method of working is poor. Sure, it will work. You can extract the values and send them to the database. However, the Page should only be responsible for managing the incoming Request, the out going Response and building the UI. Also, what if there are many forms on the site which have to capture this information? The code will be duplicated in many places causing problems if the name of the cookie changes. Instead I prefer to hand the task of capturing data from the cookie to a couple of classes which encapsulate the process and return a single object for the marketing data.

Applying SRP



All that this page is responsible for is passing the CookieCollection to the MarketingTrackerBuilder object. It then stores this in a private field to be passed on to the database when the form is submitted.


This class is essentially a DTO. It has no other job than to store the four pieces of information about the campaign which brought the visitor to the website. It also implements an interface. We will see why that is useful later.


Most of the work is being done in the Builder. The class knows how to extract the fields from the cookie. It is also where the name of the cookie is defined. Keeping this information here means that if anything to do with reading the cookie changes, it will only change here. Often this kind of code is scattered around many WebForm pages. Then a change to the implementation requires a search and replace on the entire code base.

When the Build method is called it first checks that the cookie exists. If the check fails it returns an instance of a NullMarketingTracker.


The NullMarketingTracker object is the reason for using the IMarketingTracker interface. We are now free to substitute the type returned as long as we code to the interface. If you review the code you can see that all references to the MarketingTracker have used the IMarketingTracker interface.

Now when values are written to the database, there is no need to check for a null strings first.

Summary

The Single Responsibility Principal is a great way to think about structuring code. By applying this to the WebForms Page object I decided that its only responsibility is to deal with the incoming request and the outgoing response. By further applying it to the code which captures the cookie data, the final design is well structured and easily maintained. If the implementation changes then the change will not ripple through the code base.

I find that this a good way to work and a great way to keep the code behind files readable and manageable.

Friday, October 07, 2011

Removing ignored files from a git repository

When I am using TFS, Visual Studio manages the files which should not be committed. So when I create a git repository I often forget to add the .gitignore file. The first reminder I get about my oversight is when I see all the DLLs being added during the first commit.

Today I decided to find out how to clean up the repository. First I added this .gitignore file to my repository:


Then I searched the internet. The first hit from Google was this post by Aral Balkan. The content and the comments provided me with all the information I needed to manage the git repository.

Searching and cleaning the repository

An instance of a git repository can be thought of as an isolated file system. As such commands can be run against it the same way as a normal file system.
The first command I needed was git ls-files which works in the same way as ls. The command git ls-files -i -X .gitignore lists all the files in the repository which would have been excluded had I remembered to set the .gitigonre.
Removing a file from git is done using the git rm. As git is a versioned file system there is the file on disk and a reference to that file in the index. The command git rm --cached will remove the reference from the index but leave the file on disk.

A script to do that

Manually removing each file from the index would take some time. It would also go against all of my computing instincts. The job needs a script.


Here I simply loop round the results from git ls-files sending each one to git rm. I am sure there are many ways to achieve the same result but this method worked well for me. I am using git bash and Windows.

Wednesday, October 05, 2011

The wonderful backbone.js

I recently gave a presentation on backbone.js at the Brighton Alt.net meeting. During this talk I demonstrated how Backbone.js can be used to organise JavaScript code into manageable layers. It’s Models and Collections manage the storing and retrieving of data. Views provide a mechanism for arranging the UI in to manageable chunks. It also has an event bus which helps reduce coupling between functions. Altogether, backbone brings order to the often chaotic world of client side development.

For the demonstration, I made a shopping list application which is available on github. Included is a web service which is used to manage the shopping list. You will need to install node.js to run the web service.

A traditional view of MVC

When first looking at backbone, I was thinking of an MVC framework in terms of the ASP.Net implementation. Here, the framework does not impose anything upon the model. The model is full of classes to capture the state and the behaviour of the system. For my shopping list it would contain types for an item, the list class, the price of the item and the state of the item. All of these would have methods which capture the behaviour. This model consists of a lot of small classes working together to define the system.

The controller is responsible for incoming requests. It will then validate the request and process it. If it is a query it will gather the required data and return it. If it was a command it will find a handler and update the model.

When complete it will load the correct view passing in the state required to render it.

The view uses the passed in data to create the representation requested by the client. Typically this will be an HTML page. The view is where we think of the client running server based MVC framework. Mainly as this is where we put all the client JavaScript.

Breaking with tradition

In backbone.js, the model object is very simple. It does not model the behaviour of a system accurately in fact, there may only be one model object. Therefore, it is not a system for building fully featured domain models.

What it does is apply the MVC pattern to browser development. Models, collections and views work together to create a wall. A wall which keeps all the AJAX code for dealing with data on one side, and all the code for building and rendering DOM elements on the other side. Without this boundary it is easy for JavaScript applications to have the same function calling a web service and updating the DOM. Over time this will lead to a system which is hard to maintain. By making a very clear separation between persistence code and UI code, backbone.js helps us to write better JavaScript.

Coding the data side

The first thing I did to find out how backbone can help my development was to create a model and a collection and point it at my web service.

I created a model object to represent an item in my shopping list:


There are three things happening above:
  1. I have created a model called ShoppingItem. This is told to use the Products collection in the constructor. It is also given some default values to be used by new instances.
  2. Here I create the collection of shopping items. In this simple demo I only have to set the endpoint for my web service and set the model object for the collection.
  3. Finally, I create a new instance of the collection.

The page itself has no real content, just a title. By using the console window in Firebug I can create, edit and delete new items in my shopping list

Here I can create a new item and when the save method is called, backbone sends a POST request to the service, creating the item.



Running this code in the browser will show backbone first POSTing the new item to the service. Then issuing a PUT to update the State, and finally a DELETE with the Id to remove it. Internally backbone uses either jQuery or Zepto for communication.

Collections

In backbone, a Model has to belong to a collection, in fact, it is a rare application where a single entity exists in isolation. Here is the Collection for my shopping list:



A very simple collection, it is told what type of Model it holds, and the URL for the web service to persist the objects to. The model object will use this URL when communicating with the web service. Finally it has method called toobuy which returns a list of all items in the collection where the state is “To buy”.

Summary

In this post I have created a shopping list in JavaScript. There is enough code here to run the application from the browser console where I can create, update and delete items from my list.

This highlights one of the first advantages of using backbone.js. I have concentrated on how my application will interact with the service before creating any UI components.

Look at the backbone.js site for more information and a growing list of examples.