Monday, January 21, 2008

Project Kit List



Essential Items for Software Projects


A recent conversation with a friend made me realise that things I have come to think of as standard practice for software projects are by no means universal and that problems I had thought not relevant any more are still around and causing mayhem and chaos around the world for developers and managers alike.


So casting caution to the wind I thought I would draw up a list of things I find essential for a project



  • Version Control

  • Build server

  • Wiki

  • Issue tracking

  • Text Editor



Version Control


It is difficult to understand why any project would not use version control. No decision is final and no PC or server is 100% reliable. At the very least Version Control is a personal safety net for things that can and will go wrong


I like to take things a little further and make version control the only way of communicating changes to the build server. This ensures that everything is under version control and that those little change that I will remember forever (hah) are written down somewhere. (The build server config should also be in version control - makes rebuilding a build server a breeze)


My personal preference is subversion. Its free, open source and works really really well. If you are using a version control system with features not supported by subversion think seriously about whether you really need those features. No really many version control systems have features that promote complex processes and practices that can really get in the way.



Build Server


My second essential item of kit is a build server. Hardware is now so inexpensive that there are few excuses for not having one of these


If you cannot afford an additional server or it is not practical (on the road with a laptop perhaps) then invest in a good virtualisation system had run your build server on the same hardware or one of the dev boxes if you are working in a team.



Wiki


If you are working in a team or even by yourself using a wiki to record things as the project goes along is great. Especially if your memory is anything like mine. Wikis are especially useful if you need to share information about the project or team with people out of your office.


Wiki's such as track also have a bug tracking system built in and integrate with a subversion version control



Issue Tracking


As your code base matures you are going to need something to keep track of the problems and changes that people want.


Don't go overboard. Putting too much reliance on an issue tracking system is that same as code generators and wizards in your ide - they stop you thinking about the problem and generate a lot of noise


Having said that I am a great fan of code generators :)




Text Editor


Ok so why put a text editor in the same rankings as version control wikis and such?


I am with the Pragmatic Programmers on this one. Having a good text editor to call upon is essential. By good I mean it fits your work, you and the things you need do do. But like all good tools you need to spend time with it learning what it is good at. My personal choices are TextMate on the Mac and Emacs just about everywhere.




Best Practice


Ok now the preachy bit. But as with tools make sure you need the practice before you use it. I have seen project adopt practices because they have seen them work well on other projects without considering the impact or relevance to the current project. Having said that some things really are universal.



Build servers and pipelines


I have talked a bit about having a build server. If you hav'nt got one look into getting one.


If you have one then there are some additional things you should consider.



  • Everything on the server came through version control. Ok maybe everything is a bit steep. Your going to need an OS, runtime and build software and other stuff that is just not practical to put through version control. But perhaps scripting the intallation and putting that script in version control would work. It would certainly make it easier to set up another build box.

  • Everything going to production comes from a build server. Yep no more quick file deployes and patches from dev boxes. If it is important enough to put through testing it is important enough to have traceability through the build.



In some situations one build server is not enough. Perhaps you are maintaining multiple versions of the application or there are complex integration points that are tested as part of a different build. (It is often useful to have a fast developer build to provide rapid feedback to the developers and then a longer integration build that makes sure the application works in its intended envioronment.)



Integration builds


Having mentioned Integraion builds I had better expand on what I mean by integration builds and integration as a concept


Integration and Continuous Integration (CI) (as part of build systems such as CruiseControl CruiseControl.net etc) are talked about a lot but what does this mean in practice and how best to make use of these tools.


The word integration and continuous integration covers a lot of concepts. Perhpas the first level of integration and I believe the original intent for work integration of the changes made by eack developer in the team.



Managing session state in persitent objects







On my current web project, like most web projects, needed a way of managing user session state. We wanted a clean separation from the web tier and a way of managing warnings or annotations to the supplied user data incase the data was not valid.


