Thursday, April 2, 2009

Moving away from blogger to wordpress.

I have decided to take blogging more seriously. At the same time, I feel blogger is too much work for me specially with all code editing / formatting without any built-in support. So, I have made up my mind to move to wordpress. This is my new blog @ wordpress: Lazy Programmer’s Shortcut. I promise to be more regular this time.

Thursday, March 26, 2009

Thinking in Objects

Long ago, I had to write some code which do this:

Given two list 1. oldList 2. newList you have to find out:
1. The elements which are common in both list.
2. The elements which are new in the newList (means they were added)
3. The elements which are in oldList and not in newList (means they were deleted)

Definitely not the hardest kind of problem! I quickly grabbed my keyboard and wrote something like this :

public class CollectionModificationHelper {

public static List getCommonElements(List oldCollection, List newCollection) {
//iterate on oldCollection and find the common elements
}

public static List getNewElements(List oldCollection, List newCollection) {
//iterate on newCollection and find the new elements
}

public static List getRemovedElements(List oldCollection, List newCollection) {
//iterate on oldCollection and find the deleted elements
}
}



Simple solution and works fine. Only problem is, its iterates over the same collection again and again to find the old/common/new elements, not a big deal if you are not worried about performance.

Yesterday, I had to write the same code! Almost 4 years after I wrote the first version, seeing a hell lot of code, reading a hell lot of materials about Object Oriented Programming and design, this is what I wrote without much thinking:


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import org.apache.commons.collections.CollectionUtils;

public class CollectionModificationHelper<T> {
private Collection<T> oldCollection;
private Collection<T> newCollection;

private Collection<T> newElements = new ArrayList<T>();
private Collection<T> commonElements = new ArrayList<T>();
private Collection<T> removedElements = new ArrayList<T>();

public CollectionModificationHelper(Collection<T> oldCollection,
Collection
<T> newCollection) {
super();
this.oldCollection = oldCollection;
this.newCollection = newCollection;

init();
}

public CollectionModificationHelper(T[] oldArray, T[] newArray) {
this((oldArray == null ? null : Arrays.asList(oldArray)), (newArray == null ? null : Arrays.asList(newArray)));
}

private void init() {
if(CollectionUtils.isEmpty(oldCollection) && CollectionUtils.isEmpty(newCollection)) {
//nothing to do!
} else if(CollectionUtils.isEmpty(oldCollection)) {
if(!CollectionUtils.isEmpty(newCollection)) {
this.newElements = new ArrayList<T>(newCollection);
}
}
else if(CollectionUtils.isEmpty(newCollection)) {
if(!CollectionUtils.isEmpty(oldCollection)) {
this.removedElements = new ArrayList<T>(oldCollection);
}
}
else {
for(T item : oldCollection) {
if(newCollection.contains(item)) {
commonElements.add(item);
}
else {
removedElements.add(item);
}
}

newElements.addAll(newCollection);
//first add all new Collection in new element.
newElements.removeAll(commonElements); //then remove the common elements.
}
}

public Collection<T> getCommonElements() {
return commonElements;
}

public Collection<T> getNewElements() {
return newElements;
}

public Collection<T> getRemovedElements() {
return removedElements;
}
}



Its interesting to see how your thought process changes over time. As far as I my opinion goes, the 2nd solution is much elegant than the first one! In the first one, I was just not thinking in Objects!

Over the years, as you are involved in serious development, you will surely learn many technologies, tricks, techniques. But I think you must thrive to learn how to think in Objects. Once you can achieve that, you will find a whole new world of idea about how the objects/components should interact. Once you are there, you will love it. I am not saying I am there already, but I sure did come a long way from where I started and trying to master it everyday. How do you prepare yourself? Practice & Read. My two best guru in this area are both named "Martin"! "Robert C. Martin" & "Martin Fowler" :) Do have a look at their work if you haven't already.

Lastly, what code is good code without some unit tests!


import java.util.Collection;

import junit.framework.TestCase;

public class CollectionModificationHelperTest extends TestCase {
public void testWithNullCollections() {
Integer[] old = null;
Integer[] newC = null;

CollectionModificationHelper<Integer> collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);

assertEquals(0, collectionModificationHelper.getCommonElements().size());
assertEquals(0, collectionModificationHelper.getNewElements().size());
assertEquals(0, collectionModificationHelper.getRemovedElements().size());

old = new Integer[]{1,2,3,4};
newC = null;

collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);
assertEquals(0, collectionModificationHelper.getCommonElements().size());
assertEquals(0, collectionModificationHelper.getNewElements().size());
assertEquals(old.length, collectionModificationHelper.getRemovedElements().size());

old = null;
newC = new Integer[]{1,2,3,4};

collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);
assertEquals(0, collectionModificationHelper.getCommonElements().size());
assertEquals(newC.length, collectionModificationHelper.getNewElements().size());
assertEquals(0, collectionModificationHelper.getRemovedElements().size());
}

