Inherit or compose.. Hmm..

When designing your domain/classes, this is one decision that always results in conflicts within teams. Whether to inherit from a class or to compose that class. This is fairly subjective but here are few pointers for discussion..

Lets take this code for example:

public class GiftCollection extends HashSet {

    public Gift getRandomGift(){
        List giftList = new ArrayList(this);
        Collections.shuffle(giftList);
        return giftList.get(0);
    }
}

It is a collection of gifts that is represented as a set. The additional behavior from a set is that it can give you a random gift. It looks fairly straight-forward and would work in a even more straight-forward manner. Lets look at a usage of this..

public class GiftSelector {

    GiftCollection giftCollection;

    public GiftSelector(GiftCollection giftCollection) {
        this.giftCollection = giftCollection;
    }

    public Gift selectRandomGift(){
          return giftCollection.getRandomGift();
    }

}

This is a basic usage of the GiftCollection provided earlier. If one looks closely, though the two classes look very similar and doing similar things, there are basic differences between the two.

GiftCollection inherits a HashSet and extends to the behaviour by adding another method getRandomGift to it. However GiftSelector decided to contain a GiftCollection and delegate few calls to it.

I’ve always preferred the latter approach for following reasons:

1. The classes (both superclass and subclass) are much more flexible to change.

In this case, if GiftCollection decides to change the signature of the method getRandomGift(), it would not have an effect on the callers of GiftSelector, since it wraps the method call.

But any change to the Set implementation would affect the api of the GiftCollection class, without its knowledge. The users of GiftCollection have to change their code, though there has been no apparent change to the class. This is not an ideal scenario.

2. Easier to test.

It clearly shows that GiftSelector is much easier to test than GiftCollection. One can easily mock the dependency of the class and unit test the code. Whereas, in the case of inheritance, most mocking libraries do not provide a way to mock super classes. So its difficult to test in isolation.

3. Polymorphism through Interfaces is more flexible

One of the reasons for inheritance has been to reduce code and take advantage of polymorphic behaviour. Interfaces provide a more flexible way to achieve the same result. Composition coupled with Interfaces present a better alternative to achieve polymorphism.

This is not to say that one should not use Inheritance.

When modeling your domain, Inheritance should be used in case of a direct ‘is-a’ relationship. It should not be used only to achieve code-reuse or polymorphism.

Prefer composition over inheritance, unless you have good reasons to not do so..

Would love to hear your thoughts on this..

Advertisements

Better way to comment.. code it.

There’s been lot of discussion on the usefulness of comments in code. Many believe they’re not required and are actually a smell that your code is not readable enough.

I’d agree with that philosophy and also feel if you must add comments, add it to explain ‘why’ of the code, not what the code does. Here I’d like to explain with an example how you can get rid of some of your comments in the code.

Let’s jump to code directly.. Here’s the code that we’d clean up for this example.

[This code is for this example only. Other design decisions are not considered.]

    public String recommendGift(double budget){
		// get gifts from helper
		String[] gifts = giftHelper.getGifts();
		String gift = null;

		for (int i = 0; i < gifts.length; i++) {

			gift = gifts[i];

			// find out if gift already given
			boolean isAlreadyGiven = false;
			for (String given : giftsGiven) {
				if(gift.equals(given)){
					isAlreadyGiven = true;
					break;
				}
			}

			// calculate rating and budget
			int x = rating * 200;
			boolean ok = budget < x;

			// if both conditions satisfy, give it.
			if(!isAlreadyGiven && ok){
				giftsGiven.add(gift);
				// increment maintenance cost of the girlfriend
				maintenanceCost += budget;
				return gift;
			}

		}

		return gift;
	}

The code is fairly straight forward. From a list of gifts, it selects the first gift that is not already given and is within the budget. There are few issues with it..

1. The method is fairly long.

2. It does too many things.

3. It is not very readable.. even with the comments.

4. The comments tell you what the code does. Thats the code’s job isn’t it.

So Lets try to clean this code.. To start with,

