Archive for the ‘tips’ Category

Dell: The D is for Customer Disservice ..

Saturday, December 1st, 2012

This post is about the bad Customer Service I received  from Dell’s online chat facility and how I think putting Customer Service Operators in front of Customers without the proper tools is tantamount to sending troops into battle without weapons. Your going to loose the battle for a happy Customer, and your staff are the casualties.

Unhappy Dell

About 10 years ago I had a Motorola mobile and I wanted to know if I could use it in the United States. I rang the local provider I was with to ask. The Customer Service representative said they could not answer my question and that I should try Motorola directly and could I hold. I then heard a flicking noise like the pages of a telephone directory were being turned. This was 10 years ago. I asked the operator what she was doing and she responded “I’m looking up Motorola’s number for you, I can’t put you through but I can give you their number.”. What helpful service. I was a customer of the provider for quite some time after that and I was very happy with the service.

Today I read an article on on the new Dell XPS 13 Developer Edition which comes with Linux installed. I went to Dell Australia and searched for it. No Luck, so I went to the Dell US site thinking that maybe it has been released in the States and down under might be lagging behind. Nope, no Dell XPS 13 Developer Edition on the site. I used the search box top right. Why would Dell announce a product was available and yet not list it on the site. Frustrating.

I was just about to leave the site when a window popped up  and asked me if I would like to talk to a Customer Service Operator and I clicked Yes. What follows is a transcript of that discussion, which Dell emailed to me when I closed the chat window. I have removed the names of the operators since this post isn’t about them, it is about the bad Customer Service I received because of the tools provided to them. Needless to say I didn’t buy a Dell today and I’m not sure if I ever will again. Although I probably should not even have considered them after the Battery in the Dell Latitude I have failed to charge just 3 months after getting it. Another story.

chat log

What I want to happen is for the search to return the product I’m looking for.  Secondly, when dealing with Customer Service I want the first person I deal with to be able to handle my query. When being handed from one person to another I expect not to have to repeat my story, especially when it is in electronic form for all to see.

Dell, please don’t send your troops to the front line without proper support, its abusing them and loosing you Customers. Please don’t tell me your systems are not compatible or don’t talk as that is just an excuse. I write software and I could make them talk.

When Customer service systems don’t align or sync to provide Service then you are simply automating a processes to upset customers quickly. Do you really want that?

Javascript MVC/Maria/Design …

Thursday, June 14th, 2012

Yesterday I gave a presentation at the Melbourne Javascript Users Group on my learnings doing MVC with Javascript, my recommended MVC Library Maria and a little on East Orientation. I enjoyed giving the presentation and if you want me to present to your group just contact me. Below are the slides from my presentation. Feel free to contact me with any questions.

melbjs-maria-east

Update:

Here is a fantastic blog post that details MVC and more importantly Maria - MVC done right - IMHO.

The Sound of Javascript: How to solve a problem with Maria …

Tuesday, May 15th, 2012

maria

Overview

Have you noticed the growing movement to developing thick clients on the browser? These thick clients move a complexity from the server to the browser while promising enhanced experiences tailored to the client device. A common theme with this movement is the use of Javascript, the Model View Controller (MVC) pattern and sending data between client and server, typically in JSON format.

This post is about developing just enough of an MVC based client on the browser to see how and where all the parts fit together, what design considerations might need to be taken into account and how the MVC pattern is applied. What is not implemented is the mechanism for communicating between the client and the server to remove a complexity that might otherwise obscure the client code. Client to server communications will be discussed without implementing code.

I’ll walk you through the code to exemplify the approach taken and how MVC comes into play. A goal is be to keep things minimal and clear in the hope you can use one or more of the techniques and tools outlined in your own projects. This post may even help you select alternative tools and frameworks.

* * The title of this blog is a play on the musical The Sound Of Music which contains the song “Maria“.

The Code

The code discussed in this post can be found here

Goal

