Tuesday, January 24, 2006

Few findings about Presentation Model

Almost every project that I have been on strives for code testability. By increasing code testability one can better the design of the solution as well as continue to change code without worries. However when it comes to increase testability of the view in the classic MVC, it is always hard to do. Microsoft proclaims that they have achieved MVC (or Model-ASPX-CodeBehind), but it fails to address the testability issue of the code in V and C: CodeBehind logic are extremely hard to test against. Both the Presentation Model (PM) and the Model-View-Presenter (MVP) pattern address this issue.

Having used both patterns for my past few projects, I think I am seeing some pros/cons. Today let's look at the Presentation Model first:

Presentation Model:
I like using Presentation Model (PM) when I am developing a web application. In web apps, there are a couple major headaches when it comes to increase code testability, the first of which is carrying state across requests. Secondly, in ASP.NET, the Page class gets created and disposed of every request, making using an intermediary class (such as a Presenter) to "push" content from the model to the view very difficult, and hence a directional referencing problem.

PM employs a "pull" model, meaning the consumer class (aka the code-behind) will ask for data that the PM has prepared for it. Because of this model, at each Page cycle step (Page_Load, Page_Init, etc.) the view will be in the driving seat as far as controlling when to reload the controls and what to load them with. The PM simply sits there and wait for someone to tap his shoulder to ask him to produce something. Notice the directional reference: the view has a reference to the PMs. The PMs do not know about the view, and do not push content out to force the view's state to be refreshed.

Usually you will have one PM per ASPX page, which I call a Page PM. When the page gets busy, your Page PM is likely to be a gynormous 1,000 line class, containing many properties for the use of the many dynamic view controls' use. Therefore, use sub-PM classes to better organize your code and avoid code duplication. The levels of sub-PM classes from my experience probably won't go deeper than 3 inheritance hierarchy.

Most of your Page PMs usually will have reference to the session object, in which most probably the aggregate root of your Domain Model will be stored. For a more complex Domain Model, the PM's task of flattening out this 3-dimensional beast starting with this aggregate root will make your view look extraordinarily simple.

Because PMs usually flatten out your Domain Model into some easily readable grid or string format, your Domain Model objects may not be the ultimate data holder objects that your view 's controls bind to. For example, you will obviously need a new object for a grid showing an insurance policy's type, coverages, each and every insured entity, and each coverage's premiums. (Hopefully they live in separate objects in your Domain Model). Create some what I call "Data Item" objects to facilitate data binding to your grids or lists. Data Item objects are just for holding your diced and sliced Domain Model data and have no behaviors. Think of them as classes that represent a row of data in every single grid on your page. In the above example, your PolicyInfoDataItem class will have public properties of [PolicyType :string, CoverageName :string, InsuredEntityName :string, CoverageAmount :double]. This inspiration comes from DataGridItem, and various ListItem variants in the .NET Framework.

Unit testing your Page PMs in NUnit is always not easy because it uses the Session object, which is not available in NUnit testing. I have seen people use reflection to create a fake HttpContext object that stores Session data on the current thread, which then during [SetUp] set the context object (yes it does have a setter). Then your PM unit test classes have access to HttpContext.Session.

Speaking of unit testing PMs, I find it to be much more work to use mocking to unit tests your PMs. Especially if you love constructor injection, having your PM's ctor to take all those IEverything classes and during unit tests have them all mocked out is a lot of work because PMs is much more object state dependent than behavior loaded. As a result, I would prefer state-based testing (Stubs or the Object Mother pattern) to facilitate unit testing PMs. One must also manage the creation and customization of your domain model's state carefully, because these tend to duplicate code across your test classes easily if you go with state-based testing.

Your view also should not directly instantiate or reference any Domain Model objects (as a guideline, not rule). Whenever possible, pass primitive type user input information gathered off the Page and pass them directly to the Page PM for actions. This can consolidate exception handling routines (instead of scattering them all over your views), and also decouple your view from your Model, which you might later put them into separate assemblies.

Your Page PM can also handle behaviors that your view requests. For example, whenever a button is clicked, its code-behind event handler will make a call to the Page PM's "Save" method, passing the necessary information gathered off the controls, and then the Page PM will delegate the responsibility of the actual save to the Domain Model layer.

Saturday, January 14, 2006

Agile story tips

