Sunday, December 17, 2006

Recursion vs. Loop

Problem

Imagine that your application is meant to process an XML file. It is given a tag and needs to find a "special tag" that this tag might be nested in. This problem has several solutions. I tackled a similar problem some time ago and I will present you with some of the solutions that I considered.

While loop

private SpecialTag findSpecialTag()
{
Tag parent = this.getParentTag();
while (parent != null && !(parent instanceof SpecialTag))
{
parent = parent.getParentTag();
}
return (SpecialTag) parent;
}

Do-while loop

private SpecialTag findSpecialTag()
{
Tag parent = this;
do
{
parent = parent.getParentTag();
}
while (parent != null && !(parent instanceof SpecialTag));
return (SpecialTag) parent;
}

Recursion

private SpecialTag findSpecialTag()
{
return findSpecialTag(this.getParentTag());
}

private SpecialTag findSpecialTag(Tag tag)
{
if (tag == null || tag instanceof SpecialTag)
{
return (SpecialTag) tag;
}
else
{
return findSpecialTag(tag.getParentTag());
}
}

Solution

In my personal opinion, I find the while loop cleanest and simplest to understand. Do-while loop gets a bit messy with the condition at the end and recursion is probably the worst. I find recursion a bit hard to follow. It can also introduce an extra method just for its own sake (as in this example).

I do not have a strong opinion on this topic. If you like to program recursions, while loops, do-while loops, or for loops, it's fine by me. I certainly will not change your code, but if you ask me to write some code, it'd most likely be a while (or for) loop.

I use while and for loops interchangeably. The previous example with while loop would look like this with for loop:

private SpecialTag findSpecialTag()
{
Tag p = this.getParentTag();
for(; p != null && !(p instanceof SpecialTag); p = p.getParentTag());
return (SpecialTag) parent;
}

What is your preference?

Big Screen

Martin Fowler in his recent blog post about big screen emphasizes the importance of the workspace size, as in the size of the screen. He says that you cannot see much on a small screen and must switch between windows that overlap each other. I totally agree with him.

I was lucky enough to work at companies that could afford spending a little extra for the benefit of increased productivity. At Siemens I had 21" monitor, which was the biggest you could get at that time. Then at 3D3.com, I had two 17" monitors, which was again an excellent choice (one screen for programming, second screen for running the app/testing).

Fast forward to present, I work at Atlassian and the choices are great. If you work fulltime you can choose between a huge 24" widescreen monitor or TWO 20" widescreen monitors. When I got my 24" monitor, the pair programming just got better.

I use a laptop at home and I used laptops for work at MSC and Agreon. I never had any problems with my eyesight. Except the time when I worked for Agreon and used a Dell laptop. My eyesight got worse and I had to wear glasses at the end of the day as my eyes were strained. Now at Atlassian, with 24" monitor in front of me, I don't need to use my glasses any more. My vision is just fine. (It must've been the screen of that Dell laptop, IBMs and Toshibas are fine) If you use a laptop, at least ask for a stand so you raise the screen to your eye height. A simple bookstand will do as long as it is strong enough. Anyway, laptops are no good for pair programming.

So a big screen is good as you can display more valuable information on the screen. However, one screen still does not save you from application switching. If you are lucky enough to have two screens, you know what I am talking about. It's just a pleasure not to be forced to switch between apps as you can easily have one on one screen and the other on the second screen. A typical scenario is coding and running the (web) application, or coding and reading documentation.

At Atlassian we take turns in support. A developer from each team takes a fortnight turn to join the support team. We usually move to support area (so we can be close to the members of support team). We have a dedicated "support desk", which has all hardware necessary. The only piece missing is the computer that the developer brings along. The monitor on support desk is a 24" widescreen monitor.

When people move to support they bring their own desktop computers. I drag my monitor as well. It's the same 24" monitor and I always think that it'd be a waste to let it sit unused on my "dev" desk for two weeks. I hook it up and voilá! Two 24" widescreen monitors give me the greatest work space I can get (for now). I gotta tell you, it's really fantastic to have these two screens. You can be digging in the code on one screen and doing something else on the other screen. I usually have a virtual machine running on one and a browser in the other. No switching, no overlapping windows.

If you want to see me in action with two 24" monitors, have a look at these videos about Atlassian and my bosses Scott and Mike [mp4] or [wmv] (around 1 min 40 sec).

Monday, December 11, 2006

Project Automation

I just finished reading Pragmatic Project Automation (How to Build, Deploy and Monitor Java Applications) written by Mike Clark.

This book is very well written and an easy read. I picked it from the shelf in our Atlassian library two months ago. I read it mostly in the mornings and evenings on the train commuting to the office. I must say that even my trips take only 20 minutes, in those 20 minutes I managed to read just enough to get me started thinking about software processes that we have in place and how to improve them.

There were many things in the book that I was quite familiar with. I have already used Ant, written unit tests, created scripts that build new releases. Although I was familiar with many of these aspects of project automation, there were new ideas, other angles of application of the automated processes I've never thought about. I was quite interested in reading the chapters dedicated to installation, deployment and monitoring. I have faced the dilemmas of these stages of software development and I was quite curious to find out how the author solved them.

This book is truly inspirational. In a sense it is a cook book for project automation. It's easy to follow and proves useful to a novice as well as experienced developer.

I will put this book back on the shelf in our office. It's worth sharing and I will highly recommend reading it to anybody who wants to automate almost anything in software development.

Wednesday, November 29, 2006

Don't hurt my files!

I have been using IntelliJ IDEA since I started working on JIRA at Atlassian. I finally upgraded to IDEA 6.0.2 last week. The first impressions are good.

I was re-arranging the dependencies of projects and libraries and needed to remove one. What made me feel really good was this pop-up:

I am so happy with IDEA's pacifist approach to my files. I am against the violence on the files!

Tuesday, November 28, 2006

What I did not know about favicon

Long time ago I learnt about that little file that can make your website special. I'm talking about favicon or favorites icon. This icon file is used when a page is bookmarked in IE5+ and Firefox.

I knew that this file had to be located in the root of the web server. And that was good enough for me at that time. Until today I did not know that the location of favicon.ico file did not have to be the root directory only.

Favicon can be associated with a webpage, not only a website. That means two things:

  • favicon placed in the root directory of the webserver is used with all web pages, no coding is necessary;
  • favicon can be placed anywhere on the webserver and must be referenced from the page in order to be used, favicon is then referred to as page icon.

All you need to do to customize the page icon is to put the following line into the header section of your page:

<link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon">

where the value in href points to the location of the favicon you want to associate with this page.

Few facts about favicon:

  • ICO file can contain multiple resolutions (the most commonly used being 16×16 and 32×32, with 64×64 and 128×128 sometimes used by Mac) and bit-depths (most common being 4, 8, 24 bpp—i.e. 16, 256 and 16 million colors) in the file;
  • image can be also any image format supported by web browser; e.g. GIF, PNG;
  • favicon.com is a website dedicated to favicon, it also includes an online editor.