My goal is to develop a small yet exemplary application and the canonical Todo application fits that bill quite nicely, with its simple data model and a user interface that needs little explanation. A Todo application can also be quite useful without server side functionality so conceptually its a whole application. The Todo Applications core model is essentially a list of entries outlining what is to be done, with each entry having a flag indicating if the entry has been completed and a description of what is to be done. To make the design and the use of MVC as clear as I can I have chosen to model the client side application as separate from the Todo model it manipulates. I find this helped me keep the separation of Client side and Server side clear and provide a more obvious ‘entry point’ for see where the Client Application begins and ends.

Tip - I strongly suggest that when Client Server data exchange is implemented that the data exchanged is not a direct mapping of the AppModel, rather it is an exchange of messages to manipulate each ’sides’ model indirectly. For example, when server data is processed it becomes a series of calls on the AppController rather than a direct replacement of the AppModel. A direct replacement or manipulation of the AppModel would be a tight coupling that would lead to possible change impact issues later.

MVC - Model View Controller

The Todo Client Application is embodied in the classes AppModel, AppView and AppController (see figure x), with the file src/js/initializer.js bringing them into existence when the browsers window load event is fired. The initializer.js code is the equivelant of a Java or ‘C’ programs ‘main’ function. Each class (AppModel, AppView & AppController) implements their part in the Model View Controller (MVC) pattern. There is a lot of material out there describing the MVC pattern in depth so I wont regurgitate it here, suffice to say I’m following the pattern as described by GOF and implemented in Smalltalk examples.

In a nutshell a View listens for events to happen on a HTML Element. When an event happens like the input field has changed the View is notified (by Maria). The View then extracts or builds whatever data is needed so it can communicate the event to the Controller by calling one of its methods. The Controller takes the notification and applies whatever Business logic it embodies (via other classes - don’t contain it within the controller) and calls a method on the associated Model to inform it of the change. The Model applies the appropriate changes to the model and then notifies all the observers of the model (via Maria) that the Model has changed. A View typically observes both a HTML Element and a Model meaning it will have a method called on it when either the HTML element or Model changes. When the HTML element changes the Controller is notified, when the Model changes the View is rendered. This is the circle of MVC life.

Looking at src/js/AppController.js you will notice little more than what is required to subclass the Maria Controller class and some may feel the controller is therefore unnecessary. Resist the urge to remove a Controller that is as simple as this because doing so removes a clear indication of where certain functionality belongs and tempts the lazy or uninformed developer to directly bind aspects of the Model to the View and that isn’t MVC. Not following MVC quickly couples and bridles the parts of an application with responsibilities that don’t belong, starting you on a road to despair.

Maria

To implement MVC I wanted to use a library that would implement MVC effectively yet not dictate an approach with lots of methods or classes that must be implemented, nor require a large library of dependent Javascript to be loaded. The Maria library developed by Peter Michaux and available here is such a library. Maria is thin and un-opinionated* making working with it simple and quick. At the time of writing this Maria is not well documented but I was lucky enough to have the support from Peter for my experiment. Maria is so straight forward that I rarely called on Peter to explain the library, instead we mostly discussed design issues like the progressive enhancement of existing HTML or the dynamic rendering of HTML by View objects, both of which Maria supports. Even if you don’t use Maria I suggest you have a look at the code behind it as an example of good Javascript.

* Maybe Maria is opinionated and I just happen to agree with the opinion.

Design Considerations

I chose to use a kind of progressive enhancement approach in the Todo Application, where the AppView attaches sub-views to HTML elements already present on the page when the AppView is created. This supported my working style where I created the HTML separately to writing and running my Javascript. With most applications there will come a time when a view cannot attach to an existing HTML element and will have to create elements at runtime. Consider this when making the choice of which style you want to use. Doing both helps make my Todo Application an example of both approaches.

Another design decision I made was to ensure dependencies are passed to a class instance when they’re are created. For me this helped make the dependencies more explicit and facilitated easier testing. However Javascript is such a flexible beast that inverting dependencies for testing isn’t strictly required as you can get at the innards of an object quite easily. I’d say that I probably inverted the dependencies more out of a personal style or ethic of not referring to global variables and not instantiating what could be passed in. Note that Maria follows the Smalltalk MVC implementation closely and will create a Controller for a view on demand (see maria getDefaultControllerConstructor) but I didn’t use this approach, and to Maria’s credit this didn’t cause any problems.

