Tuesday, April 26, 2005

Ruby Love

Ruby is the "Most Loved" programming language? That's one way of reading Thomas David Baker's Google results. Intepretation of the raw statistics is difficult, but my explanation of the astoundingly high Love/Hate ration is Ruby's Principal of Least Surprise. Things work the way you expect them to; by design. Isn't that the way all programming languages should be?
Category: ,

Saturday, April 23, 2005

Process, Philosophy or Religion

As I have admitted before, I work in software development. That means that I attempt to create useful1 software for people.
Starting from the requirements2, I:

  • think until it hurts

  • scratch out a bare-bones solution (back of envelope style))

  • hack it until it works


Umm, no. You can't tell clients that, can you? let's try that again:

  • Perform Analysis on the requirements

  • Develop the Analysis model into an implementation specific Design

  • Construct, Test and Improve the code (and design (and analysis))) iteratively


That's better. Now I have a process. I'm still doing the same things, but now I have fancy names. And when a client asks me how I develop software, I can answer that I use a RUP-derived Agile methodolgy. And I'm still doing things the same. The same way I did them when the correct answer to the above question was Waterfall. Many people misunderstand Waterfall; as a development process, it never worked. In fact, almost no one except the military tried to follow it literally (who notched up some really impressive catastrophes as a result). Waterfall is a tool used by project managers to document and report the project upwards. Managers understand Waterfall. Waterfall assumes omnicience; mere mortals need not even try that route.

So what does a poor developer do? Pick a process? Draw a line between Waterfall and XP, close your eyes and jab a pin to make your selection? Or perhaps the other way around? Find a style and methodology that works for you; pin fancy names on it. Here is the divide. Should you choose a Process or a Philosophy (or a Religion)?

A Process is useful if you need guidance. It is also useful as the basis for a contract between the developer and the client. If you tell your client that you will be following the Unified Process (or, more concretely, RUP), you are defining a set concepts; artifacts, activities, roles, responsibilities and so on. These form a common vocabulary (with the oft forgotten proviso that everyone needs to share the same understanding of the terms) for the project. Customize to the needs of the project and you have your methodology. Alas, this is no silver bullet. You still need to know what you're doing. Apply a process (any process) without understanding and you are on the road to disaster.

A Philosophy is the distilled result of experience. It trancends process; it is flexible; it adapts to your current needs, yet allows you to do things the same way as before. It may guide you, for example, to test early and test often (now called TDD – Test Driven Development). You can do that in virtually any process; whether your process specifies unit testing or no. Philosophy may guide you to maintain your code in a constantly buildable state. With a little ingenuity, you can fit Continuous Integration into most projects. Code ownership, or rather the lack of ownership may be a bit trickier if your team includes developers who are territorial, but that's a reminder that a team that is divided in Philosophy is not an effective team.

Religion is a Philosophy that has hardened through dogma. William Caputo baldly proclaims XP as a Religion (though he softens that statement down in his explanation). I guess that's why it's called eXtreme Programming. He elsewhere makes the good point that it is ultimately people who make a project succeed, not the process. For my own responsibility, I will add that successful teams generally share a common Philosophy; that is the secret sauce that binds them together. It promotes the trust and openess that is at the heart of the agile process. And that brings us to this simple paraphrase of (I believe) Kung Fu-tze (aka Confucius)3.

When the right man uses the wrong process, the wrong process works in the right way

When the wrong man uses the right process, the right process works in the wrong way



Category:


Note 1: Useful means both functional and useable (pointed out by Don Norman in his POET book, as I remember)
Note 2:Requirements gathering is another prickly area that I am saving for another occasion.
Note 3:With so many quotations attributed to him, I may just be mistaken. I can't find a reference to the original.

Wednesday, April 20, 2005

Web pages

When we build web pages we fill them with contain many things:

  • Content – that's the main stuff, the focus and purpose of the page.

  • Navigation – not part of the above, but ways to get to other pages

  • Fine print – again, not prime content, but necessary stuff like contact details and legalese.

  • Ambience – signs or hints that you are at the right place.

  • Fluff – stuff that makes no contribution to the purpose of the page.