We decided to store information supplied in a GET or POST request in document objects. These document objects would then be used by the service tiers to perform the requested operation. Each document object was kept simple by only allowing fields/attributes. The documents would be validated by a validator for each document type, the validators using a utiltity class of validations to keep the duplicate code count low. The documents can be presisted for long running user transactions.


Perhaps the best way to illustrate how this works is with an example. Lets assume that we have a request handler for a registration service that takes a map of name/value pairs for the values the user has supplied on the registration form. For simpliity the response and error handling paths have been ignored.







import java.util.Map;

public class RegisterRequestHandler {
private RegistrationService registrationService;

public RegisterRequestHandler(RegistrationService registrationService) {

this.registrationService = registrationService;
}

public void handlePost(Map<String, String> params) {
RegisterDocument document = readDocument(params);

RegisterDocumentValidator validator = new RegisterDocumentValidator();

if (validator.validate(document)) {
registrationService.register(document);
redirectToSuccessfulConfirmation();
} else {
persistDocument(document);
redirectToRegisterPath();
}

}

private void redirectToSuccessfulConfirmation() {
// ...
}

private void persistDocument(RegisterDocument document) {
// ...
}

private void redirectToRegisterPath() {
// ...
}

private RegisterDocument readDocument(Map<String, String> params) {
RegisterDocument registerDocument = new RegisterDocument();
registerDocument.name = new Field(params.get("name"));
registerDocument.password = new Field(params.get("password"));
registerDocument.userName = new Field(params.get("username"));

return registerDocument;
}
}



The handlePost entry point turns the name/value pair of parameters into a registraion document representing the users application for an account. The document is validated and if valid a request for a new account is passed on the appropriate service. If the document is not valid the user is redirected to the registraion application form with any warnings identified int he persisted registrtion document.



The registration document contains the fields we expect from the UI and very simple helper methods.






public class RegisterDocument {
Field userName;
Field password;
Field name;

public boolean hasWarning() {
return userName.hasWarning() || password.hasWarning() || name.hasWarning();
}
}



The field class manages the value and any warnings.







public class Field {
private String value;
private Annotation annotation;

public Field(String value, Annotation annotation) {
this.value = value;
this.annotation = annotation;
}

public Field(String value) {
this(value, Annotation.none);
}

public String getValue() {
return value;
}

public void addWarning(String warning) {
annotation = new Annotation(warning, Annotation.AnnotationType.warning);
}

public boolean hasWarning() {
return annotation.getType() == Annotation.AnnotationType.warning;
}
}



Perhpas choosing the most overloaded name (Annotation) this class models the validators response. Allowing warnings or infomation to be associated with the value. Used to report problems back to the user.






public class Annotation {
enum AnnotationType {
warning, info, none
}

private AnnotationType type;
private String value;

public static Annotation none = new Annotation("", AnnotationType.none);

public Annotation(String value, AnnotationType type) {
this.value = value;
this.type = type;
}


public AnnotationType getType() {
return type;
}
}







public class RegisterDocumentValidator {
public boolean validate(RegisterDocument document) {
if (isEmpty(document.name.getValue())) {
document.name.addWarning("You must supply a name");
}

// ...

return document.hasWarning();
}

private boolean isEmpty(String name) {
return (name == null || name.length() == 0);
}
}



Any services use the documents as parameters. They are decoupled from the UI and can be more easily unit tested.





public interface RegistrationService {
void register(RegisterDocument document);
}









Monday, December 10, 2007

Google Maps and the Sony Ericsson W850i

A friend of mine demoed Google Maps My Location feature on his mobile phone. I had been using google maps for a while so downloaded the latest version - but alas no 'My Location' feature.

Time for a firmware update

Sony have a couple of apps required for the job. The PC Suite contains all the drivers and an update program for the firmware. Installation under VMWare Fusion was seamless. The UI is quite flash but it still took me a couple of goes to realise that the 'C' button the instructions referred to was the Cancel button rather than the 3 button (it was late in the evening).

Once the firmware was updated and GMM installed the location feature got me to within 100m - not bad as I was sitting in a basement flat! The directions feature is fab - working off a postcode the route to work (driving) was pretty good.