So the good news is that literally every page on your website can have its own icon (which would be a nonsense, but makes a total sense for web applications running on the same server).

Monday, November 27, 2006

Animated CSS Evolution

I found this quite impressive animated GIF that show an evolution of a CSS for a website. The original post with animation was created by Dion Almaer.

Well done!

Sunday, October 22, 2006

70km and still kicking

Today I took part in Sydney Spring Cycle organized by Bicycle NSW. Sydney Spring Cycle is an annual event. It takes about 50km from start in North Sydney to finish at Sydney Olympic Park in Homebush.

It was my first SSC ride and it was a very pleasant ride indeed. My friends and I aimed for an early start at 7am. This meant I had to get up at 5am to get ready an be in North Sydney on time. The weather was cold and it rained a bit. We warmed up quite quickly though.

Later during the day the sky cleared and it was a beautiful day to ride. I really enjoyed a company of thousands other rides. I rode my old mountain bike and my friends were on road bikes. To my surprise I managed quite well. I was able to keep up with them (I think they just spared me).

50km seemed like a lot. I usually ride 10km to work in Sydney CBD, which takes me half an hour. When we reached the 40km milestone, there was a sign "10km to go." By that time it seemed like nothing.

In fact, we had enough energy for a short sprint to the finish line. It was a great day out. I felt so energized that I also rode home from Homebush, adding few extra kilometers to the count.

At the end I did 70km. Here is the proof.

Sydney Spring Cycle 2006

I created a Sydney Spring Cycle bicycle path on Bikely, if you are interested and would like to see it on Google map. The photos I took today can be found at Flickr.

Thank you all who organized such a great event! I'll be there next year too!

Thursday, October 05, 2006

Microformats - hCard

What is new on my blog today? I added my contact information into the template. Since I learnt more about microformats at the Web Directions conference, I used hCard microformat. No, you cannot see it as the style on that DIV is set to display: none and that means it's there but not visible.

If you have Tails or Tails Export extensions for Firefox or Flock browsers, you should be able to see these normally grey icons get some colors .

When you click on Tails you get

When you click on Tails Export you get

All I added was this:


<div class="vcard" style="display: none;">
 <a class="url fn" href="http://hanuska.blogspot.com/">Dushan Hanuska</a>
 <div class="adr">
  <span class="locality">Sydney</span>
  <span class="region">NSW</span>
  <span class="postal-code">2000</span>
  <span class="country-name">Australia</span>
 </div>
 <span class="geo">
  <span class="latitude">-33.879176</span>,
  <span class="longitude">151.212044</span>
 </span>
</div>

If you want to add your hCard onto your page, you can create one using hCard Creator. It's quite simple and gives only the basic options, but it's a good place to start.

Monday, October 02, 2006

Cool Links from Web Directions South 2006

If you have any other cool link related to cool web sites, post them in your comment to this blog post.

Designing for lifestyle

Getting inside the minds of customers is essential for achieving the "aha" effect. More importantly, don't listen to what your customers say! Observe what they do!

When there are people and machines we get four different types of communication:

  • human to human: touch, words, voice;
  • human to machine: input devices, touch (mouse, keyboard);
  • machine to machine: binary communication, exchange of XML documents;
  • machine to human: GUI communication.

When it comes to machine to human communication, is it important that we pay attention? There could be messages such as an engine light turns on in the car. It is our role, the role of software developers, to make these messages user-friendly. Otherwise the messages will be ignored or overlooked.

We have seen that AJAX can fail in keeping the user informed - the message does not make it through. It could be a case when a user votes on something, the request is made but the page does not get reloaded, so we need to highlight the fact that the vote was processed. The question is how to do it so the user sees it without affecting other "more important" things that the user is currently doing on the (same) page.

There has been a lot of work done in improving the user experience. Starting from Eliza chat bot and the subservient chicken in 2004 to today's websites that are very user-friendly: JetBlue, TiVo, Google, Apple.

It is all about designing an appropriate user experience. It's also about finding the fine line between practical and emotional (are you emotionally attached to this, do you find this useful, etc.)

Practical

  • learnable
  • cost effective
  • functional
  • meets the needs
  • trustworthy

Emotional

  • customizable
  • unique
  • aesthetic
  • meets desires
  • compelling

The real deal is that one you are able to break into people's habits and make them to use your application as a part of their daily rituals (not really an addiction), you will be successful.

Some of the interesting statistics mentioned were how the usage of mobile phones changed people's rituals and how these technologies saturated the market (Japan 90%, Korea 83%, Europe 68%, US 48%, world-wide 28%). I can see a great potential for growth here in Australia too. And there are some serious money too. In the US, 12-18 year-old kids spend around $4900 a year, which 48% of that is on mobiles (in China it is less than $100 a year). It was also interesting how people use their phones/devices. In US they are called cell phones (amongst popular ones are Palm and Blackberry). In EU and Australia they are called mobile phones and other brands and models are more popular (Nokia, Ericsson). In Singapore however, people may even have two of them. One that is more of a fashion statement and may not even look like a phone.

There is also a gap between what people think and how people live. As an example, you think that all people would wash their hands after using the toilet, but not all people do. We know that we develop applications and we can think of the ways people will use them. But people are very creative and they use our applications even in unimaginable ways. It's about going through the stages:

"I'm ready to try this out" -> PERCEPTION -> INTERACTION -> INTEGRATION -> "This works for me!"

And what is next? Web 3.0. Global brain = something like a combination of shared data and a search engine aggregating the knowledge spread all over the web.

You-biquity

From my notes on Mark Pesce's presentation on You-biquity at Web Directions conference.

Virtual reality isn’t the television of the future, it is the telephone of the future.

Part 1: Human Essence

Right now anything is possible. Humans and chimpanzees are at least 98% identical. We have now found the gene that gives us a bigger brain than our chimpanzee cousins. Both chimps and humans are incredibly social creatures. These social qualities we have as humans are essential to our lives. We build our relationships, we build social hierarchies, we are very social. Social modeling happens in the neocortex of the brain, of which we have more than any other animal. The Dunbar Number: the number of people you can hold in your head is directly relative to the size of neocortex. The reason we have a bigger brain than chimpanzees is to hold a bigger social network in our heads and that is what being human is all about.

Part 2: Virtual Networks

Social network needs to be fed fresh data, otherwise it dies. We need to spend time to feed them the data and the time is the non-renewable resource in the 21st century. My social network could be used as my spam filter – if an e-mail is not from a third-degree contact then it's highly suspicious. Wouldn't that be cool! E-mail forwarding is an ad-hoc social network. We find things, we filter them and then we forward them – three F's. For every moment we spend on-line we create a massive amount of data – a data shadow. This data tells a lot about us but at the moment all of then is wasted, not used at all. The mashups are in the right directions, but we need more to use our data to the maximum. The Web is the universal glue.

Part 3: The Center of the World