A design decision I have touched on already is embodied in AppModel, a Class that represents the data of the Client Application as a whole. The AppModel contains a reference to the set of Todos that are being manipulated. This set of Todos could be seen as the core model but a higher level abstraction helps here as the Model in MVC is typically manipulated through an assortment of views and sub-views created on the same Model. When this model is not the ‘parent’ you eventually end up with a Controller needing to track a parent and a child model, or a model that keeps a parent relationship unnecessarily. Typically the top level model will expose the behavior that manipulates sub-models making it ideal as a parent and ‘documenting’ the behavior of the Application, ie: addTodo().

The Application

My Todo Application is minimal in that it only captures items to be done and doesn’t currently allow you to mark an item as done. This is enough to illustrate the points I wanted to make in code and to use the Maria framework in a ‘real’ way.  The code for the Todo application is available in here (link) and what follows is a walk through of the code from the entry point through each class as it participates in the MVC pattern to enable the collection of Todos. It is hoped that following the code from the entry point down with a description of each line is the most appropriate way of describing what is going on and how the parts of the application come to interact with each other.

maria-files

Running The Application

To run the Todo Application you need to make the todo-maria.js file by issuing the “make” command in the root folder. This results in a todo-maria.js file being created in a ‘build’ sub-folder. When this is done you can open the index.html file with your browser and you should see the Todo Application. Should you run into problems please check the README file in the distribution.

src/js/initializer.js

maria-initializer

This file is packaged into the todo-maria.js file by the ‘Makefile’ where the initializer code is run as the full todo-maria.js is interpreted. The code in this initializer
creates the root triad of AppModel, AppView and AppController with their dependencies when the browser window has loaded. Since the AppView requires an existing HTML document there is no need to create the view before the document is ready. The initializer fragment of code uses the Maria event listener API to register our function to be called when the window loads. The initializer tests if the global ‘window’ object is defined before continuing because in my test scenarios the ‘window’ object is not present. There is probably a nicer approach than this but I have not looked into it.

src/js/AppView.js

maria-appview

The AppView is the main view of the application but it doesn’t attach itself to any HTML element, instead it binds other views to HTML elements using the DocumentToViewBinder class. The AppView requests the DocumentToViewBinder to bind the HTML elements ‘entry’ and ‘list’ to the associated View and Controllers, with each sharing the same AppModel. You can think of the AppView as an Abstract View. You should note that the AppView is an observer of the AppModel and when the AppModel is changed the update() method is called on the AppView. This update() method doesn’t perform any action as the sub-views themselves perform these actions as they are also observers of the AppModel.

src/js/AppModel.js

maria-appmodel

The AppModel class represents the data model for the whole application and is composed of a set to contain the Todo’s. The ‘Set’ class is provided by Maria and it has some neat Collection methods making working with a collection more natural than when working with an array. When additional data is required for the application it would be added to the AppModel. When a Controller needs to manipulate data it calls a method on the AppModel to ask it to do the work. At the time of writing this the AppModel exposes the Todo set with a method and this is wrong, wrong, wrong. The AppModel should instead allow a function to be applied to each element of the Todo Set, keeping the implementation private and using the Tell Don’t Ask principle. I’ll be changing this as a priority.

src/js/AppController.js

maria-appcontroller

The AppController coordinates requests from the View to update the model. Looking at the code right now you can see that the AppController does nothing more than subclass the Maria Controller and remember the associated Model. Not all the controllers in the Todo Application are this trivial but resist the urge to remove the ones that are. Controllers that do nothing provide two things, a place to add functionality when needed and a clear indication that the associated View doesn’t make requests to modify the associated model. A Controller is the ideal place to expose the behaviour needed to update the model, typically taking the notification from the View and then packaging that up in a new object before calling a method on the model. This flow is shown in the InputController which I’ll detail below.

src/js/DocumentToViewBinder.js

