About   Forum   Wiki   Home  

       
    Managed Chaos      
   
Naresh Jain’s Weblog on Object thinking, Patterns, Open Source, Agile and Adventure Sports

 
`
 
Tags
Recent Comments
Quick Search
Recent Entries
Categories
Archives
December 2008
M T W T F S S
« Nov    
1234567
891011121314
15161718192021
22232425262728
293031  
Add to Technorati Favorites

Syndicate This Blog
Entries (RSS)
Comments (RSS)

Self Documenting Code Example

Saturday, November 8th, 2008

Yesterday a colleague @ Directi was writing some code and was very unhappy about the code. He was not sure how to write the following method without having to add a comment to explain the rationale behind the code’s logic.

private HttpSession renewSession (HttpServletRequest request, HttpServletResponse response)
{
HttpSession session = webUtils.getSession(request, response);
session.invalidate();
return webUtils.getSession(request, response);
}

The method name expressed what the code was doing (renewing an existing session) but the “why” it was doing what it was doing was missing. The why is very important for someone to understand. This method was invoked from the following method:

void createAuthenticatedSessionUsingAuthenticatedEntity (HttpServletRequest request, HttpServletResponse response)
{
HttpSession session = renewSession(request, response);
AuthenticationInfoBean authInfoBean = authUtils.getAuthInfoBean (request);
session.setAttribute(getAuthenticatedUserBeanKey(), authenticatedBeanCreator.create(authInfoBean.getUsername(), authUtils.getValidatedEntity(request)));
}

One option was to rename renewSession method to renewUnAuthenticatedSessionToEliminateSesionFixationByInvalidatingSession. But in the context where this method was used, it would be too much noise. Not always I’m interested in how and why are you renewing the session.

Another option is to write a JavaDoc for the renewSession method. Personally I hate JavaDocs and I was interested to find a way to eliminate that. So I asked the developer to first write the JavaDoc to express what he wanted to express. He wrote:

/**
* This method retrieves the unauthenticated session, then invalidates the session to eliminate session fixation issue and creates a new authenticated session.
* @param request HttpServletRequest
* @param response HttpServletResponse
* @return HttpSession Authenticated Session.
*/
private HttpSession renewSession (HttpServletRequest request, HttpServletResponse response)
{
HttpSession session = webUtils.getSession(request, response);
session.invalidate();
return webUtils.getSession(request, response);
}

Now looking at the comment it was easy for me to figure out how to write the code such that the comment is not required. This is what we ended up creating.

private HttpSession renewSession(HttpServletRequest request, HttpServletResponse response)
{
HttpSession session = retrieveUnAuthenticatedSession (request, response);
eliminateSesionFixationByInvalidatingSession (session);
return newlyCreatedAuthenticatedSession (request, response);
}

Again its arguable if writing code this way is much better that writing a small JavaDoc comment. As a rule of thumb, I always prefer self-documenting code over code which needs comments to support it. The real problem comes from the fact the comments soon fall out of place with the code. And why spend all the extra time maintaining code and its comments and make sure they are in sync.

Throwing Away Code

Tuesday, October 7th, 2008

After burning my hands several times, I have concluded that

Throwing away code regularly will save a lot of time, effort, frustration, etc in the long run

Also

Throwing away code is an effective and efficient way to achieve Simple Design

Hence I propose, we add “Throwing away code” as a practice under the Simple Design, XP practice.

Mother of all Software Design Principles

Wednesday, September 24th, 2008

Design is the art of making constant trade-off decisions; Good Design has balanced Trade-offs!

The problem with design, as with life is that …… You can’t have it all!

Its easy to stick with extremes (complete upfront design v/s  code & fix style design), but its really hard to strike a balance (just enough or just in time design). Just enough is relative and means different things to different people. Also varies from context to context. Just enough design in one context can mean over-engineeing in another context.

Also, there is no ONE way of doing things. There are always options when it comes to designing software and one has to choose a approach that makes most sense. Is that the best design? Do you really need the best design? Its always easy to find a better design in retrospect.

Hence I say, the only Universal truth is that there are no Universal truths. Even law of gravity does not apply universally.

Micro-Design v/s Macro-Design v/s BUFD

Monday, September 22nd, 2008

My 2 cents to help with all the confusion out there with the word Design. (when I say Design, I really mean Object Oriented Design).

When we are developing and hence designing using Test Driven Development (TDD), the meaning of the word design is very different from what it means in the context of Big Upfront Design (BUFD). Even if we are not referring to BUFD, the amount of design required can vary significantly. Some people even challenge tge whole notion of design being different from code. There has been (and will continue to be) a disagreement regarding how much to design before writing code?

Of late I find myself using the phrase micro-design to refer to the baby steps in the evolutionary design process, the kind of design that is really driven by the unit tests. While micro-design is very important and an integral part of development, there are times when you need a slightly bigger picture. For Ex. sometimes a feature can span across the software system and scope of this design is slightly more than micro-design, but very less compared to BUFD. I refer to the design step of this scope in the evolutionary design process as macro-design. I find prototypes and acceptance tests are really great at driving macro-design.

I find it really useful to call out to developers that this is micro-design step v/s this is macro-design step v/s this is BUFD.

Unit Tests Validates Micro-Design

Monday, September 22nd, 2008

I’m about to make a rather controversial statement now: “Developers who use purely inside-out avatar of TDD, .i.e. use unit tests to drive their development, are really using tests to validate their design and not so much to drive the design”.

The reason I think this way is because in my experience, developers who drive development using unit tests already have a mental model, whiteboard model, CRC card model, etc. of their design. Unit tests really helps them validate that design. (This is clearly not same as BUFD (Big Upfront Design). In this context its micro-design, design of a small feature not the whole system). Of course there is some amount of driving the design as well. When developers find out that the design they had thought about does not really fit well, they evolve it and use unit tests to get feedback. But as you can see the intent is not really to discover a new design by writing the test first.

Is this wrong? Is this a sign that you are a poor developer? Absolutely no. Its perfectly fine to do so and it also works really well in some cases for some people. But I want to highlight that there is another approach to influence design as well.

In my experience, using an Acceptance tests helps better with driving/discovering micro-design. When your test is not in the implementation land, when its in the defining-the-problem-land, there are better chances of tests helping you to discover the design.

While TDD is great at driving/discovering micro-design, Prototyping is great as driving/discovering macro-design.

Summary of Styles of TDD workshop

Monday, September 22nd, 2008

At the Agile 2008 conference in Toronto, Bill Wake and I faciliatated a workshop on Styles of TDD (had to change the name from “Avatars of TDD”, based on feedback from people that most people don’t know the word Avatar). You can find a quick summary of the workshop here : http://agile2008toronto.pbwiki.com/Styles-of-TDD

When does Design begin?

Sunday, September 21st, 2008

I used to think that Design really beginnings once you have the requirement (user story) in place. Over the years, I have learnt that design is not just a phase on the project. Design is quite intertwined with other activities we do during development and is spread through-out the life-cycle of a project. IMHO, there’s no discrete point in time on your project when you are not designing. To put some meat to this topic, let me share a recent experience with you which will reinforce my point.

A good buddy of mine, (who had been a TDD practitioner for a while) called me up and told me to have a look at some code. He was not very comfortable with the way the classes were interact with each other (design smell). I looked over the code and I agreed with him. The classes depended on each other in an awkward manner. Then I looked at the tests and I felt the tests were not really right. Could not tell why exactly, but something did not seem right. I asked him to show me the user story he was working on. I looked at the story and I realized what was happening. The way he had his story broken down, was quite different from how I would break it.

So I asked him, if I could give a shot at breaking down the stories differently. We spent some time and came up with user stories that kind of make sense to me. That was followed by a short TDD sessions. We got rid of the awkward class dependency issue, but ran into another issue. Well that’s not the point. What’s important here is, we realized that breaking down the user story differently lead to a very different design. What does this mean? We concluded saying, the way we create our user stories can impact the software design. So by breaking the user stories differently one can lead to a different design. Hence while we are creating/breaking down user stories, we are making design decisions.

We can take this one step further. I’ve had experience on real projects where depending on the order in which we developed our stories, the design evolved differently. Jeff Patton likes to say that when the stakeholders take a decision of building software to solve a business problem, they have made a design decision.

Conclusion: Design begins way before we think it actually does. We know Prototyping and TDD is a great way to validate those design decision. Don’t forget the best feedback is got when actual user use your software. Hence try to realse as frequently as possible. May be on a daily basis.

Prototyping, a forgotten Design Practice

Saturday, September 20th, 2008

Amongst the gazillion myths about Agile, one of them is “Agile means no design, its a cowboy coders’ feast”. Give me a break, you think its cool to pretend that code just flows out of your fingers without any design/thinking? Why is thinking about design before coding production code looked down upon? I completely understand the pitfalls of big upfront design and I’m not proposing that. Whether you use CRC cards, white board, acceptance tests, mental models or whatever have you, you are designing. You might not think about it as traditional design. But think about it, you are actually designing. And there is nothing wrong with it. You are not a poor developer if you do that. In fact as I know, some of the most respected programmers in the industry do some form of design before they code production code.

In fact I claim that when you are breaking down your user stories you are designing your software. I actually have an example of how breaking down your stories differently can lead to a very different design. In this blog post, I explain why.

One of the things that I have found very useful when building software is to just prototype 2 or 3 different approaches, to explore the problem domain, before actually TDDing the whole solution. Recently I added version control support to FitNesse.  The approach I used was I tried first logical solution that came to my mind. It worked, but as I started using it, I need more stuff and the design I had would not really fit well the new requirement I had. I could have incrementally refactored the design to suite the new requirements, but since I treated the code as prototype, I threw it away and started from scratch. It seemed a lot less effort to throw it away and rebuild it from ground zero. Again this time, I just treated the code as prototype. I was really exploring a new idea and I wanted to test the design by writing some quick and dirty code. Usually these sessions might last a couple of days. These are clearly not months worth of effort.

It turned out that my second design worked for single user, but would not work for multiple users. It had a fundamental design problem that I could not have thought before hand. (May be some other smart people could have found it before we started, but I could not. May be having a pair would have helped, but this was open source and I did not have a pair).  Again this was a quick and dirty way to get a high level design feedback.

This style really complements the whole TDD philosophy. Its not that you do a quick and dirty prototype and you don’t need to do TDD any more. Prototypes really help you explore a broader aspect of your system design than TDD can do. TDD helps get feedback about your design and also helps build a safety net, but there are multiple design options and TDD helps you achieve one of those designs. How do you know if there is some other class or library that can actually work, sometimes TDD can help you with that. But if you are completely unaware of its existence, you would need an exploratory session to figure out your options. Once you know what options you have, TDD can really help you solidify it. Hope you get my point.

Sometimes, I write a high-level automated test and build various prototype. The automated test really cuts the manual check at the end.

Prototype is similar to the spiking practice that XP suggests. Somehow spiking has really fallen of the face of the earth. But XP really recommends you spike out various approaches to solve a problem, pick the best and then TDD the solution.

Prototyping is not a new practice its been around for ages. In fact its been around not just in software but also in other disciplines (craft related) like painting. A lot of times, painters create clay models of their subject to understand the depth or other dimensions about the subject. This really helps them give the real feel to their painting.

Now that your are convinced about the importance of prototyping, the next question is should you always prototype? Of course not. If you are not sure about the design, if you want to explore the problem domain, or if you think there is high technical risk with what you are building, sure. Else its just ritual (waste of time).

So when does prototyping stop? At some point you might feel confident enough that you understand the problem domain enough and you can switch to TDDing your production code. But if the requirements changes and something fundamental on which your design decision was based changes, you might be able to just incrementally refactor your design to suit the new requirement. Sometimes, you hit the point where trying a prototype and throwing away your existing design might be the best option. You are the best judge.

3rd Annual Simple Design and Testing Conference

Monday, September 15th, 2008

Just got back from the 3rd SDTConf. I’m very happy with the conference overall. We had over 40 participants at the conference. (A little less than I expected, but they were all really passionate people). That’s right, Quality OVER Quantity.

We discussed some really interesting topics. Check out the conference schedule for more details. I also got to pair with Micah Martin on the Avatars of TDD. It was fun. We hacked some Ruby using RSpec.

Big thanks to Jim Newkirk for helping me organize this. Also big things to all our sponsors, Microsoft, Agile Alliance, Rally, Version One, SQE and Open Information Foundation who made this conference possible.

Toolkit v/s Framework

Friday, September 5th, 2008

Toolkit: A set of related and reusable classes designed to provide useful, general-purpose functionality. Ex: Collections, IO Library, etc

Framework: A set of cooperating classes that make up a reusable design for specific types of software. Ex: JUnit, Spring, etc

Toolkit Framework
 Code reuse Design reuse (Dictates the architecture or part of it by defining overall structure and key responsibilities of classes) 
 Delegate calls  Create application specific subclasses of abstract classes from the framework
 We define the main body of the class and call the toolkit code we want to reuse  Reuse the main body and write the code it calls
 Very helpful. Library are usually built by experts and rest of the developers can leverage library builder’s expertise.  Faster to build applications this way. Also ensures same structure across different applications, hence easy to maintain. At the same time frameworks are guilty of enforcing stuff on the developers and loss of some creative freedom.
    Licensed under
Creative Commons License
Design by vikivix