People form a strong relationships with their mobile phones. The phone has become seamlessly integrated into our lives. And the relationship is very emotional. We say we don't have an emotional relationship with our phone but we all lie. Just drop your phone down to the toilet or on the floor and see what happens. I lost my social life! The phone ultimately meets the physical and virtual worlds. For most of the time the phone does nothing. It just waits. What a waste! Imagine if we could use it as a device that listens actively and automatically connects us with the friends that are near.

The street finds it’s own use for things, uses its makers never intended.

Web APIs

Web APIs are sexier that desktop APIs. Having an API allows the external developers to access your data or your services in a smart way. They can they use your data or services in ways you would not imagine.

Currently it is very popular to use the data with mapping APIs. At the moment the Google Maps have the best and most detailed images of Australia. Microsoft competes with Virtual Earth, they have good images, good maps, but a very restrictive licensing. Yahoo! Maps has also good images and also gives a choice of Flash or JavaScript. They also provide an option of a static image. The downside of Yahoo! Maps is the lack of mapping information.

Another popular category of APIs is Search. Search APIs can provide cache access, spell-checking, content analysis and much more. Amazon's API offers search on prices, images, customer reviews and affiliate sales.

A good resource for Web APIs is ProgrammableWeb, which acts as an encyclopedia of available APIs and how people use them.

Mashups are novel UI that enhance your data, e. g. by combining your local data with mapping information. Chicagocrime.org – one of the first map mashups was built prior to Google’s API being made public. It’s not all about maps – TagTV, Viral Video Chart, BlueOrganizer, Salesforce Adwords.

There are two general types of APIs: interfaces (maps) and data types (the rest). For example Google Maps are very simple to include; just drop in the script, add four lines of JavaScript and you are done. The other APIs are simply a request to a web resource via HTTP. XML is often used to return the result, though JSON is becoming more popular. These can also be called directly from JavaScript using the XMLHttpRequest object.

The current limitations several. You are limited to the functionality that the provider makes available, unless you screen scrape. There are also concerns with automated collection of personal data, licenses and the changes in terms of use (what will you do if Google Maps is no longer available). We also need to standardize. There are some APIs available that abstract the mapping API access and allow you to switch between Google Maps, Yahoo Maps, etc. Cross domain AJAX is also a security risk. Images, CSS and JavaScript can be loaded from other damains, but HTML or XML can not. A workaround could a proxy server, but this could be a bottleneck if not cached. JSON-P is another alternative, currently supports GET requests, but fails silently if you get the API URL wrong.

In the future we can see ContextAgnosticXmlHttpRequest, enhanced JSON – JSONRequest. Web APIs are all about work we do not have to do. So open your data, offer an API, let the others do the work!

Hijax

How can we make feature-rich web site and also offer the way so people with disabilities can access it?

The old way it to produce two version of the website, e. g. Flesh version and HTML only versions. The big drawback of this approach is that the user is presented with the choices first and only then the user enters the website with content. Or some sort of client-side script is run in order to determine the capabilities of the browser. There is no way easy way check the user this way (e. g. the user is blind). Therefore we have a behavior that can be switched ON or OFF.

A better way is progressive enhancement. Initially we have content that we want to publish or present. Then we have the markup – (X)HTML. We add the presentation layer – CSS. At last we add the behavior on top – DOM Scripting.

We still have to answer whether we have some of the functionality in-line or external (*.css and *.js files).

The HIJAX way is :

  • Begin by creating a website using traditional page refreshes,
  • Data is sent to the server via links and form submissions: the server returns updated pages,
  • Intercept (hijack) those links and forms using (unobtrusive) JavaScript,
  • Send that data to XMLHttpRequest instead of the server,
  • The server returns just the information that's required instead of an entire page,

We have a choice of data format:

  • XML + DOM methods
  • JSON + eval()
  • HTML + innerHTML

Another important thing is that the browser is an unpredictable environment. The user can be running on any OS with any type of web browser. The only thing that we know is what is on our server. Therefore all business logic should be kept on the server side. For example a table sorting can be done on the client-side by JavaScript. This would off-load the server, but we would have to face the challenges with the differences between JavaScript support on various browsers. On top of that we would have no feedback about the usage of table sorting. If this logic was on the server, we could collect the data about table sorting and improve the website accordingly.

The main benefits of using Hijax approach are that we do not need to spend time building a non-Ajax version. Our web application will be still accessible in the usual way. We do not duplicate the logic (client-side and server-side validation) and the links are spiderable and potentially bookmarkable.

HIJAX is a term coined by. I learnt about Hijax at the Web Directions conference. Jeremy Keith presented Proressive Enhancement with Hijax. He is an author of DOM Scripting: Web Design with JavaScript and the Document Object Model and currently working on his next book Bulletproof Ajax.

Microformats

In these days we turn for the answers to our questions to the Internet. Sometimes we even refer to it as the wisdom of the crowd.

Take IMDB for example. It is a centralized solution. When it comes to the reviews they are written by the people. But who owns these reviews? Are they real? Can we trust them? Google is the answer to all our prayers. Or as a big sign in front of one church said “Google does not have the answers to all questions.”

We saw the raise of open source. Then we also had a raise of open standards for document formats. They are getting more popular and also more important. The next step will be the open data. Standardizing the data format will also allow for more mashups. Very popular type of mashup these days is the combination of maps and some other proprietary data. If two people publish the data in two different formats, none of them can make use of the other.

Web has evolved. The move is from HTML to XHTML. The benefits are such as that microformats are simple data formats, HTML based, based on existing standards and existing development practices. To mention a few, there is hCard (based on vCard), hCalendar (based on iCal), hReview, hListing- for classfields, hResume and many more.

I also discovered that there are some Firefox extensions that discover microformats on the page and allow the user to see them. One that is worth mentioning is Tails.

Where to do from here? We all publish data on the web. More microformatted data we publish more options of their usage will be present.

More information about microformats can be found at microformats.org, microformatique.com. Read about how to highlight microformats with CSS. New book on microformats by John Allsopp will be coming out in early 2007.

Web Accessibility

I attended the Web Directions conference last week. One of the eye-opening sessions (at least for me) was “Accessibility 2.0” and “Designing for Accessibility: More simple techniques that make a difference” by Derek Featherstone from FurtherAhead.

Accessibility is about allowing disabled people to use our website. I have never worked on a project that would require access by people with disabilities. I think it really takes a real life experience to realize what these people must go through in their everyday lives. Why should we make it more difficult for them with our web applications? Do you know how many web applications stop working when you switch JavaScript off? You would be surprised to see how big number that is.

There are some guidelines that we can follow in order to make our websites more accessible. If we remove frames, replace menu images with menu using text and CSS, don't use tables for formatting, we make a big step towards accessibility of our websites. Another thing is having PDF documents on the website. PDFs are not accessible and they also need to be downloaded in order to read them and find out that it's not the document that we wanted. Another place for improvement are the web forms. Fields should have labels.