The DocumentToViewBinder is a Factory for finding a HTML element from the DOM and creating an associated View and Controller. It is the element map passed to the DocumentToViewBinder that defines which Views are bound to which HTML elements, and these views will typically register to be notified when certain events are fired by the elements they are bound to. See InputView as an example of this. Technically the DocumentToViewBinder should be constructed with another class that handles the finding of the HTML element to be bind, as mixing this responsibility into the DocumentToViewBinder class violates the Single Responsibility Principle. I’ll add this as a TODO for me.

src/js/namespace.js

The namespace.js file ensures that a todo object exists into which all the todo application components can be bound. Using a namespace reduces the probability that class names and function names will collide with already defined classes and functions.

src/js/InputView.js

maria-inputview

The InputView class listens for events on the associated HTML text input field, and for notifications of the AppModel being updated. Maria will call the ‘initialize’ method on a View to give it the opportunity to register for the events on the HTML element that is it interested in. In this case the InputView is interested in the ‘change’ event on the HTML element and when that event occurs it wants the ‘inputChanged’ method called on the InputView. When the ‘inputChanged’ method is called the View extracts the contents of the HTML text input field and tells the associated InputController that the view changed passing the input text along. The InputView also provides an ‘update’ method which is called (by Maria) when the AppModel has been updated. In this case the InputView does nothing with this notification and I could remove this method as Maria provides a no-operation implementation, however I left it defined as an explicit extension point for people less familiar with Maria or myself at a future date.

src/js/InputController.js

maria-inputcontroller

The InputController provides a method to be called when input has been given via the InputView. When input is received it is packaged up into a simple object and the method for adding todo entries is called on the AppModel. The View is also asked to clear its input ready for the next input.

src/js/ListView.js

maria-listview

The ListView class is slightly different to the InputView in that it doesn’t listen for event on any HTML elements, instead it listens only for notifications that the
AppModel has changed. When the AppModel has changed the ListView clears the associated HTML unordered list and adds each of the items in the Todo set as items in the unordered list.

Testing

I used the BusterJS framework for testing for two main reasons, firstly it provides behavior style testing that I am used to from my use of Ruby and RSpec, and secondly because it was being used by Maria for it’s testing. I found BusterJS to be fast and effective and its ability to automatically test on different browsers is very attractive.

At times I found that my tests would fail but running them two more times and they would pass. I have not looked into this and would not use BusterJS in a Continuous Integration environment until I could find out why this is happening.

You should note that some of the tests are not up to my usual standard as they don’t check all arguments passed to methods when they check a method call. This means it is possible to forget a parameter and tests continue to pass. I let the tests get this way as I was new to BusterJS and the underlying SinonJS library. I’ll be tightening up the tests.

Conclusions

Writing my Todo Application as a browser based client was a worth while experience and it helped me get a grasp on what it means to develop this style of application. Some important things I learned were:

  1. Follow MVC and always have a Controller even if it does nothing. Don’t communicate directly from View to Model, or Model to View. The MVC circle of life is all about being called back in response to events on objects being observed.
  2. Create a top level Model composed of other models to conceptualize the Client as a whole. I went so far as to have a top level Controller and View which helped.
  3. Use Maria or another MVC framework that is light and unobtrusive. I recommend you start with Maria even if you plan on moving onto more opinionated frameworks as it will provide a grounded understanding of MVC principles.

Your feedback is welcomed.

Courtesy is catching …

Wednesday, April 18th, 2012

bowing

I received an email from a friend regarding my interactions with him, and the positive effect they have had on him and his interactions with others. It appears that courtesy is catching.

Here is the email:

“We haven’t had a chance to chat for a while but the things you write have had an impact on my interactions with others. One thing I noticed is you take the time for a pleasantries like “nice to chat with you”. I always try to be polite with others when I interact with them but never quite as far as showing appreciation just for the opportunity to interact. Lately I’ve been adding a few of these kinds of pleasantries when interacting with others. Even with people I have good working relationships with, I’m finding they appreciate the acknowledgement and I enjoy giving it. So it is a bonus for everyone.