Stories in an Agile project tend to be less talked about than Test Driven Development, Continuous Integration, and Food :-). But in fact, when it's done well it can profoundly affect the project team's productivity and end users' satisfaction towards the software. The following are a few findings from my experience related to stories management that will drive better software. Their importance are rated on a a scale of 1 to 5 asterisks:

  • Stories should be a thin-thread from the frontend all the way to the backend. (*****)

    This helps the features being developed each iteration to be completed more consistently, and consistency drives predictability, and thus increases visibility and helps business to prioritize and plan given the available time and resources.

  • Business analysts (or the sponsor/end user) should own the stories. During IPM (Iteration Planning Meeting), they should be signed-off, meaning no changes should be made when developers start developing them. (*****)

    By freezing the requirements, developers can be much more productive. Compare a 100m race between two runners, one can go all the way from start to finish without stopping, while the other has to stop-and-go every 10m because he has to worry about the next 10m track he runs will be changed. Also, by someone owning the stories, after the stories were developed the owner of the story will have the responsibility to verify the correctness of the solution. Thus this requires better-written story specifications (tying back to freezing requirements), and in the end the developed story becomes exactly what business wants.

  • Stories should be measured in terms of difficulties or story points, instead of ideal development days (IDD). (****)

    There are two camps of people when it comes to this bullet. One camp uses IDD to estimate the difficulty of a story, then uses Load Factor to measure how off they were in their original estimates. The other camp uses Level of Difficulty such as small/medium/large, or Story Points such as 1-5, so they can measure purely based on yesterday's weather, and not a number that someone uncomfortably being forced to make up.

    IMHO, the first camp's glossaries were created at "post-mortem," literally. Consider the following conversation after a project failure:
    Business: Why did you guys fail to deliver? You only delivered half of what I want.
    Developers: Because we were not productive.
    Business: Why?
    Developers: Too many damn meetings.
    Business: Hm... so in "ideal time" if you had no meetings you would be able to deliver?
    Developers: Oh yea...
    Business: So in hindsight, the original estimates you guys told me was off by a "load factor" of 1/2. Next time should I want a new software I better take that into my budget account...

    The problem is that all these numbers are only meaningful within the context of that one project. But people being people, they like to carry these numbers with them to any projects they walk into wherever they go... because apparently they have been burned before. Next time when business asks for budget for a brand new project, guess what. They will bump up the budget by half, because of that "load factor."

    By using the terms of the second camp, one is implicitly forced to think of these measurements in the context of the current project. When I say this story's difficulty is a Large, one has to ask: Relative to what? Of course, the answer is relative to the other stories of this project. When I say, Story A is a 1 and Story B is a 3, again you are forced to think in the context of the current project.

    You might ask, now if you don't bump up the budget by half, then doesn't the business not get all of what they ask for? The answer is yes. But that's the beauty of short, iterative releases. If we can do that, then in the end the business without bumping up the original budget, yes they will exactly get what they have asked for according to their business priority, perhaps the 6 out of their 10 features, but since we have delivered at least some of the features in early iterations, not only the business has saved money due to those features being rolled out, but also the business is in better shape when it comes to repositioning itself to face more real world challenges, and thus will pump more budget to continue develop the software to give them what they want.

  • If stories are small enough, then there is no need to task them out during an IPM (Iteration Planning Meeting). If stories are to be tasked, they should be estimated. As each of them are completed, actuals should be measured.

    Admit to it. Small estimates are much more accurate than big estimates. Therefore, if each story is tasked out into small chunks of time estimates, and after story completion we have its corresponding actual time spent measurement, we then can find out how much work really is to complete say Story A, a medium-difficulty story or one that has Story Points of 3.

    So what are these estimates and actuals for? They are actual prove (or tracked history) of how we complete our Stories. Let's say in Iteration One we have a story "Public user login" that has a Story Points of 3. In that iteration (two-weeks), at the IPM the development team estimates that there are a total of 10 tasks to be done to complete that story, and they busted their ass to complete that and only that story. Then, in Iteration Seven, a similar story "Restricted user login" shows up. Relatively speaking, it also has a Story Points of 3, since they are about equally difficult. However, since most of the one-time tasks to do that has been completed, the actual number of tasks to complete this story in Iteration Seven might be just 3 tasks. Now the team can use the rest of the time to build other stories, and thereby achieve more Story Points. If it turns out the team achieved total of 7 points in the end, then we say the team is kicking some ass and is more productive than they were in Iteration One. You would notice the total time spent on all tasks between the two iterations will be somewhat the same (assuming no resources change), but completed Story Points increased. From the point of the business, it rocks, because they are seeing more stuff being churned out by the team, in exactly the manner they want it to be.

    This brings up another very important point, if you notice...

  • For story difficulty measurements, whatever you use (IDD, Small/Medium/Large, Story Points), you should always estimate it using the same scale as you estimate the entire story list. (*****)

    This is the only way to measure whether the team is improving over the course of the development.

    Using the example in the last bullet, if in Iteration One the team thinks that "User login story" is a 3 Story Points story, and in Iteration Seven the team completes a similar also 3 Story Points story "Restricted login story", then if in Iteration Ten business comes back and say they want a brand new but similarly difficult "CEO only login story", now despite the fact that in Iteration Ten, after doing those two login stories, this new story requires very very little work to complete, we must again make this story have 3 Story points.

    This way, the measurements will tell the business the following:
    In Iteration One, the development completed 3 Story Points.
    In Iteration Seven, the development completed 7 Story Points (because the tasks required to do the "Restricted login story" has reduced.
    In Iteration Ten, the development completed 14 Story Points (because even few tasks is required to complete the new 3-Point "CEO only login" story).
    In terms of the business people, Story Points = functionalities = business value. They know what they are getting in a consistent basis.

    Should there be a case somewhere in Iteration Eight the number of Story Points dropped, then one has to figure out why. Here's the task actuals can come into handy. In Iteration Seven, 7 Story Points and total of say 100 actual hours of time were needed to complete all tasks. In Iteration Eight, only 6.5 Story Points were completed. But if we look at the hours of the actual, only 90 hours were recorded from all tasks. Now we know the time the team spent on the actual tasks for all stories are about the same. Probably because people having vacations or public holidays that contributes to the drop in productivity.