The phrase “people with disabilities don't go to our website” is just a nonsense. They do and they can also bring some revenue. Take for example Tesco Access. Grocery shopping on the web is an ideal service for visually-impaired customers. Imagine trying to tell a can of beans from a can of tomatoes on the shelf if you can't see the labels. Then think about having the description read to you by your computer. Their website was designed for accessibility and because of this feature it boosted revenue by another 4%.

Accessibility is personal. Removing barriers, user testing is personal.

Where do I go from here? Well, I will start at the roots – W3C Web Accessibility Initiative and Section 508. Then I will read Dive into Accessibility book that according to its website answers two questions “Why should I make my web site more accessible?” and “How can I make my web site more accessible?” Australia with its Disability Discrimination Act is six years ahead of USA.

I also found The Illinois Center for Instructional Technology Accessibility very informative. They list the best practices, have software for download (Accessibility Extensions for Mozilla/Firefox lives here) and lots more. Another great resource for developers is Evaluating Web Sites for Accessibility with Firefox by Patrick H. Lauke.

Some of these guidelines are very much a checklist approach. User experience is more important. Therefore we need to sit down with the real user, the one that will be using the system, and work together in order to fulfill the user's needs and expectations of this system.

Jeremy Keith presenting in Melbourne

WSG and Web Directions are hosting a presentation by Jeremy Keith.

When:
Thursday 05 October 2006 at 6:30pm

Where:
Centre for Innovation & Technology Commercialisation
Level 1, 257 Collins Street
Melbourne VIC 3000

Quotes that made me laugh today

A funny quote that came out of Web Directions conference.

The web isn’t a power drill! - Andy Clarke
It’s a series of tubes! - John Allsopp

Friday, September 29, 2006

How we built Flickr workshop and Web Directions North conference

I just came home after a two-day Web Directions South 2006 conference. This conference was a huge success. I will blog about it more later. What is next? Well, there is going to be a Web Directions North conference in Vancouver in 6-10 February next year. And if you look at the schedule, there is some skiing and boarding planned as well... just get your boss to pay for it :-)

This is a link to the upcoming one-day workshop presented by Cal Henderson on Building Enterprise Web Apps on a Budget - How We Built Flickr organized by webworkshops.

It is scheduled as following:
Brisbane 13 November 2006
Sydney 14 November 2006
Canberra 16 November 2006
Melbourne 17 November 2006

Hope to see you there!

Have you Googled Yourself?

As John DellaContrada an UB Internet-Culture Expert says in his "Self-Googling" Isn't Just Vanity; It's a Shrewd Form of Personal "Brand Management"

"Self-Googling" -- searching for your own name on the popular Google search engine -- may seem like an innocuous act of vanity, but a University at Buffalo communications professor recommends it as a shrewd form of "personal brand management" in the digital age.

I don't do this much, but how can I resist? I write this blog and few other things in other places so I wondered what people find when they search my name. So I googled my surname... I got 7 out of 10 results on the first page.

And as John DellaContrada consludes

"Starting your own Weblog or Web site can help you to shape your public image, and make sure that it accurately reflects your abilities and interests."

So what are you waiting for? Go out there and start writing!

Thursday, September 28, 2006

Good Design in Practice

I attended the first day of the Web Directions South 2006 conference today. Some of the topics that were covered today were about the design of the web sites and web pages or the design in general. Since I read The Design of Everyday Things by Donal A. Norman (which I mentioned in one of my previous posts about Good Desing) I tend to look at things in a different way. And I also appreciate the good design of the things we use. A thing can have all it needs but if not designed well it will fail as it will be unusable (see the cover of the book and you'll get the idea at least – or read the whole book).

There was one of the things that I use in my everyday life, but only today I realized how brilliantly it was designed. Derek Featherstone has apparently same eye as me as he showed us the photo that he took the day before. It was a photo of

The pedestrian crossing button

How perfect it is! Not only you can see the big white arrow but if your eyesight is impaired you can touch and feel the smaller raised arrow. And that is not all! If you cannot see it, you can hear it ticking when the green light is on. And that still is not all! If you cannot see nor hear, you can still feel it. The button VIBRATES!!! Derek said it at the conference and was all excited about it. I did not believe. I had to touch it on my way home from the conference. It is true! It does vibrate!

How cool is that?! That is a successful design in practice. Way to go designers!

What is next? Well, as a software developer I will focus a bit more on designing the web applications in a way that all people can access them, even if they have some disabilities. Sometimes we go and design things that are cool, but not usable by all of us...

Wednesday, September 27, 2006

First element in the List

Imagine this scenario. You are working on an existing application. There is a framework used. One of the benefits that this framework gives you is retrieving and processing parameters coming from the client, let's say a web application. The framework gives you all parameters as a List. Now in this particular case you always get only one parameter, but is it enclosed in the List. How do you get it out efficiently?

The intended method would be described: Get the list of parameters and if not empty, return first element in the list otherwise return null. The code was looked similar to this:

1 public E getSingleParam(List params) {
2 E param = null;
3 if (params != null && params.size() >= 1) {
4 param = params.iterator().next();
5 }
6 }

This code works fine but it has several points for improvement. First is how the code at line 3 expresses the intention of check whether the list of parameters is not null and not empty, specifically the later. List interface defines boolean isEmpty() method that is in most cases more efficient to run than getting the size and comparing it to 0 (greater than) or 1 (grater than or equal). That is if the list implements an internal flag for its "emptiness" state or has an internal counter as opposed to re-counting its elements. In the worst case scenario the efficiency will be the same as getting the size and comparing it with 0. In that case isEmpty() method is still a nice convenience method to call and should be preferred before the size() > 0 alternative. Another reason is that it speaks for itself. All we need to know is whether there are any elements in the list or not. Getting the size should be used to for other purposes (e.g. calculating the width of the table column when displaying the results in a tabular form – 100% / size()).

1 public E getSingleParam(List params) {
2 E param = null;
3 if (params != null && !params.isEmpty()) {
4 param = params.iterator().next();
5 }
6 }

The second point of making the code to perform better and to make it easier to read is the line 4. On this line we are getting the first element of the list. As shown in the example above, this is an inefficient way as we construct an Iterator only for the purpose of one iteration. Constructing new objects and disposing of them is usually expensive and should be avoided. A better way is to access the element directly, such as:

1 public E getSingleParam(List params) {
2 E param = null;
3 if (params != null && !params.isEmpty()) {
4 param = params.get(0);
5 }
6 }

This way no new objects are constructed (no Iterator). Another difference between the two is the exception that could be possibly thrown. The exception would be thrown if we did not have the previous check or in the case of concurrent modification of the list which is very unlikely in this case. The exception thrown in first case would be a NoSuchElementException. In the second way, an IndexOutOfBoundsException would be thrown. Both of them are runtime exceptions and do not have to be declared. In this case getting one exception or the other should not make any difference.

Tuesday, August 22, 2006

Tricky instanceof operator

Let's start with a little puzzle.

Object obj = ...
System.out.println(obj instanceof Object);

How do you initialize the obj in order to print "false"?

Well, aren't all possible Java objects instances of Object? To answer this question one must understand how instanceof operator works. The answer is that it would print "true" for any Object. The only way to make it false is not to give it an object, give it a null reference.

The tricky bit about instanceof operator can be that if object on the left side is null, the condition evaluates to false. Therefore there is no need for null check after a class cast as in the following example.

public boolean equals(Object o) {
if (o instanceof MyClass) {
MyClass mc = (MyClass) o;
if (mc == null) // never null
return false;
else
return ... // compare members of mc
}
return false;
}

This can be simplified as shown in the following code snippet

public boolean equals(Object o) {
if (o instanceof MyClass) {
MyClass mc = (MyClass) o;
return ... // compare members of mc
}
return false;
}

So the moral if this excercise is that instanceof operator works as you would expect with objects, and returns false when given a null.

And remember that equals() method is probably the only reasonable place for instanceof operator. If you do it elsewhere and use it to create an alternative flow (e.g. if-else, switch) it is a bad smell and should be replaced with polymorphism. Read more about Swich Statement code smell and Polymorphism

BTW the previous example was not a very nice example of how to implement equals method, so do not copy it ;-) Usually we would do something like this