So thanks for leading me by example. :-)

A Goal Pyramid: Helping make decisions …

Sunday, October 30th, 2011

goalpyramid

When a Team starts on a piece of work they implicitly know the goal is to get the job done as efficiently as possible. There are probably other goals that are not verbalised and therefore not implicitly in the minds of the Team and this is a big problem, big enough to destroy the Team and significantly hamper getting the job done. A shared understanding of the goals of the Team helps focus decisions as each decision can be related to how it helps accomplish the goals. Without established goals decisions making can break down into a battle of wills which is extremely costly in multiple ways (this is covered in the book ‘Getting to Yes’ which I blogged about here. The goals of the Team are not just the Company goals they are also Team members personal goals like ‘I want to learn technology X’ or ‘I think the design should be Y’. These personal goals are rarely explicit bubbling along just below the surface with a building current that can derail a project.

Explicit and honest goals can help a Team focus and make decisions quickly and in a manner that feels more cohesive and transparent rather than driven by the loudest person, biggest personality or <insert sterotype here>. What follows is a proposed technique for making the goals of the Team explicit and prioritised to enable a Team to move forward efficiently with a transparent mechanism for making decisions quickly, reducing personal conflict and focusing the Team on getting the job done. After all, getting the job done is always the number one goal.

A Goal Pyramid is a hierarchy of ten (10) Goals starting with one at the top, two on the next row, three on the next and so on to form a Pyramid. It is suggested that the Goal Pyramid be kept to ten (10) goals. The first and highest priority goal is the core Business goal, “to get the job done as efficiently as possible”. If this isn’t the Goal at your Company then you should change the first and highest priority goal to that. This top goal is not a negotiable goal like the rest that make up the pyramid. To find and fill out the other goals you need the team to list all the goals they can think of and then prioritize them into the top nine (9). These top nine (9) goals will make up the rest of the pyramid from left to right, top to bottom starting on row two. The goals on row two have a higher importance than those on row three etc. A pyramid is used rather than a list or another shape as it allows the number one (1) goal to be clear while allowing the remaining goals to share in importance on each row, and have priority over those on lower rows.

The list of goals to prioritize should be succinct and clear to each team member so they know what they will be voting for to form their top nine (9). Each goal should have a title, a description and a “because when we don’t …” section which lists the impact/remifications of not focusing on the goal back to the number one (1) goal. For example, “Goal: Clean Code. Description: We should follow the principles set out in the book Clean Code. Because: When we don’t the code base becomes harder to work with slowing our ability to ‘<number 1 goal here>’”. In arranging your pyramid graphically I suggest putting the ‘Goal:’ in the Pyramid and having a legend under it to elaborate on the ‘Goal:’. However, nothing should stop you from having all this information in each pyramid segment if you wish.

A difficulty and thing to watch out for in forming the pyramid is getting the team members to be open, honest and transparent in why the goal matters. For example, a goal of “Keep Simple” looks fine until you dig deeper and draw out the fear behind this goal which might be a fear of meeting the deadline or a fear of a design that is not fully understood. ie: I want to keep the design simple because I don’t understand your proposed design. This particular example draws out a different issue, that of information sharing / knowledge transfer to understand a design more. This is an intended side effect of forming the Goal Pyramid. Encourage your team to think hard about the goals and to be as honest and fearless in presenting them to be voted upon. Wanting to use a particular tool or approach is a fine goal and it needs to be related back to the number one goal, made known and prioritised with the team. Letting the who team in on a goal means we can all work together towards multiple goals. A win-win situation.

    • Goal: Simple Goal statement
    • Description: A longer more informative description of the goal.
    • Because:  A set of reasons for the goal.

Once your Goal Pyramid is formed you can refer to it in situations where a decision is required, helping focus the discussions on the goals and to break deadlocks which can occur when Team members are in a battle of wills. A systematic analysis of how a path of action effects reaching the number one Team Goal will usually be resolved quicker than battle of wills and assist in preserving ego. For example, lets say a Team member wants to use a new and exciting piece of technology and a goal in the pyramid is “Goal: No risk. Description: Don’t take unnecessary risks. Because: When we take risks where a tried and proven path exists we jeopardize our ability to ‘<number 1 goal here>’, we can say no in a non-personal and professional manner by pointing out this ‘agreed’ team goal. Note, we don’t have to say no, we can say yes in a way that meets our goals. For example, in the same case above we might ask the team member for a plan or strategy for mitigating the risks, or offer our own like “why don’t you make a branch and work on this after hours or weekends to prove it out, taking the risk away from the team?”.

I have not yet tried a Goal Pyramid, and I plan to do so as soon as I can. I formulated it because I see a use for it in solving problems I have experienced in my career. One thing I have learnt in many years is that there are rarely if any technical problems that hamper a team delivering, rather people problems have been the root cause. I hope to use a Goal Pyramid as a tool to facilitate getting through some of these people challenges. Should you make or use a Goal Pyramid then please let me know as I would like to provide feedback here on success or failure of this approach. I will do the same.

Edit: This link was emailed to me and I think it is relevant to this post: http://blog.8thlight.com/brian-pratt/2011/10/25/simplicity-of-teamwork.html

A fart in a jar…

Saturday, January 22nd, 2011

jarjar

Recently I spoke to some people about commercializing some software I was helping develop and the discussion was very short. After the discussion I remembered a lesson I learned in 2000 after I’d tried to ’sell’ an idea to get funding.

What I remembered is that it is all about numbers. You could be selling a ‘fart in a jar’ and as long as the numbers are good you probably have a chance. Focus on the numbers and don’t spend a great deal of time on describing the service or product - or at least leave that to last. The investors are looking for a ‘risk to reward’ that suits them. Give them this information first, and if asked, tell them what the product or service is. They will probably want to know, but after the numbers appeal to them.

What numbers will they want to know?

  1. How many ‘farts in a jar’ do think you will sell over 1, 2 and 5 years?
  2. How much will people pay for a ‘fart in a jar’?
  3. What is the cost of putting a ‘fart in a jar’ and delivering it to the purchaser?
  4. How much of the ‘profit’ will they get?
  5. How much money do they have to risk to get that ‘profit’ and in what time frame?

There are some other things that investors will want to know like the competition and if there are other risks involved in getting a ‘fart into a jar’ etc etc. However, my experiences suggest this will be of secondary value to the numbers.

On another note, does anyone know a good way of finding out what someone would pay for a service (not a ‘fart in a jar’) ?

Disable The File Save Dialog

Monday, September 27th, 2010

No File Save Dialog

The web application I am developing allows the User to download various files in different formats. To test this works I’m using a combination of things, with Ruby WATIR-WEBDRIVER for the front end and Firefox for the browser and all automated with Hudson as the Continuous Integration (CI) Server.  The problem I face is that Firefox wants me to tell it what to do with the files each time I download them and this isn’t going to work for my CI needs.  So how can I prevent Firefox from asking me what to do with each file I download?

The functionality is there inside Firefox and WATIR-WEBDRIVER and you just need to turn it on. What follows are the steps to do this:

Create a Firefox Profile

Run the following command from your command prompt / terminal:

firefox -ProfileManager -no-remote

This will start an instance of the Firefox Profile Manager (see below) where you can create a new profile. I called mine “no-download-dialog”. You may also have an existing profile for running WebDriver but leave this alone. Click “Create Profile” and follow the wizard.  When back on the profile manager select “Don’t ask at Startup.”. Click “Start Firefox”.  NOTE that we are now using the Firefox Profile we just created.

Make a File Association

Firefox allows you to disable asking you what should happen to files being downloaded when there is a file association for that type of file.  So using this Firefox instance go to a Web site and download a file of the type you are going to download during your tests. In my case these were XML and Word documents. During the download Firefox will ask you where you want to save the file and allow you to select the option to “Do this automatically for files like this from now on” (See below). Select this option and save the file.

Now that file is downloaded Firefox should have an association between the file type and the action you want to perform. To make sure this is correct go to the Firefox Preferences (sometimes called Options) and select the Applications tab. I’m using Linux so this is Edit->Preferences->Applications (See below).  Scroll down the list of Content Types and Actions until you find the Content Type for your file. If you can’t find it then maybe your Web Server is sending something else as the Content Type when you download files.  When you find the Content Type check that the Action is set to “Save File”, if it isn’t you can change it now.

As a final test find another file of the required type and download it and you should not see a file dialog. However, you may see the Download Manager window, which can be disabled in the Preferences->General tab. De-select the “Show the downloads window when downloading a file”.

Test with Profile

Now that you have a profile that doesn’t ask what to do with downloaded files you need to tell your tests which profile to use. I’m using WATIR-WEBDRIVER but the same abilities are provided with other tools that sit atop Selenium. In your code where you obtain a browser instance add an argument to specify the Firefox profile to use. For me this looked liked this:

Watir::Browser.new(:firefox, :profile => 'no-download-dialog')

In some other tools or in Java you may need to specify the profile on the command line like this:

java -jar selenium-server.jar -firefoxProfileTemplate "<your no download dialog profile name>"

Set the Default Profile

So that Firefox is using the default profile when started outside of testing you need to tell it to use the “default” profile again. To do this Start Firefox Profile Manager and choose “default” and make sure “Don’t ask at startup” is selected and then exit.  Firefox should behave as normal when started outside of testing

Now when Firefox is run by by the Continuous Integration Server it will not stop the tests to ask you where to save files.

Test Driven Tortoise vs Hackey Hare …

Sunday, August 8th, 2010

hare-n-tortoise

Said the Test Driven Tortoise one day to the Hackey Hare:
“I’ll run you a code race if you dare.
I’ll bet you cannot
Arrive at that production spot
As quickly as I can get there.”

Quoth the Hackey Hare: “You are surely insane.
Pray, what has affected your brain?
You seem pretty sick.
Call a doctor in–quick,
And let him prescribe for your pain.”

“Never mind,” said the Test Driven Tortoise. “Let’s run!
Will you bet me?” “Why, certainly.” “Done!”
While the Test Driven Tortoise creeps,
with Tests, Continuous Integration and
customer speaks, Hackey Hare makes four leaps,
And then tells all how soon he’ll be done.

It seemed such a one-sided race,
To win was almost a disgrace.
So he hackily coded about
until the bugs inevitably came out –
As the Tortoise was nearing the place.

Too late! Though he sped like a dart,
the bugs hard to start
The Tortoise was first. She was smart:
“You can surely code fast,”
She remarked. “Yet you’re last.
It is better to get a good start.”

Adapted from Jean de La Fontaine’s poem: Hare And The Tortoise

A corollary to this fable is another version http://www.jobcyclone.com/articles/haretortoise.php related more to business that sees the hare winning, however, the key to this version is “fast and consistent”. It is rare to find someone that is both fast and consistent without using techniques like Test Driven Development and Continuous Integration which support going as fast as you can as consistently as you can.

If you want to win the race you should start with TDD and CI.

Coding Secret …

Saturday, July 31st, 2010

 I’m sitting at a cafe at 8am sipping a nice coffee while I write this. You may not find this very exciting but for me is it quite out of the ordinary as I usually spend this time with my wife and twin sons. Would you find it exciting if I was to tell you that I would reveal a single little thing you can do to your code that will improve it for you and for everyone else that uses it?

With the one piece of advice I’m going to tell you how to reduce the amount of code you write so you can keep your code dry’er , do things quicker because you are doing less, and make  your code more readable and a better match for your domain. Does this sound too good to be true?

The advice is to never use a primitive collection as a domain object. To be clear this advice also means that a primitive collection cannot be exposed outside of the containing Class.

What I usually see in code is the use of a primitive collection to represent a domain model concept or in place of a proper class. I guess this is usually done because it is thought to save time or that this is what these types are for. The code looks like this (in Java for the masses):

List<Account> accounts;

for (Account account : accounts) { do something with account } 

The key point of the advice is the use of “List<Account>” should only appear in the definition of a Class called Accounts. Try this advice and see positive benefits for yourself.

 

After this advice is applied the Accounts class then represents a concrete concept in the domain which was missing before, although it was implied. Accounts can now have methods that represent domain concepts and they will exist in a single place, not scattered or duplicated throughout the code.  Want to know what business happens with a collection of Accounts, just look at Accounts.

 

The advice applies to more than just primitive collections but I thought I would start there as they represent a common usage. The advice can also be applied to less obvious collection types like File. For example, don’t just use a File object but subclass it and name the class to represent what is in the file, giving more meaning to “File” and the things that you want to do with that file.

 

This advice is not just for Java programmers, although most of the code examples around promote this primitive approach. Many non-Java languages like Ruby have great support for collections but these too should not be used in place of a concrete class.

 

When I apply this advice to my own code (in Ruby, Smalltalk and Java) the result is more meaning in the model and less code.  Please give it a try and let me know your experiences.

How To Program: Requirements …

Thursday, March 18th, 2010

 questions

This is the second in a series of posts about how to program, and before I begin I should say that this series is probably more about how to be a Software Developer but I used the tag line ‘How To Program’ to catch the interest of the intended audience, School or University Students.

This post is about what is arguably the most important part of being a Software Developer, Requirements. A good Developer helps solve the problems that the Customer is trying to solve and gives you an experience-based opinion of all the risks along the way so the Customer can make informed choices, and none of this is possible if you don’t know what the Customer wants. After you know what the Customer wants you can then go through a process of getting as close to that as possible. When I say Customer, I mean anyone who interacts with you, as how well you interact with a Customer will shape your work life.

Whole careers are built around obtaining and understanding Customer requirements and I don’t profess to be the best person to provide information on how to get requirements, but I can tell you the techniques I have used with success.

Keep in mind that almost always a Customer will say what they want in terms of a solution they have in mind. For example, the School Teacher Customer may say “I want a web application that allows me to take attendance/roll-call.”, but do they really need a web application? Do they really need to take attendance/roll-call? How would you know, how would they know? Your task is to get to the bottom or most basic needs and problems of the Customer. Maybe they have the right solution in mind, but you won’t know if you don’t know the problems they are trying to solve. Maybe a barcode on each students forehead that is automatically scanned when they walk through the school gates is the solution? To make things more complicated the initial Customer may not be the only Customer and the solution may need to take others into account as well.

Ask “Why?” until you get to what is the root problem or need that is to be addressed. This is usually about five (5) Whys or when the Customer can’t reduce the need any further. Asking “why” needs to be done with tact and sympathy or asking why repeatedly could cause friction and then getting to the real need may become impossible.

Ask “How will having the requirement benefit them?” to find out what is required from another angle, the angle of satisfaction. This will help you understand the scope of the requirement and possibly the quality required in the solution. Sometimes finding out the benefit the Customer perceives they will get from a requirement can also bring out the real requirement or need. For example, a Customer who wants a faster Web Site might actually want a faster graphics card or faster Internet connection. The other advantage of asking how the Customer will be benefit from the requirement is that it can also bring out that the Customer isn’t the actual Customer for the requirement, in which case you need to find the other Customer. For example, we had the School Teacher who wanted a Web Application to take attendance/roll-call but it probably didn’t benefit them directly but is required as part of the process the School follows. So maybe the School Teacher isn’t the Customer, but the School Administrators?

I’m probably going to be a little controversial with this next statement, but it is something I feel strongly about and have had success by maintaining. If you can’t find a Customer who needs the requirement then it shouldn’t be a requirement. Every requirement should have a Customer who needs it and can define the satisfaction criteria for the requirement. You may have to look hard to find them but you know you have found them when you can say that requirement X benefits Customer Y directly because of Z.

In summary:

Ask why to uncover the real need or problem.

Identify the benefit(s) of meeting the requirement.

I recommend reading Jonathan Babcocks Blog http://practicalanalyst.com/ and Liz Keogh’s Blog http://lizkeogh.com/ for informative insights into Requirements.

The next instalment is Analysis.