An effective page is one that guides the eye to the main areas of the page, while still allowing users to find the secondary components.
Take a look at Google's home page, for example. Their content jumps straight out at you. Navigation and fine print; restrained. Ambience; the Google logo and spartanic page layout. Fluff? Zero. OK, not every page can be that simple and focused. Try Wired.com; the colours may be garish, but your eye can't miss the main content. And once again zero fluff.
Now try some telecom sites; Sprint, AT&T or Verizon. What do you see? Sprint (www.sprintpcs.com) has the improved lately, but it's still a challenge to find what the page is about. AT&T page "features" Flash. I need say no more. Verizon's main page has no less than 5 (five) non-content images (4 smiling women and one dog, when I last looked). I have no idea what, if any, focus was intended, but it's certainly not easy to find your way around such a busy page. Is it a coincidence that telecom companies enjoy a less than glorious reputation for customer service?
Web applications are hardly diffrent. Their "content" is the application window; often simialr to a desktop application's dialog window. Navigation offers other tasks or work flows. The fine print may read "Company confidential" and yes, non-content fluff sneaks in too. In my experience it's the company internal web applications that can be the worst. With a captive user group, comapnies feel less need for usability. "Blame and train" user interfaces abound. How much time (and money) is lost as a consequence? I don't dare think.
The basic principles have been known for a long time (small details apart, they are not much different from other user interface design areas). Good web page design is not that difficult.
Category: ,

Tuesday, April 19, 2005

Javascript

Javascript has acquired a rather dubious reputation. In part, this was due to some unbelievably bad implementation; in part it was (is) due to some excruciatingly bad code out there. Javascript today (and I should perhaps write EcmaScript) is altogether another thing. Still many developers hav litle clue how to write even moderately good Javascript. For those who wish to learn good Javascript style, one place to go is Ten good practices for writing Javascript in 200.
Category: ,

Naming consistency

I recently had to interface to some code written by another project. My attention was drawn to some data transfer objects (DTOs) and the lack of consistency in naming attributes. A common feature of these DTOs were an object ID and a display text. The object IDs were variously named as id, value, typeCode; often in combination with the class name. The display text were correspondingly named value, name, valueText and the like.
That the attribute "value" might be the Object ID in one class but the display text in another was disturbing. I am unable to guess how many bugs – past, present and future – such naming is responsible for, but I am sure it is many, many. This is the sort of thing that code reviews can pick up; it will come as no surprise to learn that the project in question "did not have time to do code reviews"
Category: ,

Sunday, April 17, 2005

Permissions

I run Linux on mylaptop. It's a sort of mongrel Debian unstable installation that used Knoppix to side-step the usual Debian installation pain. One of the first things I did was to apt-get Firefox. Then along came updates; now we have reached 1.03. Installing red-hot fresh Firefox releases means a manual install; if you want to use apt-get, you have to wait until the .deb package is released.
For my lack of patience, the reward is pain. Pain because printing didn't work – a permissions problem in /var/tmp, as far as I remember. Easy to fix; once you know where to look.
Then extensions didn't work. Extensions wouldn't install; they would say that they would install the next time Firefox re-started. Restart firefox and they would still promise that they would install the next time Firefox re-starts. Permissions problems again; to get a new install to work at all, I needed to bring up Firefox once as root. After that, I must chown all the files and folders it created in my .mozilla folder.
At least its better than rooting around in the registry.
Category: ,

Sunday, April 10, 2005

Interviews

Every so often, my colleagues and I are asked to interview a candidate for a project. We read the resume (or CV as it is referred to in some places) and schedule a time when one of can talk to the candidate; A first time interview is invariably done by phone; only short-listed candidates get to a face-to-face meeting.
Our initial impression of the candidate is formed by the few pages that supposedly summarize his or her skills and experience. When reading these ndash; particularly when the candidate's native language may not be English – we try to give a little slack. Nonetheless, overall sloppiness and inaccuracy generally is an accurate indicator of the candidate's abilities (or should I say lack of abilities).
Those resumes that come via placement agencies need special handling. There are some agencies – I won't mention any names – make a point of bolding every "keyword". The resumes they forward are truely unbelievable, the cadidate having years of experience in every conceivable area. Not only do they have experience in every technlogy you've ever heard of, but often extending back before even the stated technology came out. Unbelievable. And, of course, that's just the point. I don't believe a word of it. Usually the candidate fails to answer basic questions about topics that they claim long experience with.
Another tendency I have noticed, possibly related to the pojnt on the previous paragraph. During the interview, candidates, answer questions by "reciting" a set piece (regardless of whether it is relevant to the question). This is a by product of a general trend to grade people on being able to regurgitate "facts", not on understanding.
Good candidates can not only explain what they know and what they have done, but also which areas they are weak in; an honest admission of topics they don't know is a good sign. For whatever reason, many candidates feel (or have been told) that they must claim expertise in everything under the sun. Overall I get the feeling that our industry is in a sad state of self-deception.
Category:

Saturday, April 09, 2005

Subversion