public boolean equals(Object o) {
if (o == null) return false;
if (o == this) return true;
if (!(o instanceof MyClass)) return false;
MyClass mc = (MyClass) o;
return ... // compare members of mc
}

Saturday, August 19, 2006

Swich Statement code smell and Polymorphism

One of the symptoms of object-oriented programming is the lack of switch or case statements. Imagine that we have some client class that calculates the area and perimeter of particular geometrical shapes.

public class Client {
private double a;
private double b;
private double r;
...
public double calculateArea(int shape) {
double area = 0;
switch(shape) {
case SQUARE:
area = a * a;
break;
case RECTANGLE:
area = a * b;
break;
case CIRCLE:
area = Math.PI * r * r;
break;
}
return area;
}

public double calculatePerimeter(int shape) {
double perimeter = 0;
switch(shape) {
case SQUARE:
perimeter = 4 * a;
break;
case RECTANGLE:
perimeter = 2 * (a + b);
break;
case CIRCLE:
perimeter = 2 * Math.PI * r;
break;
}
return perimeter;
}
...
}

The previous code is clearly a poor design that limits the current client to only work with three types of shapes. The problem with switch statements is the duplication and that is a code smell. There are usually several places in the code where the behaviour slightly deviates and these switch statements are present (e.g. in calculateArea and calculatePerimeter methods). Even worse case is if we work with objects where the switch is replaced by multiple instanceof conditions.


public class Client {
...
public double calculateArea(Object shape) {
double area = 0;
if (shape instanceof Square) {
Square square = (Square) shape;
area = square.getA() * square.getA();
}
else if (shape instanceof Rectangle) {
Rectangle rectangle = (Rectangle) shape;
area = rectangle.getA() * rectangle.getB();
}
else if (shape instanceof Circle) {
Circle circle = (Circle) shape;
area = Math.PI * cirle.getR() * cirle.getR();
}
return area;
}

public double calculatePerimeter(Object shape) {
double perimeter = 0;
if (shape instanceof Square) {
Square square = (Square) shape;
perimeter = 4 * square.getA();
}
else if (shape instanceof Rectangle) {
Rectangle rectangle = (Rectangle) shape;
perimeter = 2 * (rectangle.getA() + rectangle.getB());
}
else if (shape instanceof Circle) {
Circle circle = (Circle) shape;
perimeter = 2 * Math.PI * cirle.getR();
}
return perimeter;
}
}

To improve the desing we make Square, Rectangle and Circle have a commont root. By that I mean that they either extend the same class, such as AbstractShape or that they implement a common interface, such as Shape or ideally both.

Then we can eliminate the switch statement code smell very easily. We replace it with polymorphism.

Shape.java file
public interface Shape {
public double getArea();
public double getPerimeter();
}

Square.java file
public class Square implements Shape {
private double a;
...
public double getArea() {
return a * a;
}
public double getPerimeter() {
return 4 * a;
}
}

Rectangle.java file
public class Rectangle implements Shape {
private double a;
private double b;
...
public double getArea() {
return a * b;
}
public double getPerimeter() {
return 2 * (a + b);
}
}

Circle.java file
public class Circle implements Shape {
private double r;
...
public double getArea() {
return Math.PI * r * r;
}
public double getPerimeter() {
return 2 * Math.PI * r;
}
}

And such refactoring simplifies the Client code. It also allows for easy extensibility by implementations of other shapes without changing a single line of Client code.

public class Client {
private Shape shape;
...
public double calculateArea() {
return shape.getArea();
}
public double calculatePerimeter() {
return shape.getPerimeter();
}
}

Another way of looking at it is from the responsibility point of view. Why should the client be responsible for calculating the area or the perimeter; or have a knowledge about shape's internals (e.g. number of sides, radius, etc.) It is the responsibility of each shape and all that the client needs to know is that a shape has a perimeter and area.

To sum this all up:

Wednesday, August 16, 2006

Programmable Web and GoogleMaps Fligh Simulator

Today I came across an iteresting website: ProgrammableWeb - because the world's is your programmable oyster. In their words:

ProgrammableWeb is where you can keep-up with the latest mashups, what's new and interesting with Web 2.0 APIs, and the Web as Platform in general. The core of the site is the blog and the 3 dashboards: Home, Mashups and APIs. All dashboards are updated daily.

It's worthwhile having a look at API part. And this is how I found

Quite nice app, good fun exploring the world without being scared of terrorism! And as you can see I had a few successful flights over the Sydney Opera House. But be careful! Do not fly too low, you can crash!

Sunday, August 13, 2006

Improved Map Iteration

When some one new to Java comes to play, first thing they do, they re-invent the wheel. Such wheel can be a class that is already implemented in java.util package. Yes! Collections and Maps! Later, as you become a senior Java developer you alredy know the narrow places in the "Utils" valley. And yet we can make mistakes.

Such mistake can be the following implementation of the method that calculates the size of the collection.

private Collection myStuff = ...

public int calculateSize() {
int count = 0;
for (Iterator it = myStuff.iterator(); it.hasNext(); it.next()) {
count++;
}
return count;
}

This can be easily fixed by

public int calculateSize() {
return myStuff.size();
}

Another, more frequent example of bad performance is a condition where one wants to know if there are any objects in the collection, but does not really care how many there are.

if (myStuff.size() == 0) {
// do something
}

Remember size() method may possibly calculate the size and therefore generally is slower than a call to isEmpty() method. Therefore the fix is obvious.

if (myStuff.isEmpty()) {
// do something
}

Could you imagine that I once worked for a company where the senior developers did not know about Iterators? So instead of

for (Iterator it = myStuff.iterator(); it.hasNext();) {
Object item = it.next();
// do something with the item
}

they had

for (int i = 0; i < myStuff.size(); i++) {
Object item = myStuff.get(i);
// do something with the item
}

and on top of that myStuff was a Vector, which is synchronized. Very sloooow code!

Nevertheless my point is: Know your collections!