This is fairly obvious and doesn’t need the comment. This kind of comment should be avoided. They don’t promote readability. Infact they have the opposite effect.

// get gifts from helper
String[] gifts = giftHelper.getGifts();

Next up, Lets move this code with comment to a separate method. The name can be derived from the comment that is given above. It would turn from.

// find out if gift already given
			boolean isAlreadyGiven = false;
			for (String given : giftsGiven) {
				if(gift.equals(given)){
					isAlreadyGiven = true;
					break;
				}
			}

to


private boolean isGiftNotAlreadyGiven(String gift) {
        boolean isAlreadyGiven = true;
        for (String given : giftsGiven) {
            if(gift.equals(given)){
                isAlreadyGiven = false;
                break;
            }
        }
        return isAlreadyGiven;
    }

If we continue the same way.. the final code will look like this:

    public String recommendGift(double budget){
        String recommendedGift = null;

        for (String gift : giftHelper.getGifts()) {
	    recommendedGift = gift;

            if(isGiftNotAlreadyGiven(recommendedGift)
                            && isUnderBudget(budget)){
                updateMaintenanceCostAndGiftsGiven(budget,
                                                   recommendedGift);
				return recommendedGift;
	           }
	     }

	    return recommendedGift;
    }

    private void updateMaintenanceCostAndGiftsGiven(double budget, String gift) {
        giftsGiven.add(gift);
        // increment maintenance cost of the girlfriend
        maintenanceCost += budget;
    }

    private boolean isUnderBudget(double budget) {
        int x = rating * 200;
        boolean ok = budget < x;
        return ok;
    }

    private boolean isGiftNotAlreadyGiven(String gift) {
        boolean isAlreadyGiven = true;
        for (String given : giftsGiven) {
            if(gift.equals(given)){
                isAlreadyGiven = false;
                break;
            }
        }
        return isAlreadyGiven;
    }

Few things to note here are:
1. The method has been split into multiple methods with names clearly specifying what they do. This makes it more readable.
2. The size of each method is hardly 4-5 lines.. which is fairly ideal.
3. The comments are gone, but the purpose is met. The code documents itself.

I tried to explain the motivation here in Programming as Writing


Please do share ways you’ve implemented them and made the code better..

Productivity Tips for Programmers

This post is dedicated to programmers who believe that spending more time on the project (in the office) is directly proportional to productivity of the programmer. Okay, I’ll break a secret here. “IT’S NOT“. Obviously you need to be in front of a computer to type, but the similarity with programming just ends there. Okay. So what should programmers do with their time?

Utilize portion of your working time honing your skills and updating on getting more productive. Here are a few simple things you can do:

1. Write Unit tests for higher productivity. (if you’re not already)

This is pretty basic stuff. But there are so many programmers who don’t do that. Well.. you should. This not only improves your code quality, it improves your productivity too. You’re not only more confident of releasing and modifying your code, you save a lot of time in the process as well.

Imagine you writing a large web application, a small code change means, rebuilding the application,deploying it and checking the feature (probably hidden under 5 links). Imagine doing it time after time. Now replace this with testing only that small change. This is a fairly practical example and with practice you can really gain a lot of time by testing effectively.

2. Practice your programming.

This is a no-brainer too. Look at other professionals. Cricketers improve their skills with ‘net practice‘. Musicians practice their instrument. Singers with their ‘Riyaaz‘. Amazingly, most of the programmers don’t practice.You should.

Take up a book like Effective JavaDesign Patterns and practice few principles per day. Take a few problems from Project Euler and solve them with your favorite language.

Unlike your regular projects, where you have a deadline, practice programs need not be time limited. So take your time. Do things the right way. With this practice your productivity will improve a lot in your regular work. It’s obvious, isn’t it.

3. Use libraries and help improve them.

There are many programmers who are library averse. They’d rather code it themselves than using a library. The primary reasons are:

  • They don’t know the library.
  • The library does lot of other things they don’t need.
  • They feel more in control with their own code.