Somehow there is always some issue with source code repositories. Like most developers, I have, at various times, used many different tools. Some simmple, some complex; some good, some truely evil. Many times, the choice of the SCM tool was forced by outside constraints; no budget (i.e. must use a free tool); client has a corporate wide policy that must be followed; must run on a certain operating system. As a result, I have source code stored in a variety of different repositories. Or, I should say, had many repositories. No more; I have subverted all of them.

The triggering event was subversion 1.1. I had been using subversion for a while, but only for newer and non-critical projects. It was working quite well, but I didn't feel totally at ease with its use of Berkley DB. The 1.1 release provides a new option; FSFS, which has numerous advantages. One in particular is that the database is independent of the platform. Finally, I could migrate code from Windows based repositories to Linux, which is my primary OS today.

Setting up subversion on Windows was quick and straight forward. I used the vss2svn script. It is written in Perl, and it looked a lot neater and readable than most Perl scripts I have seen. More importantly, it worked. Not first time, admittedly; I fumbled a bit while I found out how to get it to work, but after a couple of mis-steps, I figured it out.
E.g.

svnadmin create --fs-type fsfs g:/svn/C

svn mkdir file:///g:/svn/C/Spread --message "C++ Spreadsheet library"
vss2svn.pl --vssproject "$/Spread Sheet" --svnrepo http://localhost/svn/C/Spread

Here I created a repository call "C" and migrated a VSS project called "Spread Sheet" into an svn project called "Spread". Repeat ad nauseam until all projects have been migrated. Note that while svnadmin and svn commands use file:// URLs, the script itself likes to tallk WebDAV (HTTP), so I had to configure Apache for subversion. [OK, I could have used suversion own server, but Apache was already installed and running.]

Reboot into Linux and confirm that the svn repository was OK. It was. Now it's just a quick install to get Eclipse to connect, right? Er, no, hold on a moment. The svn plugin for Eclipse uses Javahl library and the nice folks at tigris.org had just stopped supplying the binaries for Linux. Now I was too far down the subversion path to back off. To my surprise, it built and installed with no problems. All smiles? Almost, but not quite. Subeclipse is still a work in progress, and it got dirctly upset with me because I tried to commit a file with name that contained an accented letter (Caramellizzaté). My bad – I should have known better. Sigh. I am hoping the latest 0.9.30 release is more placid. Overall, though, I am quite pleased with the result.
Category:

Friday, April 08, 2005

Inheritance

For some reason, inheritance has been under attack recently. One source that people frequently cite is an article by Allen Holub, called "Why extends is evil". Allen has been around for long enough to have acquired the status of knowing what he is talking about. I remember reading his articles in DDJ, myself. That makes it more surprising that his article totally misses the point of inheritance. Let's look at his example.
Allen extends Java's ArrayList class to make it behave like a stack. Er, OK, but then he points out that actually his nice new Stack class has some flaws:

Stack a_stack = new Stack();
a_stack.push("1");
a_stack.push("2");
a_stack.clear();

Allen rightly points out that by calling clear() on his stack, you leave it in disarray. Ah, but that can be fixed by overriding the all of ArrayList's methods that would subvert his lovely Stack class..Oh, but that means that we have to override so much that we would be better off just inheriting the interface, he writes.

Umm, I think we just hit the core of Allen's problem. By using extends, Allen is telling us that he believes that Stack is-a ArrayList. Yet almost immediately afterwards, he tells us that his Stack class breaks when you try to use ArrayList behaviour on it. In other words, a Stack does not have an is-a relationhip with ArrayList. And Allen should know that using extends in a situation where there is no is-a relationship is just plain wrong.

So why is Allen trying to mislead us? Can it be that Allen has never heard of one of the basic principles of OOD? I doubt it.Is Allen just pulling an Apriil Fools joke on us? No, the article date was August 1, not April 1. Can it be that his work as a consultant has led him into selling voodo and black-magic to his clients? Perish the thought. Just stirring up controversy in advance for his forthcoming book. What a cynical idea.

If he had written that "using extends without an is-a relationship" is evil, it would be easier to agree with him. I don't know what motives led him to write such nonsense, but please just politely ignore it. Inheritance is fine when it is properly used. If you don't know when inheritance is appropriate, go and do some homework (try Googling on Liskov Substitution Principle as a start).

Category: ,

Thursday, April 07, 2005

Jsp page architecture