Now back to the topic of improving the Map iteration. Well, it really depends what we need to do at each step of our iteration.

If you need to iterate over the keys of the Map do this

for (Iterator it = myMap.keySet().iterator(); it.hasNext();) {
Object key = it.next();
// do something with the key
}

And if you need to iterate over the values of the Map do this

for (Iterator it = myMap.values().iterator(); it.hasNext();) {
Object value = it.next();
// do something with the value
}

But what if we need both the key and the value? The usual approach and very bad approach is to get the set of keys, iterate over them and get the value for each key.

for (Iterator it = myMap.keySet().iterator(); it.hasNext();) {
Object key = it.next();
Object value = myMap.get(key);
// do something with the key and the value
}

What is wrong about this? Nothing! You can do it this way and it's perfectly fine. It is just very inefficient as at each iteration a map needs to look up the value for a given key. It is better to iterate over map entries. There is a special interface Map.Entry that can be used to retrieve the key and the value of each entry in the map. So the previous example can be transformed into

for (Iterator it = myMap.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
Object value = entry.getValue();
// do something with the key and the value
}

Don't forget to change myMap.get(key) to entry.getValue(), otherwise you are not gaining anything from this modification. I did this recently, I omitted to change it, even worse - I changed it to myMap.get(entry.getValue()). As a result the map was not finding anything... Luckily, we had tests around the class I modified and my stupid mistake was caught early.

Have the tests ready before making changes! Even experienced people make mistakes.

Server Polling - Reverse AJAX

I am starting to feel a bit old or old-school. I know the concepts of AJAX but never had enough time (or project) to get my hands dirty doing AJAX. So I decided to make time and learn AJAX by doing.

I joined the 10-Week Free AJAX Programming (with Passion!) online course organized by Sang Shin from Sun Microsystems. This course is in its second week now and the homework was:

"... to write one or two paragraphs describing an "interesting" AJAX related technology/feature you find while you are playing with the online demos or while reading AJAX articles on the net"

I though that it would be good to share my point of view with you. So, here I go.

Title: Server Polling - Reverse Ajax)
URL: http://ajaxian.com/archives/reverse-ajax-with-dwr

Keeping the displayed information up-to-date was always difficult in web world. Before AJAX, one had to use JavaScript or META Refresh tag to get the page refreshed. This was quite annoying from the user experience point of view. However it was not as annoying as something that I experienced few days ago on one of the banks website (a bank in Australia). I was filling out the form and there were couple of select boxes on the page. I selected an option in the select box and moved onto next field just to realize that as I was typing, the page has been reloaded and all data entered past that select-box was gone and had to be re-typed again. Very, very annoying - and it's AJAX age already!

Server polling, in my humble opinion, is a great feature of AJAX. There is no need to refresh the whole page to obtain the required information. With AJAX, it is possible to:

  • update the forms with information as the user moves through the form (e.g. country - state - city)
  • get the feedback about a long server-side or transport process (e.g. progress bar showing the percentage of the uploading file)
  • fake the push of the updated data from the server (think stock prices, weather, traffic info)

I am sure that I will come across more coolness when I start writing more and more Ajax code!

Thursday, August 10, 2006

Empty String

How many times have you coded a check for String being null or empty? Countless times, right? I have. We use some ready-to-use classes from open source frameworks or we write our own StringUtils class. More or less they all implement the same thing and it always looks similar to the following code snippet:

String s = ...
if (s == null || s.equals(""))...

or similar to the following, which trims leading and ending whitespaces

String s = ...
if (s == null || s.trim().equals(""))...

Of course you could also do this:

"".equals(s)

which is a case when you do not care if String s is null and you don't have to worry about NPE as if won't happen ("" is never null, whereas s could be). But that's another story.

I have had "extra" warnings turned on in my IDE for couple of days. But today my IDE suprised me when it highlighted

[1] s.equals("")

and suggested that I could optimize it by making it to

[2] s.length() == 0

And guess what?! The IDE was right! I looked at the suggested code briefly, gave it a bit of thought and agreed that it would probably be faster. Method [1] creates a new instance of the String (an empty String, yes I know that all instances of "" would be caught during compilation and optimized and that they all would refer to the same instance). Just to be on the safe side I looked at the source of the String class.

And here is what I found. The length() method returns and integer primitive, which is not calculated with each method call to length(). It is rather a member variable (or constant, as Strings are invariants) of String class that is calculated when new String instance is created. So this method would be super fast.

536   public int length()
537 {
538 return count;
539 }

