Archive for September, 2008
Using java.util.Date safely
Assuming that you are unable to use Joda Time on your project, there are some simple ways that I have come across that allow you to not suffer at the hands of java.util.Date.
What’s wrong with java.util.date in the first place?
First of all java.util.date is mutable. This means that if you create a java.util.date object its state can be modified after creation.
This means that you can do an operation like the following, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import java.util.Date; import java.util.Calendar; public class DateTest { public static void main(String[] args) { Date aDate = createDate(1, 0, 2008); System.out.println(aDate); aDate.setTime(createDate(1, 0, 2009).getTime()); System.out.println(aDate); } private static Date createDate(int date, int month, int year) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.DATE, date); calendar.set(Calendar.MONTH, month); calendar.set(Calendar.YEAR, year); return new Date(calendar.getTimeInMillis()); } } |
Ignoring the horridness of the zero based month on Calendar, the output of the above piece of code (when I ran it) is as follows.
Tue Jan 01 23:41:50 GMT 2008 Thu Jan 01 23:41:50 GMT 2009
The ‘aDate’ object has actually had its value changed by this piece of code. Clearly this means that we have to be careful how we handle uses of java.util.Date in our code to ensure unexpected things don’t happen.
The problems java.util.Date can cause
Often when looking at code we will notice dates being returned via a getter from a class:
1 2 3 4 5 6 7 | public class DateTest { private Date aDate; public Date getADate() { return aDate; } } |
Eventually we would like to get to a stage where aDate is encapsulated inside the DateTest class but for now we just want to ensure that clients of DateTest can’t change the value of the ‘aDate’ field in DateTest. Right now this is what will happen if a client changed the value returned by getADate() because ‘aDate’ is a reference type.
If we want to return ‘aDate’ we need to ensure that the value in DateTest cannot be changed by clients of this class. We can do this by returning a copy of the value:
1 2 3 4 5 6 7 | public class DateTest { private Date aDate; public Date getADate() { return new Date(aDate.getTime()); } } |
We have the same problem when setting dates – the reference which you set it to will still be changeable from outside the class.
e.g.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import java.util.Date; import java.util.Calendar; public class DateTest { private Date aDate; public void setADate(Date aDate) { this.aDate = aDate; } public static void main(String[] args) { Date myDate = createDate(1,0,2008); new DateTest().setADate(myDate); } private static Date createDate(int date, int month, int year) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.DATE, date); calendar.set(Calendar.MONTH, month); calendar.set(Calendar.YEAR, year); return new Date(calendar.getTimeInMillis()); } } |
If we change myDate in this scenario the ‘aDate’ field in the DateTest object will also be changed. We can get around this the same way as before by creating a new date with the value passed in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import java.util.Date; public class DateTest { private Date aDate; public void setADate(Date aDate) { this.aDate = new Date(aDate.getTime()); } public static void main(String[] args) { Date myDate = someDate(); new DateTest().setADate(myDate) } } |
Joshua Bloch and Neal Gafter’s Java Puzzlers has more on this topic and other interesting quirks in Java.
Testing file system operations
On my previous project one of the areas that we needed to work out how to test was around interaction with the file system.
The decision that we needed to make was whether we should unit test this type of functionality or whether it could just be covered by a functional test.
To Unit Test
One of the patterns to use when unit testing things like this is the Gateway pattern. To quote Martin Fowler’s Patterns of Enterprise Application Architecture
[A gateway is] An object that encapsulates access to an external system or resource.
Therefore we would define an interface with the file operations that we intended to use in our code.
1 2 3 4 | public interface IFileGateway { bool Exists(string path); } |
We can then mock/stub this out in a unit test and use an implementation of the gateway in the real application.
1 2 3 4 5 6 7 | public class FileGateway : IFileGateway { public bool Exists(string path) { return File.Exists(path); } } |
In this case making the code more testable was remarkably easy. We can test the behaviour of the system without actually having any reliance on the file system which means we can potentially cut time from our test suite.
Additionally we are now shielded from the implementation of how we find out if a file exists. This provides flexibility if in the future files are stored on a cluster rather than a single machine, for example, and we need to have a different implementation of working out if a file exists.
The disadvantage is that we have added another level of abstraction to the system which potentially adds complexity.
To Functional Test/To Not Test
The alternative approach is just to test the operation in a functional test or not bother testing this functionality at all.
We could setup some dummy file locations for our test and then do various tests against these.
This is probably marginally quicker than wrapping the calls to the file system behind an abstraction as suggested above.
The problem is that this gain in speed is lost by the extra time it would take to run our build – we would now probably test more combinations since this bit of functionality is not covered at a lower level.
We are also now tied to the file system for executing this operation so if we need to change this in the future there may now be multiple places where changes need to be made.
The other option of course is to not bother testing this functionality. The logic behind this approach is that we know that File.Exists works because it is part of the .NET framework, why bother testing it?
While this is true, it is the interaction with our system that we are interested in. We are not actually testing an API implementation – we want to know if a file exists or not. How this is worked out is irrelevant to us.
Clearly we get a gain in speed of development if we don’t test things like this – and we can probably make a reasonable attempt at explaining why it’s not necessary. As with most things in software the trade off comes later on when we end up with the same problems we would have in just functional testing.
In Conclusion
I am not a fan of over engineering things for the sake of it and maybe the Gateway pattern approach to making this unit testable would be seen as that.
I don’t believe this is the case. The gains we get from having clearly defined boundaries of where we interact with external resources is invaluable and helps make our code more flexible, maintainable and open to change.
Team Productivity vs Individual Productivity
I’ve been reading Neal Ford’s The Productive Programmer (my review) which is a book all about improving your productivity as an individual developer.
It got me thinking that there are also ways that we can make teams more productive so that they are actually teams and not just a group of individuals who happen to work with each other.
I’ve had the opportunity of working under some great Tech Leads who have helped create an environment where teams can perform to their maximum. I’ve noticed some recurring themes in both those teams.
In his book Neal talks about getting into a state called ‘Flow‘ when programming. This is a state where you are totally focused on what you’re working on and are able to be extremely productive.
When looking at Team Productivity one of the key factors behind how well the team performs is how well the team communicates. There are several ways that we can ensure that this is done effectively.
Team Proximity
It seems obvious but teams operate optimally when they are all working in the same physical space. Whether this be having an area of the office just for the team or using a conference room, communication is at its best when it’s easy to do.
In particular if the desk layout is such that it is easy for people to pair with each other on a problem or ask questions without having to move very far then we have a good setup.
Team Size
We need to keep the size of the team appropriate to the size of the work and the time in which it needs to be completed.
The smaller the team and therefore the smaller the number of lines of communication the more effective a team can be. Of course we need to ensure that we have enough people on the team to complete the work required.
At an extreme we learn from Brook’s Law that adding people to a team probably won’t make it go faster. This is also true when working out the initial size of the team – if the team is too big then the number of lines of communication becomes increasingly big and effective communication becomes difficult.
Safe Environment
Even if you have the other two it won’t matter unless a safe environment can be generated for people in the team to interact.
This means that people can feel free to ask questions to others in the team without being made to feel inferior.
People not communicating properly with each other is one of the biggest reason time is wasted on projects – reinventing solutions to problems that another team member has solved is a complete waste of time.
To given an example – on one project i wanted to work out how to unit test a Windows web service that we had written. I searched Google a bit but couldn’t work it out. Luckily I was able to ask one of my more senior colleagues how to do it and he pointed me towards the Gateway pattern which allowed me to solve the problem straight away.
He didn’t make me feel like I was stupid for not knowing how to solve the problem, but explained some options for how he would solve it and pointed me towards a book where I could read more about the solution.
How do we get the balance?
Individual productivity is defined as reaching the state of Flow in The Productive Programmer. In this state by definition you are working alone and not communicating with other team members. Team productivity on the other hand requires constant communication to make it work.
My colleague Jon Pither describes some of the issues he has noticed with pair programming with regards to this.
Psychologists refer to zone as ‘flow’. Daniel Coleman – author of Emotional Intelligence – describes flow as being “emotional intelligence at its best… the ultimate in harnessing the emotions in the service of performance and learning”.
…
Pair programming is a not stress free activity…Being in a “pair” you are constantly required to explain your intricate thought processes to another person.
…
We need to appreciate that developers are humans, and sadly are not perfect coding punching-out machines. Pair-programming introduces an emotional burden on the developer.
While I agree with Jon that pair programming is a completely different proposition to working alone, I’m not as qualified as him to comment as I’ve spent most of my professional life pair programming.
Certainly within an agile team there will be tasks which can be done individually and maybe these are the times individuals can use to achieve the fulfillment that being in a state of flow provides.
In terms of pure productivity I wonder whether there is such a thing as Pair Flow or Team Flow which would describe the state where a pair or team is working in an optimal state.
There needs to be a balance between a pair actually getting things done but also providing help to other pairs when the need arises.
I have noticed that one way this works fairly successfully is that if another pair needs help then only one person in the pair goes to help while the other can continue working. Although you lose the benefit of having both people at the keyboard since it’s only for a short period of time I think it’s acceptable.
For me personally I find it more enjoyable to work with others all the time even though I may not get into the state of flow although I appreciate that others may have different opinions on this matter.
What makes a good developer?
Early last year I became very curious about what it was that made the best developers in the industry so good at what they do.
Jay Fields points out some things that he believes indicate that a developer is good at the end of this post but a former colleague and I tried to come up with a list of areas that any Developer needed to be skilled in to justifiably consider themselves good.
This is not an exhaustive list but it was just some ideas we brainstormed and I’ve expanded on them a bit.
Languages and Tools
The first skill any developer needs to have is an ability to work with programming languages and the main tools that are used with them. These could include build tools, IDEs, web frameworks, messaging APIs.
Although Martin Fowler talks about how he prefers design skills over language skills, I think it is important that you do have a good level of knowledge of at least one language.
These skills can best be acquired through practice, learning APIs, playing around with different frameworks etc. There are also infinite books available which go through the features of different languages which I won’t list here.
In a Java development environment you might need skills in some of the following, for example:
Clearly the more languages and tools you are familiar with the more useful you become on any team you’re on. Knowledge of different types of languages (e.g. static/dynamic/functional) can help bring different points of view in understanding how to solve problems.
Programming Paradigm
This concerns the design skills which Martin talks about. Martin covers it in much more detail, but one area this would cover is having a good understanding of object orientation which is vital for writing maintainable code with imperative languages.
An understanding of ways to approach different problems you might encounter in enterprise development by knowing different patterns and when to apply them is also useful.
The following books would make good reading in this area:
- Agile Software Development Principles, Patterns and Practices – Robert Martin
- Clean Code – Robert Martin
- Code Complete – Steve McConnell
- Design Patterns – Gang of Four
- Head First Design Patterns – Kathy Sierra & Co
- Enterprise Integration Patterns – Gregor Hohpe, Bobby Woolf
- Object Design: Roles, Responsibilities and Collaborations – Rebecca Wirfs Brock, Alan McKean
- Patterns of Enterprise Application Architecture – Martin Fowler
- Refactoring – Martin Fowler
- Refactoring to Patterns – Joshua Kerievsky
- The Pragmatic Programmer – Andrew Hunt, Dave Thomas
- Working with Legacy Code – Michael Feathers
Domain Specific Knowledge
Specific knowledge about the domain (e.g. Investment Banking) is vital for writing a system which is closely linked to the problems it is trying to solve.
Although a lot of this knowledge is acquired by the Business Analyst on the project if Developers can gain it too then conversations with users will be much easier to deal with as amongst other things the terminology they use will make sense.
Beyond this it is useful to understand the goals the business people have, the processes they use to achieve those goals. An understanding of the history of their business so you can see where their industry is going and why is useful for context.
Some domain knowledge can be gained by reading books – this is especially true once you start reading the books that practitioners are reading – but a lot of the knowledge can only be learned by speaking to or watching people who do that job for a living. For example I found out that Options, Futures and Other Derivatives is a very popular book in the investment banking world from my time working in that environment.
Eric Evans’ Domain Driven Design details a way of writing code specific to the domain that you’re working in. Specific domain related books are probably best located with an Amazon search.
With regards to learning domains, the approaches one can take vary from focusing very heavily on one domain and learning it inside out to getting an understanding of a broad set of different domains.
People Skills
One of the most important skills in software development is the ability to work effectively with other people – fellow developers, Quality/Business Analysts, clients, users, the list is endless. If you can do this effectively then you go a long way to ensuring your success.
All the skills of Emotional Intelligence as Daniel Goleman has termed it.
Some useful reading around this area:
Problem Solving
The ability to solve problems that don’t have an obvious solution is key in software. Coding wise it could be debugging a class-path issue when deploying your application to JBoss or finding a tricky bug that a test reveals.
I found Debugging: The Nine Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems to be very useful reading around this area as it helps to keep you honest when solving coding problems and not over thinking the problem.
The best problem solvers logically go through the problem logically using small steps, investigating potential causes until they solve the problem.
Personal Management
The art of managing your time effectively, prioritising your work correctly and keeping focus on what’s important. GTD is a famous book in this area although I think it comes down to experience and understanding the way to best exploit the way that you work.
Communication
This links to people skills but includes written communication, how you transmit ideas and your ability to persuade people.
These skills come in very useful when taking part in exercises such as pair programming for example.
I have read a lot of information around Neuro Linguistic Programming (NLP) in this area – Introducing NLP is a useful book to start with on this subject. NLP amongst other things is a gathering of techniques which effective communicators have been seen to use. NLP Weekly is a useful online resource.
Gaps
Acknowledging when the facts don’t match your theory and keeping room for possiblity. In other words approaching things with an open mind, keen to learn other approaches to solving problems.
Go Meta
The ability to learn how to learn – the skill of skill acquisition – as well as knowing which skills to learn next and which to abandon.
Andy Hunt’s Pragmatic Thinking and Learning strikes me as a book which covers most of these things. It has only recently come out but I will review it when I get my copy.
–
There are bound to be things I haven’t considered for this list. I would like to hear other ideas. My underlying desire is to hear the skills that people are developing to make themselves a better software developer.
Construx have the idea of a Professional Development Ladder but I think you need to be a member to see a proper version of it.
Clean Code: Book Review
The Book
Clean Code by Robert ‘Uncle Bob’ Martin
The Review
I first heard of Uncle Bob a couple of years ago in a conversation with Obie Fernandez and having previously read his Agile Principles, Patterns and Practices in C# book, when my colleague Alexandre Martins came back from JAOO Sydney raving about a talk on ‘Clean Code’ he’d seen I knew I had to buy this book when it came out.
In a good trend which I’ve noticed in a lot of Martin Fowler books, Uncle Bob lays out in the opening chapter how he thinks the book can best be read. Uncle Bob suggested that it was necessary to really immerse yourself in the code presented to get the most value from the book, I think I got a lot more from reading the book this way rather than just skim reading as I often tend to do.
What I learned
- The best idea in this book for me was the newspaper metaphor that is mentioned with regards to formatting your code. This describes the idea of making code read like a newspaper article. We should be able to get a general idea of how it works near the top of the class before reading more and more details further down. This can be achieved by breaking the code out into lots of small methods. It was strange how involved I got with the newspaper metaphor. Having read about it early on I started looking at all code after that to be in that format and when it wasn’t (when showing examples of not such clean code) I became disappointed.
- Learning Tests – the idea of writing tests to gain understanding of how a 3rd party code works – was an idea I had not come across before. The idea here is to write simple tests which describe the way that you think a 3rd party library works for example. If a new version of the library is released we can rerun these to check that it still works the same way. Previously I have always written throwaway pieces of code to gain this understanding but writing tests that we can later refer back to is a much better way of achieving the same aim.
-
Treating the test code as being as important as the actual code was another idea that came across. Writing expressive tests is something that I am very interested in, and my colleague Phillip Calcado has written about the idea of Domain Driven Tests. Uncle Bob mentions a similar idea which he refers to as a Domain Specific Testing Language – a set of functions and utilities to help derive a testing API. The same ideas about keeping the tests expressive and clutter free apply. To end on a quote which is oh so true
If you let the tests rot, then the code will rot too
- I came out with an improved understanding of how the Open Closed Principle, Single Responsibility Principle and Law of Demeter can be adhered to in a code base. The examples used in the book are very like code I have seen on projects so it was much easier to relate to. I found the context they were presented in in this book made them much easier to understand as it was part of a bigger picture of writing clean objects rather than just addressing the ideas in a standalone fashion.
- One of my favourite quotes from the book is the following
Master programmers think of systems as stories to be told rather than programs to be written
This almost requires a paradigm shift and makes it unacceptable to write code that isn’t expressive. I am far from being a Master programmer but if I can write code that is easy for other people to understand then I feel I’m starting to get somewhere.
I also found the following statement revealing as I was under the assumption that experienced developers wrote code like this first time
When I write functions they come out long and complicated…then I massage and refine that code, splitting out functions, changing names and eliminating duplication…all the whole keeping the tests passing.
-
I really liked the approach used in the case studies used in the last three chapters of the book. The code was presented, the problem with it identified, a solution proposed (and it’s name referenced) and then the implementation was detailed. It reminded me of the approach taken in Joshua Kerievsky’s Refactoring to Patterns in its pragmatic approach to aiding learning.
I found it useful to refer to Chapter 17 ‘Smells and Heuristics’ when reading the case studies to check exactly what the smell/heuristic was describing. A reference (e.g. G30) is given in brackets after the paragraph which describes how to improve the code.
In summary
This is the best book I’ve ever read about writing good code. On multiple occasions I found myself wishing I could be on the same team as Uncle Bob to watch him carry out code improvements for real.
The key ideas that stand out for me are keeping your code simple and expressive – the code should do pretty much what you’d expect it to do so that when you (or anyone else) come back to read this can be done quickly and easily.
I would recommend reading this book before reading Agile Principles, Patterns and Practices as I found the examples used in this book to explain OO principles much easier to follow. You can then go into more detail on the theory in the other book.
I read this book while I was on holiday and not really looking at any real code. I think reading the book while working on a project would probably be even more valuable. I will certainly be referencing it frequently when I get back to the code.
Alt.NET UK Conference 2.0
I spent most of yesterday at the 2nd Alt.NET UK conference at Conway Hall in London.
First of all kudos to Ian Cooper, Alan Dean and Ben Hall for arranging it. There seemed to be a lot more people around than for the one in February which no doubt took a lot of arranging.
It was again run using the open spaces format and we started with an interesting discussion on what Alt.NET actually is. There’s been quite a bit of discussion in the blogosphere and everyone seemed to have a slightly different opinion – for me it’s a group of people who are interested in improving how they work in .NET. Ian Cooper pointed out the Foundations of Programming e-book as something concrete which has been released regarding what Alt.NET actually is.
The day was again split into four streams – I stuck to the more general software development oriented discussions.
Agile
This session focused on agile estimation session techniques. Mike Cohn’s book is probably the best known reading in this area.
Ian Cooper raised an interesting idea around the discussion of estimates – he suggested getting the person with the highest and lowest estimates to explain why they had given that estimate to help bring out the different assumptions that people were making regarding the story.
He also spoke about his use of Alistair Cockburn’s Crystal methodology which advocates a 3 phase approach to development whereby you start with the skeleton of the system early on and gradually fill it out in future iterations. I have read a little bit of the book but never used it myself so it was interesting to hear a practical experience.
The idea of only releasing software when it is actually needed rather than at frequent 2 week intervals regardless was also raised but from what I’ve seen on my projects when there are releases it is because the software is needed by the users. I think this is more a case of pragmatically using the methodology rather than sticking to precise rules.
Acceptance Testing
A lot of the focus in this session was around how we can improve the communication between BAs, QAs and Developers when it comes to writing acceptance criteria.
Gojko Adzic suggested the idea of having an Acceptance Testing 3-Some before a story is played so that these tests can be written with all opinions taken into account. The idea here was that the tests written would be more accurate and hopefully reduce the problem of having to go back and change them later on.
While this idea seems good I am more of the opinion that we should just go with the acceptance tests that the QA writes, implement those, then check with the business whether everything is covered. The feedback loop in this approach is much shorter and as the key to software development for me is getting frequent feedback I prefer this approach. This is certainly the way we have done things on the ThoughtWorks projects I’ve been a part of. Requirements by Collaboration was pointed out as being a good book to read with regards to getting everyone involved in the process.
The idea of having a ubiquitous language that everyone in the team used to describe acceptance tests was another good idea that came out of discussions – although I think if a team is developing software using a Domain Driven approach then this is likely to happen anyway.
A large part of the session focused on UI tests and the problems people experienced with regards to brittleness and long running time. One way to get around this is clearly not to have so many tests at this level – one idea was to only have automated UI level tests for critical scenarios e.g. logging into the system and then manual test other scenarios.
One way we have got around this on the projects I’ve worked on is by having a level of tests one level down which test component interaction separate from the UI – typically called functional tests. These could be used to test things such as NHibernate logic rather than doing this through the UI. We would also look to keep minimal logic in the presentation layer as this is the most difficult part of systems to get automated tests around.
TextTest was mentioned as being an acceptance testing tool which tested the system by going through the log files. This has the added benefit of forcing you to write more useful logging code. Green Pepper was also mentioned as a useful way of using acceptance tests which link together Jira and Confluence.
Domain Driven Design
The discussion (perhaps not surprisingly) focused on the concepts described in Eric Evans’ book.
The value of having rich domain objects with the business logic inside was questioned with Ian Cooper pointing out that business logic need not necessarily be business rules but could also describe the way that we traverse the object graph. In particular the Law of Demeter was discussed as a way of avoiding an anaemic domain model.
The problem of designing from the database upwards resulting in these anaemic objects was raised – one potential solution being driving the design from acceptance tests i.e. top down.
Ian Cooper pointed out that coding in a Domain Driven way with lots of plain C# objects made testing much easier. I think in general keeping the behaviour and data together in an object makes it easy to test. Doing this using a Domain Driven approach just makes it even easier to use the code as a communication mechanism.
There was also discussion around the use of Data Transfer Objects, with the general consensus being that using DTOs was good around the UI to save you having to deal with incomplete domain objects around these areas.
The idea of the UI being outside the bounded context that our domain model is used in was also suggested which strikes me as a good idea – would be good to see it done in practice though.
It was suggested that DDD is only useful in complex domains. I think this is true to an extent but some some of the ideas of DDD are just good software development principles such as having a common/ubiquitous language in the team. Ideas such as bounded context are clearly only necessary when there is a greater level of complexity.
I would certainly recommend picking up a copy of the book – 90% of what was discussed is in there.
Developer Education
This was the most interactive session I attended and the majority of the people in the room were able to offer their opinions which I thought was much more aligned with the spirit of the open spaces format.
The discussion focused on how the environment that you’re working in influences your enthusiasm for learning new technologies and new ways of doing things. I am lucky in that working for ThoughtWorks I have colleagues who are very enthusiastic about technology and encouraging other people to learn.
The Ruby community was pointed out as one where there appears to be much more enthusiasm than there is in the .NET world. I’m not sure how exactly we can measure this but blogging wise the Ruby guys definitely have the edge. I think some of this can be explained that people who ran with Ruby early on are massive technology enthusiasts and you’re unlikely to start working with Ruby because you have to – it normally starts out for the love of the language from my experience.
A suggestion was made that holding Brown Bag sessions at lunch time where people could share their learnings with colleagues was a good way of helping to share knowledge. This is certainly an idea that we use frequently at ThoughtWorks and there is actually even more value in the conversations which come afterwards.
The Google idea of 20 % time to dedicate to your own learning was raised as being ideal, although it was pointed out that this was a hard thing to implement as getting things done always takes precedence.
Overall
It was an interesting day and it’s always good to hear the experiences of other people outside of ThoughtWorks.
I think we need to try and find a way that more people can get involved because most of the sessions I attended were very dominated by a few people who had great knowledge on the subject. While it is no doubt very useful to hear their opinions I think it would be even better if more people could get to speak.
Configurable Builds: One configuration file per machine
I’ve covered some of the ways that I’ve seen for making builds configurable in previous posts:
One which I haven’t covered which my colleagues Gil Peeters and Jim Barritt have pointed out is having a build with one configuration file for each machine.
Again the setup is fairly similar to one configuration per user or environment. Using Nant we would have the following near the top of the build file:
<property name="machine.name" value="${environment::get-machine-name()}" />
<include buildfile="${trunk.dir}\config\${machine.name}.properties.xml" />We could then have one configuration for each developer machine:
machine1.properties.xml
<?xml version="1.0" ?> <properties> <property name="property1" value="onevalue" /> </properties>
machine2.properties.xml
<?xml version="1.0" ?> <properties> <property name="property1" value="anothervalue" /> </properties>
The build file can be run using the following command:
nant -buildfile:build-file.build target-name
The benefit of this approach can be seen (as Gil points out) in pair programming where the settings on any one machine will always be the same regardless of who is logged in. We also still get the advantage of being able to use remote resources on developer machines.
Having machine specific configuration also allows more flexibility for configurations on continuous integration for example. To quote Gil:
Each CI build (multiple builds per build server) get’s it’s own [configuration] based on the build host and build name.
The disadvantage again is we have to add a new configuration file every time we want to run the build on a different machine.
The Productive Programmer: Book Review
The Book
The Productive Programmer by Neal Ford
The Review
I first came across this book when I was browsing Andy Hunt’s Pragmatic Thinking and Learning: Refactor Your Wetware on Amazon. It showed up as one of the related books.
I had expected it to be a more theoretical book than it actually is. It is full of really useful command line tips and ways to use system tools and IDEs more effectively. It only took until page 3 for me to learn something from this book – a short cut for navigating Firefox tabs which I now use all the time. Apple Key + Tab Number (Mac) or Ctrl Key + Tab Number (Windows) takes you to the appropriate tab for those who are intrigued!
The first half of the book (Mechanics) covers general power user tips and tricks for using your machine better while the second half (Practice) is more about ways that you can be more productive as a developer.
I will summarise some of my favourite parts of the book and the most interesting things that I learnt from reading it.
Mechanics
- I have often wanted to learn how to use the Unix command line properly – I know how to do basic operations but nothing spectacular – but I found it difficult to work out how to make full use of it short of pairing with an expert. Having read this book I have learnt some excellent tips that I wouldn’t have come across otherwise.
- The idea of shims – little pieces of code that you can write to solve small problems – is the standout idea in this book for me. I often find myself repeating the same boring manual steps without even considering that there could be a better way. This book completely changed the way I think about these types of tasks.
- I thought I had a pretty good idea how to use a lot of the tools on the Mac but Neal shows so many different ways that you can improve your effectiveness with them. The book lists innovative ways to make use of QuickSilver, the Clipboard and Shell and also includes links in the footnotes to applications referenced in the text. This is something I haven’t seen done in a book before but it’s a really good idea as far as I’m concerned.
Practice
- Neal explains how to use open classes in Ruby when creating fluent interface DSLs and finally I now finally understand why extension methods have been introduced into C#. When there are code samples these are annotated and then explained in detail. This certainly made it easier for me to follow some of the examples around using the Unix shell and Ruby.
- Neal reminds you of things that you probably know but need reiterating. The ‘angry monkeys’ story is a particular stand out with regards to this. This covers the idea of always challenging why things are being done a certain way and not accepting ‘because this is how it’s always done’ as an acceptable answer. There is an interesting example used with regards to using underscores in test names as suggested here.
- The chapter on Composed Method and SLAP (Single Level of Abstraction) when writing code was especially good – I knew of the concept but I didn’t know there was a pattern named after it. My reading around this led me to an interesting post on the Arrow Head anti pattern – this is what the code can end up looking like if you don’t keep to one level of abstraction.
I found that the best way to read this book was to read a bit of it and then try out the suggestions on the computer. It’s not really a book that you can read on the train for example.
In Summary
I would rank this book up there with The Pragmatic Programmer as one that I would recommend all developers read. There are so many tips in it that you are bound to find some that you didn’t know about and your view of automation will be much broader having read it, which can only be a good thing.
I was an automation junkie after reading The Pragmatic Programmer, but after reading this book I think I’m going to become even more obsessive about it.
—
As a side note this is the first time I’ve tried to write a review of a book on the blog. Feedback on whether doing it like this is useful or better ways that you’ve seen it done would be gratefully received.
BDD style unit test names
A couple of my colleagues have been posting about how to name your unit tests based on this original post by Jay Fields.
I think that test names are useful, especially when written in a BDD style expressing what a test is supposed to be doing.
For example, in a C# NUnit test we might see the following as a test name:
[Test] public void ShouldDoSomething() { // Code testing that we're doing something }
I write all my tests like this and I’m often asked what the point of the ‘Should’ is, why not just name it ‘DoSomething’.
For me although it’s a subtle change it influences the way that people look at the test. They can look at the test in a much more critical way.
In the above example someone can look at the test name ‘ShouldDoSomething’ and then think ‘Actually no, it should be doing something else.’ The test name and the test contents can then be changed to fit this new understanding of the test.
I’m with Chris Johnston who says the following when it comes to naming tests:
One habit that I picked up on my last project was naming a test after I had written it. While creating the unit test, I would simply name it foo(). Then, once I saw what the code was actually doing, I would go back and rename the test to something appropriate.
Ideally I want to name the test properly before I write it but sometimes it becomes clear to me exactly what the name should be as I’m writing the test.
If I’m in this situation I usually just name the test ‘ShouldDoSomething’ and then by the time I’ve written it I know what it should actually be doing and I can go back and rename it.
In terms of the general argument over whether we should even have test names, I have only really coded tests in Java and C# so I’m not in a position to comment on whether using a language like Ruby means that they aren’t necessary.
For me the test name provides the intention of what you are trying to do, and I like to skim the list of tests in a class – by using Ctrl – F12 and then typing in ‘Should’ to filter the method list in Resharper – so that I can see at a high level what is supposed to be happening in that test fixture.
In the world of IntelliJ there is also a nice plugin called TestDox which allows you to get a list of your tests nicely indented with spaces.
The Wisdom of Crowds and groupthink in Agile Software Development
Gojko Adzic posted a summary of a talk James Surowiecki gave at Agile 2008 and it got me thinking how we use the Wisdom of Crowds in Agile projects.
One of the most interesting things I learnt from the book is that when you bring together a diverse group of people, their output will probably be better than any one expert. Gojko points out this example that was used at Agile 2008:
The organisers of Agile 2008 conducted a similar experiment, asking conference attendees to estimate the number of lines of code in Visual Studio. The average value of all guesses was 47 million and the actual number is 43.3 million of code. The interesting thing as well is that only two people guessed better than the group average.
There are a couple of areas of agile where I have seen how The Wisdom of Crowds can become groupthink if we’re not careful:
Agile Estimation Sessions
Agile estimation sessions are where the estimates for how long pieces of work will take are calculated.
The way these are typically conducted is the Business Analyst will explain the story to the team of Developers who will then all independently come up with their estimate of how long they think it will take to implement the story. They then ‘throw down’ their estimate in a rock-paper-scissors style approach.
The idea is then to take the most popular score suggested. If there is a difference in estimates then a discussion will ensue. It is often the case that the understanding of what is required to complete a story is different or different assumptions have been made as to the difficulty.
The value of having a group of people having input into a decision is most obvious when they are coming from different points of view i.e. they have diverse points of view.
Therefore the input of a new team member in these estimation sessions should in fact be vital for coming up with a better estimate. Often I see new members of teams choosing not to take part in these sessions which I think is a shame as their input could be very valuable as they will provide an angle on things that others may not have considered.
Speaking generally, a lot of developers think in a very similar way to each other so you actually end up with them giving similar estimates most of the time.
Retrospectives
Retrospectives are where the team gets together to discuss the project, how things are going, and areas where improvements can be made.
The first part of these sessions involves team members putting up on a white board things that have gone well, not gone well, and things that are confusing them to describe one particular retrospective technique.
As long as the safety of the group is fairly high then we can have a reasonable level of confidence that all issues are going to be brought up at some stage.
It is possible even with a perceived good safety level that team members can feel intimidated by others and they don’t want to cause conflict by bringing up issues which will do so.
The voting system used to decide which topics should be discussed after the initial issues have been identified favours a team consensus. There might be an issue which should be discussed for the benefit of the team but if the majority decide it’s not an issue then it may be left out.
The problem of having a lot of people who think in the same way on a team is again raised.
So what can we do instead?
In both agile estimation sessions and retrospectives the most value is gained from these sessions when the opinion of the group is better than any one individual. As I’ve suggested, however, there may be times when this is not the case.
Gojko suggests an interesting way to overcome this:
An immediate thing that comes to mind is to build teams out of people with different opinions. Have people on the team that think differently, use different tools and approach the problems from a different angle. This will help the team spot blind spots easier and avoid the echo effect, increasing the team collective intelligence.
While this is a good idea I think it is very difficult to implement in reality. It does suggest a very different model around team creation than is currently considered good practice.
When we form teams the emphasis is often on creating teams with the greatest skill around working with a particular language for example. Gojko’s suggestion would involve creating a mixed team of Developers with different language specialisations for example. It would be obvious to see how someone coming from a Ruby background could bring a whole different perspective onto a Java project for example.
Assuming that we can’t actually design our teams in this way we can still stay aware of groupthink and how we can avoid it.
In retrospectives we should do whatever is necessary to ensure there is an environment where everyone in the group can express their opinions. One easy way this can be done is to have an outsider facilitate the retrospective – this removes the possibility of an influential team member guiding a retrospective to fit their agenda.
In terms of estimation sessions we should always look to get assumptions out on the table for story cards and never dismiss the estimates of any one person. Using ideas such as pair programming to spread knowledge of a system more quickly is also useful for quickly helping provide team members with more context when making their estimates. There is much more on other techniques of agile estimation on Jay Field’s article here.
I’m sure there are other ideas around these areas for making better use of The Wisdom of Crowds so it would be interesting to hear what you think.