Think about this

  • A library has been well tested and covers more scenarios,saving you lot of time.
  • When you improve on the library, it can help a larger community. Improving your private code couldn’t possibly have that impact.
  • To top it all, other folks are working on improving that library too. That indirectly helps your code.

In short, use a library unless it is too unsuited or heavy for your requirement.

4. Read code and technical stuff

Reading code and modifying is as difficult if not more than writing it in first place. There’s lot of good code available for reading in the open-source world. Pick up your favorite library and open up its code and start reading. You may not comprehend all of it immediately.. but with practice, you’ll be able to identify different patterns used and can incorporate them in your code too.

Apart from code, also subscribe to few technical blogs from good software experts and keep yourself updated on the trends.

Well, there are many other things you can do to improve your skills and be more productive in your work. These top my list. Do share things you do..

Interviews – Two at a time.

One of the factors that you look for in a candidate during interviews is his collaborative skills. How good is a person when it comes to carrying a conversation with a fellow colleague. How about disagreements? Does he respect arguments or gets aggressive..

How do you do that?

Here’s a proposition..

I was once in an interview session, and were short of interviewers. Lot of people showed up and we had limited time. So we decided to have paired-candidate session. This is where two candidates would appear together in an interview session. It was fairly effective and surprisingly pleasant experience. Here’s my observation from the experience..

1. There was a basic comfort during the session.

Since interviews have gone on to become this huge one-sided affairs, its become really difficult to gauge a person’s original nature during the interview. Getting a person into a proper discussion is quite a challenge. There are hardly any constructive arguments or discussions. Just questions and answers which are not a good representation of a person’s capability technically, leave alone his collaborative skills and interpersonal skills.

With another candidate in there, it is more comforting for the candidates and when they discuss, it can be more natural. This also spawns many useful discussions and arguments.

2. Simulate a typical work like setup

At work, you’re faced with similar situations fairly repeatedly. You are always discussing technical solutions with your colleagues. Either looking for support or challenging a solution. However, this situation is not repeated effectively during a interview session.

Two candidates at a time can help simulate a typical work-day, and can help gauge a person’s interpersonal and technical capabilities.

3. Interviewer as a moderator

I’ve always felt that interviewers should be doing more of listening. Just get the candidates talking and listen to them. With one-to-one interviews, mostly the sessions end up becoming a quiz situation. If that is all you want, there are many softwares which might do a better job at it.

With two folks in there, it can be really useful to have a good moderator as an interviewer. One would need to get both of them started in an argument or a discussion and observe how people react to individual points.

Knowing each of the candidates before hand can help a lot in moderation. Look up their details on the web and fit the right candidates together to get opposing views and opinions.

Conclusion:

In all, its a nice session to add to your interview plan. It’ll not only help you gauge the technical abilities but will also assure you of how the person would behave during the actual work. This coupled with initial research about the candidate can be a wonderful combination to add to your plan.

Have you ever conducted a ‘Two at a time interview’.. Please do share your learnings from the experience.

Sprint or Marathon.. What’s your model?

I’ve observed a basic difference when it comes to a sprinter and a marathon runner thats very relevant to a business ecosystem.

A sprint is a short distance run, fastest one wins. Speed is the most important attribute. Competition at its best.

When you observe a sprint, you’d typically see 10-12 athletes who’re running individually to beat the other one to the finish point. They don’t look at each other at all except after the end of the race. The key thing here is.. they don’t rely on each other much.

A marathon is however a longer run and tests your stamina, endurance and sustainable speed. It is competition, but of a different nature.

When you observe a marathon, you’d see groups running together for most of the distance. Its only at the end that people move away from the group. Running with each other helps athletes psychologically where they feel part of a group. They draw strength from each other in an implicit manner. They form a support system.

How is your business model structured?

If you’re running alone, is your business of sprint nature? if not.. see if being in right group can help you. Form a group of companies which offer similar services/products and benefit from each other without affecting the competing agreements. Share your knowledge to younger folks and encourage your fraternity to grow. It’ll only help you in the long run.

If you’re in sprinting business.. practice hard, run hard.