On the other side, there is the equals() method, which is fast as well, but not as fast as length method. It has to do a check for class, class casting and comparison of count members (that's what length method returns).

684   public boolean equals(Object anObject)
685 {
686 if (! (anObject instanceof String))
687 return false;
688 String str2 = (String) anObject;
689 if (count != str2.count)
690 return false;
691 if (value == str2.value && offset == str2.offset)
692 return true;
693 int i = count;
694 int x = offset;
695 int y = str2.offset;
696 while (--i >= 0)
697 if (value[x++] != str2.value[y++])
698 return false;
699 return true;
700 }

And remember the few important points when it comes to Strings:

  • Do not compare Strings with == operator. Unless you want to compare the object references. Use equals() method.

  • Do not construct new instances like new String("abc"). Simple "abc" will do, unless you really mean that you need a new instance of String with same value. Read more about How useful is String(String) constructor

  • Do not concatenate Strings in loops using + operator. It's faster to use StringBuffer (or StringBuilder, which is in Tiger and is not synchronized) append() and then toString() methods instead. The plus (+) operator constructs new String object each time.

Saturday, August 05, 2006

Comments in Java Code

We all use comments to describe the Java code. There are three types if comments in Java as demonstrated in this Java tutorial by SUN:

// text

where the compiler ignores everything from // to the end of the line

/* text */

where the compiler ignores everything from /* to */ and

/** documentation */

which is ignored by the compiler the same way as the previous comment type. This one is a special comment as this indicates a documentation comment. The JDK javadoc tool uses doc comments when preparing automatically generated documentation.

I am not going to tell you how to use them. There are many articles and documentation written about that. We all know how to use them and most of us use them on a daily basis. Over time we can develop a stereotype. Mine looks like this:


/** first name */
private String firstName;

/** last name */
private String lastName;

/**
* Constructs and returns the full name
* @return full name
*/

public String getFullName() {
if (firstName == null) {
if (lastName == null) {
// user does not have a name specified
return "[no name]";
}
else {
return lastName;
}
}
else {
if (lastName == null) {
return firstName;
}
else {
// construct full name from first and last name
return firstName + " " + lastName;
}
}
}

As you can see, I use doc comments to describe the meaning and function of my class members. I also like to use line comments, rather than block comments. Even if my comment spans multiple lines I prefer to use // comments. It's due to my IDE settings. When I press Ctrl+/ it un-/comments the selected lines. It's very neat feature and I use it a lot.

Recently, I was doing some code modifications and I wanted to re-visit some code later. I decide to break the code by putting a comment in the middle if it, so it would not compile and I would be forced to come back to it.

I did somethig like this:


myObject.getAnother()/* change to ID */.getName();

To my surprise the code did not break. Even when I changed it to


myObject.getAnother()./* change to ID */getName();

Obviously, when I did this


myObject.getAnother().ge/* change to ID */tName();

the code broke. At the end I made it to break in a nice way, anyway


myObject.getAnother()./* change to ID */.getName();

(notice an extra dot)

All this made me thinking. Where are all the valid spots for the comments. After I read the definition for Java comments I understood why it worked, but I simply find it puzzling. Of course, we do not put comments in places like this, but the language allows us to.

I am not sure if there is any value in this lesson learnt. It would certainly make a good exam question though. I can see it now: "Will the following code compile?" ...

Saturday, July 22, 2006

Debug This!

Whilst in Korea, my cousin Ladislav Babinec took this shot. Both, he and I have a bit of electrical engineering background (he works for a T-Com originally Slovak Telecom). So we were amazed how an electrician would go about fixing this mess. Or maybe they hire only the elecricians with special puzzle solving skills. After this photo had been taken I noticed similar electric poles in many places throughout Seoul. Simply amazing! I wonder what tools do those electricians use for debugging.

Good Design

I am back from the wonderful trip to South Korea, where my wife comes from. We spent some time sightseeing Seoul and some time meeting with Miae's relatives. I am already looking forward the next time we visit Korea and will travel around the country.

Before one of the meetings we had, I had to go to a restroom. It was in a very luxurious 5-star hotel. As I was sitting there and doing my business I noticed a little white box mounted on the wall. This little device had a display and many buttons. As I can read Korean script (Hangul), but have no idea what I read, I had absolutely no clue what this magic white-box is for. Naturally, I knew there was a connection with the human waste disposal unit I was sitting on.

What was even worse was the fact the the most common button - FLUSH - was nowhere to be found. I checked the usual spots around the toilet, but I found absolutely nothing. So I decided (as a citizen of a developed country and an educated man) that I have to have a crack on this thing and must be able to flush using basic logic and common sense.

Koreans are probably laughing at me right now, but I failed miserably. I pressed few this-must-work buttons, but could not make that damn thing to flush. So I left with shame, leaving a surprise present for the lucky person who would come after me. Luckily, no one was waiting so I got away with it without too much embarrassment.

This whole story reminds me of an excellent book I read long time ago. The design of Everyday Things by Donald A. Norman talks about the good and bad design of things we use everyday. He says that if things are designed well, no manuals, no labels, no description text is necessary. You simply grab the thing and use it in a right way. How many times you tried to push the door that was meant to be pulled just because the door handle was easier to grab and push? How many times you pushed the wrong light switch because the switches were not in logical order?

Well, I don't know if it was me this time or a bad design. Why do we need so many buttons for the toilet anyway?

Tuesday, July 11, 2006

Korean Coca-Cola Zero

My "coffee" - I am happy that I can find what I need on my trip in Korea :-)

Kkokka-Kkolla Jero


What am I up to these days?

You may have been wondering why I am not blogging as frequently as I did before. Well, I am on vacation in Seoul, South Korea.

As it usually happens there are more things to see than there is time. And since July is the month with the highest rainfall, I feel lucky to enjoy so many days with very little rain so far.

The following are:

  1. Bell at the entrance to Bongwonsa - the largest of the temples, next to Inwangsan - Seoul's most famous shamanist shrine,

  2. Resting pavilon in the Korean Folk Village,

  3. Hyowon Bell at the Hwaseong (Suwon Fortress) - UNESCO World Cultural Heritage,

  4. Gyengbokgung - Palace of Shining Hapiness, the Primary Palace of Joseon Dynasty,

  5. Geunjeongjeon - the greatest building at Gyengbokgung where ceremonies of the state took place.






Tuesday, July 04, 2006

Southpark - how would you look like if you were there?

This is Miae and me in Southpark - well, the way we see ourselves.

This image was generated using the Planearium and paintbrush.

Tuesday, June 27, 2006

Pair Programming Habits

I finished reading Pair Programming Illuminated, a book written by Laurie Williams and Robert Kessler. I talked about this book in my previous blog: "The Seven Myths of Pair Programming". I really enjoyed reading this book. It's time to put it back the shelf, so other developers in our office can get their hands on it, but I am sure I will come back to is sometimes. I want to talk a bit about one of the chapter at the end of this book.

Seven Habits of Effective Pair Programming

Habit 1: Take Breaks

This was one of the things that we identified early on. Pair programming is a very intensive activity. We worked in pairs whole day. And then at the end of the day, exhausted, we were still in the office catching up with the pile of e-mails and other administrative stuff. Take breaks on regular basis. Have a coffee, tea, talk to other developers, stretch, do whatever - simply, have a break!

Habit 2: Practice Humility

One of my favorite quotes that I use on daily basis: "Pair programming makes me feel stupid everyday. I love it!"

Habit 3: Be Confident / Be Receptive

Do not be afraid to appear dumb. Nobody expects you to know everything. You do not expect the others to know the answers to all your questions, do you? And remember, this is a teamwork, not a competition.

Habit 4: Communicate

This is very important. Today I had an encounter with one of our staff. He is not usually exposed to pair programming that we practice in our team. He came over to my computer and typed commands rapidly on the command line. No words said. I could not follow him. I was not experienced enough in that particular area and wanted to learn from him, so I asked him if he could comment what he was doing. I felt stupid again... but hey, I learnt something!

Habit 5: Listen

This is important as well. We all dive deeply into our thought when we type away our code. Sometimes I found myself not really listening to the navigator. When I finished, I had to ask what he said and reiterate thought his thought.

Another case is when you listen but assume you know what he or she is going to say. Do not assume. Listen! If he or she wants to say something, there is probably a good reason for it.

Habit 6: Be a Team Player

No much to be said here. Just be part of what is happening. Be actively involved in the process, whether it is coding or just thinking as a navigator. You need to be able to understand what is going on at any moment. If you don't, ask!

Habit 7: Hone the Balance between Compromise and Standing Firm

It's hard to find balance if you try to go separate ways. Always think that this is a teamwork and the way the project should be heading.

Monday, June 26, 2006

GWT Studio Plugin for IntelliJ IDEA

Alex Tkachman of Jetbrains announced on Friday that he had developed a plugin that adds support for Google Web Toolkit (GWT) to IntelliJ IDEA.

More information and a watchable demo

Sunday, June 18, 2006

Programming for mobile devices

If you are into programming for mobile devices and have not really dived into it yet, here is a usefull article that talks about writing cool games for cellular devices. I did not spent much time on it, but it seems like a very good tutorial with a complete example that might be useful for me one day - hence this blog post.

Friday, June 16, 2006

Pair Programming and Office Environment

Everyday I come to the office and I see people working. We all work in different ways. Sometimes we work by ourselves, sometimes we pair up to work together on a card we pick from the wall (card = task from the story board). These two ways of working are very different and I would like to share my thoughts on them with you.