public void testCollectionModificationHelper() {
Integer[] old = new Integer[]{1,2,3,4,5,6,7};
Integer[] newC = new Integer[]{1,4,10,11,12,13};

CollectionModificationHelper<Integer> collectionModificationHelper = new CollectionModificationHelper<Integer>( old, newC);

Collection<Integer> commonElements = collectionModificationHelper.getCommonElements();
Collection<Integer> newElements = collectionModificationHelper.getNewElements();
Collection<Integer> removedElements = collectionModificationHelper.getRemovedElements();

System.out.println("commonElements: " commonElements);
System.out.println("newElements: " newElements);
System.out.println("removedElements: " removedElements);

assertEquals(2, commonElements.size());
assertEquals(4, newElements.size());
assertEquals(5, removedElements.size());
}
}

Thursday, January 29, 2009

Evidence Based Scheduling, Estimation and Scrum

People who know me would be surprised to see me talk about Estimation, Scheduling and all the related stuff. To be frank I consider that quite boring and better be left alone for managers! However, I am so loving the new process called Scrum we are following for last 6 months, I thought I should write a line or two about it.

Long ago I was reading this article by Joel which talked about doing your scheduling/estimation based on the evidence. What evidence you may ask? If I understood it right, the evidence is your team's efficiency! Being used to have the people who has no Idea about what the "NEW FEATURE" is and doing the estimation, I kind of liked the idea. How many times have you stayed late in the office to finish the "Cool and Easy" feature that your manager Promised to deliver the next release? I always felt the manager, no matter how experienced or skilled he is, should not be solely responsible for the estimation. We are in the business of programming, and programming is art! Its not the construction business, its not the military. For any work of creativity, you need freedom and comfort. Until we adopted scrum, I was always wondering how the developers can be a part of the whole management thing specially given the lack of interest of the developers in such things.

I am not going to describe what scrum is and what are the common benefits of following scrum, you will find plenty of reference in the net. I'll just point out what are the things that I think scrum is so effective from estimation point of view and lucrative from a developer's perspective, So here is my two cents:

1. The Team does the estimation! Your team is composed of people with diverse skill sets. When you throw a new story to a team, at least 2 of the team members would have some kind of idea about how to do it. For some other story, may be some other team members will put their input. So the estimation will be as good as it gets. And after two or three sprints with the similar kind of stories, the estimation should be perfect!

2. The Developers make the Promises! If you are some investor in any software business, and want to have some feature done within a specific time frame, here is a piece of advice from a man in the tranches, ask your developers, not the manager! If a developer commit he will do something done within a specific deadline, he will. We developers are so dumbly proud that we will even sacrifice our personal life to meet the deadline that we promised. On the other hand, if you ask your manager, he will just keep pushing the developers because he can't do the things himself even he wanted to. That way, you will end up with a buggy and messy product which is the outcome of all the hatred and frustration that your developers produced during the overtime that they did. Scrum does not have a project manager! Scrum has a Scrum master whose responsibility does not include estimation! It is the team who did the promise during your sprint planning that they will accomplish the features. Any self respecting and efficient team will thrive to achieve that. You will be surprised to see the team requesting you to keep the workspace open during the weekend so they can polish the stories for the reviews! Self-management- this is what scrum is all about. In a manager led project, not all the team members share the same responsibility as the manager. Since the manager is solely responsible for all the planning and estimation, other team member doesn't event feel responsible for the project because they are not at the gun point! This is specially true when the manager tries to accomplish some impossible deadline.

3. The Estimation is based on Evidence! Right after 2 months of following scrum, we kind of knew our team capacity is 80 points per 15 day sprint. After doing 10 sprints, we can now almost 90% accurately tell that if we plan 100 points, we are going to do overtime and we plan 60 points, we will be relaxing! How do we calculate the 80 point? The stories or the tasks that we estimate are constantly compared with the stories or tasks that we did in the previous sprints. We will say, it took us 2 days to do that "user registration form" with all the unit tests and automated tests which was a 5 point story. So we think the "user account detail collection" is a 8 point story which will take 3 days. Simple yet so efficient! One thing about estimation we don't give much importance is our hunch or intuition! But we develop our ability to "guess" over so many trials and errors! Our subconscious mind is constantly collecting and processing information and our "guess" is the outcome of that. When 6-7 people are guessing something, its the fruit of years of experience that should not be overlooked. It is as close an estimation as you could ever get.

4. Scrum is sustainable! Scrum is by the developers , for the developers :) Forgive my cheap joke, but couldn't help it ! We are making the estimation, we are making the promises, we decide whats best for the product, we choose the technology, we take the pride! We don't have a manager to micromanage us, instead we have a scrum master to lead us. We work for ourselves, we work for the team, we work for the product. The satisfaction that this brings us can't be compared to anything else, no amount of money or facilities can bring this. We don't feel sick every week, we don't think we are underpaid, we don't feel the constant anger, we don't think about skipping the office each morning, in a word, we don't burn out! We are happy developers who have fun in the workplace. Believe me, if you want a good product, you don't need fancy office or fancy furniture or worlds best salary package or even worlds best programmers. You need happy and motivated developers who are smart enough to get the job done. I believe scrum provides the best way to get there.

Having said all these, I must warn that scrum is not for everyone. Scrum is all about self-managed team. That requires highly skilled and seasoned developers who are matured enough to self manage. Scrum requires honesty which is usually not a problem with programmers. Most of all, scrum requires teaming. If your developers can't jell together, you will end up with highly inefficient team. One of the main reason I feel we could adopt scrum so easily is because each and every developer of the team is quite experienced and has a minimum level of competency. I wonder how we would adopt scrum if we were a bunch of armatures.