What architecture should I use when using Java Server Pages? Sun leaves us guessing. There is "Model 1" — which loosely translated means the JSP page contains everything in a hodge-podge. And there is "model 2" — which, again roughly translated, means that you do your homework first and let the JSP do just the display part of the deal. That still leaves us with a lot of questions.
Here's my answer (YMMV – Your Milage May Vary):

  • Your URI translates into a servlet (which might be a Struts Action, or equivalent). The servelet (or Action) talks to the "back-end" — hopefully directly or indirectly to your Domain Object Model (DOM).

  • The Servlet/Action does all neccessary preparation to display the data / entry form. That includes converting raw data to display format (applying I18N / user preferences etc.).

  • The servelet forwards to the JSP.

  • The JSP starts with the obligatory jsp stuff (page includes, taglib includes and the like.)

  • Then there is an absolutely minimal scriptlet to do stuff that absolutely must be done in the page (maybe a log trace statement or something)

  • From here on, only tags – HTML and JSP (including custom tags) are permitted


You may ask – Absoultely no scriptlets in the HTML? Correct. None whatsoever. Iteration? Struts/JSTL iteration maybe, but definately no <% for (int n = 0; n < length; n++) %>. Never, ever. Just say no. Do all your preparations beforehand and let the JSP render it.

Advantage? Your pages become simpler and easier to work with. Pages that mix Java scriptlets and HTML are understandable by neither your GUI folks, nor your Java developers. Whoever tries to make changes will trample on the other's domain. It will end in tears, believe me. Don't go there.

[Last minute addendum: You might ponder over tables (the tabular data sort, of course). If rendering tables using scriptlets is out – and it is – it doesn't mean you just do the same iteration using Struts/Jstl. If you haven't done already, go to http://displaytag.sourceforge.net/ immediately. Disclaimer: I don't use displaytag myself; I have my own library that contains a similar (in concept, but not implementation) tag.]
Category: ,

Tuesday, April 05, 2005

Where to start

Where do you start when you have a new task delivered to you? I'm assuming now that the requirements are there and clear enough to procede (breathtaking assumption, isn't it)? What do you look for as you do your analysis?

I find that while I am going through the usual business of identifying objects (nouns) and actions (methods) I'm looking for patterns (not the GOF type — not yet) and symmetry. These are keys to simplification.

Take for example, a simple little brain teaser where one of the key action requires concatenating symbols. Groups of symbols may be joined by operators; in other words any pair of symbols may be separated by an operator or abutted directly. Where's the symetry? Lets restate that last bit: any pair of symbols may be separated by an operator or nothing. But nothing can just be an "operator" object that contains an empty string, for example. In the real world symmetry is broken; in our solution space, we can restore the broken symmetry and make our code that little bit simpler and more elegant:

Here's the code (Ruby) I wrote:


@sep = { "+" => "-", "-" => "", "" => "+" }



It's a hash (associative array) that lets me look up a value in terms of a current value.
Pure rotational symetry.

Show the full teaser (complete with code).

Tables static or dynamic

Right now, I seem to be caught up with tables — the (X)HTML sort. My current project has lots of them. No, not for layout; that's so last millenium. We use tables to present tabular data; results and summaries, for example. And tables to accumulate entered data prior to submitting a page. Those are the dynamic ones. The user enters data into text fields and selects from dropdowns, but instead of submiting straight away, we add (remove or edit) data to the table. A new row? Use the DOM. Hidden variables? Store them in hidden columns; or maybe in attributes of the row element.

Now the next step is in-place editing; imagine a screen displaying rows from a report. Now users want to click on a data cell and edit the data just as if it were a spreadsheet. That's interesting; I mocked up a prototype pretty fast, but them got stuck aligning the text field over the table cell. Tricky to get it right accross browsers. I'm getting there. Yesterday, I noticed that someone else was doing something similar. No tables, though. I'm not eager to have shadow edit cells for each display cell; it wouldn't scale for my requirements. I prefer to create and destroy the edit field on the fly. But encouraging that there's some one else out there trying to do something similar.

Oh and in some cases, when the user edits the data and hits enter, we have to fetch a whole new row from the server. We do that using a Javascript http client — that is the technique that just got itself a fancy new name, Ajax. But that's a new topic — I'll save it for another post.

Thinking objects

Thinking in terms objects is so natural for me that I tend to forget that some people don't. Long back, I remeber someone putting ot like this. The world is divided into two; those who see objects in everything and those who can't understand what all the fuss is about. For me, using object is a way of reducing the signal to noise ratio of the code.

That Allows me to concentrate on the interesting bits and delegating the neccessary, but boring details to the objects that have been given those responsibilities. It's another aspect of the DRY principle. A class takes responsibility for certain behaviours, leaving me free to invoke them whenever I have the need.

That saves me having to write the same code snippets time and time again. As they say; laziness is the mother of invention. Great, now I can spend more time doing the interesting bits.

Monday, April 04, 2005

Watir 1.2

Watir 1.2 has been released. Support for tables is much improved, but there are still some niggly details that need fixing. Also, the newWindow unit test fails when I try to run it. I don't know if this is me or if the released code has a bug. Still nice job so far.