Caves

People need privacy. They need to take or make phone calls or do some other things without disturbing others in the office. They also need to have a "home base", where they can keep their belongings. Such places could be small offices or cubicles.

Caves are also great for pairs whose task is to investigate something that none of the developers in that pair have experience with. This way some new things can be explored in a much more efficient way and different approaches can produce various results. These can be later discussed and a common solutions can be found. If the pair worked on one PC, the productivity would be only slightly better than of one developer working alone.

Commons

When it comes to pairing, people typically use their "personal spaces" or designated spaces, such as pairing desks or pairing rooms. There are two roles in each pair. The driver is the person who is in control of the keyboard and mouse at that moment. The other person is usually called the navigator.

In the case of the personal spaces, each desk must not limit the access to the PC. What I mean by that, is that the desk is best to be straight. Corner desks do not allow the developers to sit next to each other. Then it looks like the navigator is breathing down the driver’s neck and has very limited visibility of the screen. So, the "cave" is unsuitable for this task.

There are several variations of the pairing desk set-up. Let's talk about them in more detail.

One PC, one screen, one mouse, one keyboard

In this configuration, there is only one screen, so the settings must be so the navigator has as good visibility of the screen as the driver. Otherwise the navigator can not contribute much and the productivity of the pair is impaired. The navigator has no active control of what is happening. The only way the navigator can influence the process is by telling or suggesting to the driver. The limitation of having just one keyboard and mouse typically results in "switching" roles. When the navigator decides to drive, the control is passed onto him/her obviously by handing of the keyboard and mouse. Therefore everyone in the office can see who has what role in each pair at that given moment.

The usual way the developers drive is that they share a larger space in front of the screen. Ideally the developers should sit side by side and share the same (50%) of the screen space. This can only be achieved by having large and/or widescreen monitors (21 inch or larger). See the images below to see how large screen can work for a pair.

For the smaller screens the percentage the driver occupies is related to the size of the screen. For the 19 inch monitors it is approximately 60%. As the roles switch the developers shift to take or give space as shown on the images below.

One PC, one screen, one keyboard, two mice

A step up is to have two mice. Having USB mice is great. Just plug one more mouse into your PC and voilĂ . You are good to go. The OS should recognize both mice and you should be able to use them. Unfortunately, there is only one mouse pointer on the screen, so you have to fight for it. (Well, at least I did not find a good software that would allow you to have two separate mouse pointers.

Having two mice has a significant benefit. The navigator does not need to be told: "DON'T TOUCH MY SCREEN" when pointing at something on the screen. A mouse can be used for that. Moreover, the mouse is a powerful tool these days. There is so much you can get done with just a click.

Alright, so we have two mice, how do we switch roles. It's almost the same as before. The keyboard gets passed around. This setup usually results in the navigator sitting on the left and having the control over the spare mouse. The driver typically sits on the right having the control over the keyboard and the mouse. When the roles changes, as displayed below, the driver who becomes the navigator (on the right) loses the control and because there is no extra mouse on the right the navigator is quite passive (same as in the configuration with one keyboard and one mouse only).

The only solution to the right-side navigator's passivity would be an extra mouse on the right. It can work, I have never tried it and personally, it's just too many rodents on one's desk.

One PC, one screen, two keyboards, two mice

This is another step up for a better working configuration. In this case another keyboard is added to the PC. Each developer has his/her keyboard and mouse combo. In this way the developers can very effectively switch roles, almost instantly a navigator can jump in and drive for a few moments and then give the control back to the driver.

If your company can not afford to have spare sets of input devices, just bring your own to the pairing desk. All of us have the PCs, the keyboards and the mice, right? So, just unplug them from your PC and bring them to the pairing PC. Ideally, you would not have to do this. There should be some spare sets. The best results are if these are wireless as they tend to clutter the desk less and are easily portable. The only problem that can arise is that their frequencies may start to interfere, so wired ones might prove the best.

One PC, two screens, two keyboards, two mice

This is an ideal configuration and if you have it, you can call yourself lucky. There are not many companies that I know of that would provide their developer with such luxury. In our company we have several pairing rooms equipped with fast PCs and dual 21 inch screens with two sets of keyboards and mice.

This configuration is not only ideal from a driving point of view, but as a navigator you have a full view of the screen. Sometimes you might feel that when you are the navigator the machine is doing your work (that is if you ignore that dude on your side, but be nice to him as he might feel the same when you drive.)

Alternatively, the real estate of the two large screens can be used more efficiently by splitting the desktop. This can be done by stretching the desktop the way the one half is of one screen and the second half is on the other screen. This is useful most typically in cases when you need one window with source code and another window for testing the application (web browser for web applications.)

Laptops and pair programming

Laptops are nice little useful things. I love them. But they are not ideal for pair programming. Well, unless some special setup is done.

Read more about why the laptops are no good for pair programming.

What can we do? How can we be pair programming and using laptops at the same time?

The answer is not that difficult. All you need to accommodate the second developer is a screen, a keyboard and a mouse. Have you heard about USB? Get a USB keyboard and a mouse, and you are set. Well almost. The second developer needs to see as well. Give him/her a screen. Laptops have video outputs these days. It should be no problem to plug in additional monitor. The only

trouble might be setting up the resolution so it fits the laptop's screen as well as additional monitor's.

Alternatively you could configure the desktop to be stretched onto the second screen and this way you can use more real-estate as long as you maintain good visibility of both screens for both of you.

Office layout

So far, we have talked about the desk configuration. But what about how the desks should be organized in the office?

There are two factors to consider. Noise and communication. The communication is important not only within the pair, but also inter-pair. It is most beneficial if you can communicate quickly and when needed. The layout of the desks in the office should allow you to see and talk to other pairs easily. The layout documented in many XP books and articles describes the setting of six desks as on the picture below.

If you have enough space in the center of the room, this setup can work the best. The pairs can see each other and can talk to each other without shouting across the room. They also have a semi-private space where the pairs can work without generating too much noise disturbing the others.

These desks should be big enough to easily accommodate both developers, equipped with fast PCs and two sets of keyboards and mice. These should belong to the common area, they should not be personal caves of anyone.

We do not have this setup. We have pairing rooms that are well equipped, but they are rooms. And as such they isolate the pair from other pairs. The downside of it is that the developers very rarely communicate between pairs outside the meetings (formal or informal) when outside of the pairing rooms. Not all developers get to use these rooms. Simply, it's just too many of us and too few rooms. So we use our personal spaces for pairing as well. Neither our desks are located in the middle of room. The are lined-up along the walls and windows around the office. And so on some occasions there are big gaps between us and we have to walk across the room to talk to our peers.

No matter what the layout of the desks in your office is, try to respect the solo developers who require a quiet atmosphere for their thought flow. Pairs generate more office noise but can also effectively block out the noise generated by others. Solo programmers can not (unless they have earplugs and some loud music). Ideally, the pairs could be in a separate room from the personal spaces where we all work alone.


Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License.