As a bonus the software on the phone felt a lot more responsive - although some of the options had move around.

Monday, October 29, 2007

Polygot Programming analogy

I have been following a short email thread at work on Polygot programming (developing applications in more than one language). In its simplest form it is unlikely that an application contains a single language. Most applications involve some sort of XML :)

While reading the thread and a side note on construction I was struck by the thought that one could draw an analogy between a computer language and a construction material.

When putting together a car for example the designers choose materials that are suited to the job at hand. Each material chosen for its properties and application. A car made entirely using a material with a small set of properties (e.g. metal) would at the very least be very uncomfortable (steel tires).

With this thought it mind it is surprising that people continue to maintain the premise that a software application should be written in a single language. At best you get an explosion of code around the areas where the chosen language is not that good. At worst you see huge frameworks to get around the limitations.

Getting different languages to behave nicely together is not easy. Recent developments in leveraging runtime environments (JRuby, IronPython) make this interoperability simpler to manage but the problems rarely go away. The analogy with car manufacture works quite well - it is usually the interfaces between one material and the next where problems turn up.

Pushing the analogy even further it has been some time since carpenters have joined pieces of wood using wooden pegs preferring in the main to use screws. Steel screws are stronger than brass but brass is preferred for wooden boats because it resists the effects of sea water (as well as being more aesthetically pleasing).

Going back to automobile analogy the instrumentation systems use many different materials to delivery the required user interface, whilst the business end (engine) uses a more constrained list of materials (although in recent years this too has been growing). You could consider the instrumentation to be the equivalent of JavaScript on web applications whilst the engine corresponds to the back end systems (just a thought).

Thursday, October 18, 2007

Subversion missing tools

Recently our team source code repository developed a problem. To be fair I don't believe that the problem was with subversion but with a disk fault but the effect was the same - subversion had a problem with one of the revision files.

After talking through the options we thought that we could replay the revisions using the svnadmin dump command and pipe the output into a new repository. Once for all the revisions up to the faulty one and again for those past the problem to HEAD. This did not work the receiving repository did not like having discontinuous build numbers.

I tried various utilities that reported they could fix fsfs format svn databases but non found or fixed the problem.

I ended up copying the previous revision over the faulty one - giving me nightmares about that missing revision. Now time to start digging through the backups for a good version of that file.

If anyone knows of a good tool that can dig into the svn filesystem to allow hand patches of revisions please let me know.

Thursday, October 11, 2007

Starting out with Numbers

I managed to hold out for quite some time (for me some time is past the launch date) before splashing out on a copy of iWork.

I have been using Excel on my Mac but wanted to know if Numbers (part of iWork) gave a fresh perspective on how a spreadsheet should work.

I have to confess I have not spent a lot of time with Numbers yet but so far I have not been disappointed.

Key features that work for me


  • Column and row headers as explicit items but still addressable
  • Inline computation of results as a formula is filled into other columns
  • More intuitive insertion of newlines in cells (got it on the 2nd try)
  • Simple menus and text wrapping as an option on the toolbar
  • Sheets start small and grow as the data grows.
  • Easy import of my existing spreadsheets


It is still early days but so far very pleased :)

Thursday, October 4, 2007

The beauty of small applications

A great colleague of mine just posted an article suggesting the Death of Enterprise applications.

I like the post it has a lot in common with the approach taken on for command line UNIX applications. Each command line app has a well defined responsibility, the OS provides a simple set of capabilities that allow these applications to communicate with one another. Using the applications and the 'glue' provided by the OS users can perform far more complex tasks. Adding in the shell means that applications can be developed just using the existing applications and OS communication.

In the world of web applications Sitemesh provides the glue roughly equivalent to the OS glue provided by the command shell. By developing applications in the progressive enhancement style allows web applications to be glued together to provide a cohesive web experience to the user.

Other benefits



* Each web application is partitioned into its own space. (loose coupling)
* 3rd party applications can be incorporated into the user experience more easily