Mark Needham

Thoughts on Software Development

Archive for the ‘Books’ tag

The Last Lecture – Randy Pausch

without comments

I recently watched Randy Pausch's 'Last Lecture: Achieving Your Childhood Dreams' and read the corresponding book and although it's not directly related to software development I think that some of the points that he makes are really intriguing.

These were some of the parts that particularly stood out for me:

  • Introduce the elephant in the room – whatever it is that people are really thinking about, put it out in the open. I think on development teams there is often a distrust of the way that other people write code because it's different to the way that we do. If we can get this out in the open more frequently and agree on a shared approach then it should result in a more consistent code base.
  • Get the fundamentals down – Pausch suggests that we need to understand the fundamentals because otherwise the fancy stuff isn't going to work. In Apprenticeship Patterns Ade Oshineye and Dave Hoover suggest that we should 'Study the Classics' which is a similar idea.

    While I think they're certainly right I'm not sure that learning theory before putting it into practice is the most effective way to learn. I think we need to do a bit of both at the same time alternating between the two so that we actually have a frame of reference when we're learning the fundamentals.

  • The brick walls are there for a reason – Pausch describes how we'll often come across obstacles stopping or blocking us from what we want to do but that we shouldn't be discouraged, they are there so that we can see how much we really want something. I think this is just generally true and not just related to software development.
  • The skill of self assessment – Pausch suggests that we need know what we don't know which I think is perhaps the best advice in the book. We need to recognise our true abilities but also have a sense of our flaws and create feedback loops to allow this to happen.

    My colleague Liz Douglass has come up with the idea of Feedback Frenzies to help create this feedback loop and this is one of the best ideas I've come across for doing this.

  • One of my favourite quotes from the book is the following which I believe was originally from Dan Stanford:

    Experience is what you get when you didn't get what you wanted

    It's a phrase worth considering at every brick wall we encounter, and at every disappointment. It's also a reminder that failure is not just acceptable, it's often essential.

    I think we can do this much more in the software world. There sometimes seems to be a stigma with identifying things which fail but I think it's really useful for others to learn from mistakes that have been made.

The Last Lecture is one of the best presentations I've had the chance to watch – I'd certainly recommend it.

Written by Mark Needham

January 1st, 2010 at 2:32 pm

Posted in Books

Tagged with

Debug It: Book Review

with one comment

David Agans' 'Debugging' is the best debugging book that I've read so I was intrigued to see that there was another book being written on the subject.

Paul Butcher offered me a copy of the book to review so I was keen to see whether it was more like 'Debugging' or 'Release It' as Ted Neward suggests.

The Book

Debug It by Paul Butcher

The Review

Much like Krzysztof Kozmic I found that a lot of the ideas early on in the book were similar to what I've been taught by my ThoughtWorks colleagues over the last 3 1/2 years.

I do think it's really good seeing these ideas in words though because it's quite easy to forget about the best way to approach problems in the heat of the moment and the approaches suggested by Paul certainly aren't done everywhere in my experience.

These were some of my favourite parts of the book:

  • When chasing a bug Butcher suggests that a useful technique to use is to try and disprove your theory of why the problem has happened. Too often we come up with a theory and just adapt any data to fit our thinking. This is also known as confirmation bias.

    In his talk 'Pimp my architecture' Dan North suggests a similar approach more generally when working out how to tackle any problem. Each person has to take the other person's argument and then fight for that to be used instead. I quite like this idea – certainly something to try out.

  • When discussing the need to refactor code as we go along, the author points out that if the code we want to change doesn't have any tests around it then we need to write some to provide us with a safety net.

    Remember, however, that refactoring crucially depends upon the support of an extensive suite of automated tests. Without tests, you’re not refactoring. You’re hacking.

    Hamlet D'Arcy makes a similar point but perhaps more forcibly in a really good blog post and Michael Feathers' 'Working Effectively With Legacy Code' covers the topic in much more detail.

  • One tip which seems obvious but is still one I've tripped up on many times is to go through the list of changes that we've made before checking in! It's incredibly easy to forget about some seemingly insignificant change that we made before checking it in and perhaps breaking our application unexpectedly.

    Somewhat tied in with this is the idea of checking in small changes more frequently and only changing one thing at a time which I wrote about previously.

  • I like that Butcher puts a lot of emphasis on ensuring that we actually know what's going wrong before we attempt to fix anything.

    Without first understanding the true root cause of the bug, we are outside the realms of software engineering and delving instead into voodoo programming or programming by coincidence.

    This is particularly true when addressing performance problems where he rightly suggests that we should look to profile the code before making a premature optimisation.

    He also suggests using the debugger so that we can get a good idea about what the code is actually doing when it's running. While I think this is useful I feel that the need to use the debugger in this way frequently might suggest that our code is difficult to reason about which could well be something to address.

  • A couple of other cool suggestions are to call on team mates to help us out if we're getting stuck trying to fix a bug and if that's not possible then to either write out the problem or talk to the rubber duck.

    If you don’t have someone to play the role of cardboard cutout, all is not necessarily lost. Try scribbling down a narrative of the problem on paper or perhaps composing an email to a friend. The trick is not to censor yourself — just like a writer would.

    I don't think the importance of communicating with team mates can be underestimated and Butcher points out that if we notice a bad pattern in the code than it's no good just going through and changing it everywhere. We need to talk with the rest of the team to decide whether we can get an agreement on the way we'll develop code going forwards.

  • The only idea I disagreed with is that of putting assertions into the code which I feel adds clutter to our code even though it makes it fail faster than would otherwise be the case. From my experience if we write good enough unit tests and have good logging in our code then the assertions aren't needed.

In Summary

The book is pretty quick to read at around 200 pages and packs a lot of useful tips into that space. I'd say it's a pretty useful book to keep by your desk to refer to now and then.

Written by Mark Needham

December 24th, 2009 at 5:26 am

Posted in Books

Tagged with ,

Fundamentals of Object-Oriented Design in UML: Book Review

with 5 comments

One of my favourite recent blog posts is one written by Sammy Larbi on coupling and cohesion and while discussing it with Phil he suggested that I would probably like this book and in particular the chapter on connascence which I've previously written about.

The Book

Fundamentals of Object-Oriented Design in UML by Meilir Page-Jones

The Review

I really enjoyed reading this book and I think it's one that I could come back and read again to gain something else from in the future.

Nearly all the mistakes that I've made and seen made with respect to the design of object oriented code are outlined in one form or the other in this book.

The book is split into three sections. The first discusses some fairly basic object oriented concepts, the second covers UML as a notation for describing our designs and the final section goes more deeply into the principles of object-oriented design.

What did I learn?

  • Although we don't seem to use UML much these days I was coming to the conclusion while reading those chapters that perhaps UML is useful as a design tool but the aim shouldn't be to come up with a UML diagram, but rather to drive a design in code.

    This is something which Uncle Bob also touched on recently:

    Is TDD a replacement for design?

    No. You still need all your design skills. You still need to know design principles, and design patterns. You should know UML. And, yes, you should create lightweight models of your proposed software designs.

    We actually found on a project I worked on recently that everyone had a different way of diagramming a design and it would have been useful to have a common notation between us. UML is surely the tool to solve that problem.

  • I quite like the way that Page-Jones describes the different types of messages that objects can receive:
    • Informative – a message telling an object about something that happened in the past.
    • Interrogative – a message asking an object to reveal something about itself.
    • Imperative – a message telling an object to take some action on itself.

    An interrogative message is effectively a getter whereas the other two are commands being sent to the object. I've not seen the distinction between events which happened in the past and those which are going to happen in the immediate future.

  • I've frequently come across the idea of information hiding when it comes to designing objects but Page-Jones introduces the idea of implementation hiding which I think is really neat.

    The idea is that while some information about our object will be viewable to other objects e.g. through attributes/getters, we can still hide the implementation of that information internally so that if we we want to change it in the future then we won't have to change all its clients too.

  • I found the concept of the rings of operation really interesting. The idea is that there are some methods on our objects which just make use of other methods on the same object. Those methods wouldn't touch any of the fields of an object directly but would rely on those methods in the inner rings to do so.

    For example if we have a getter on an object to access a field then if other methods on that object want to access that field they should go via the getter instead of accessing the field directly.

    I often find myself avoiding using getters with the hope that if don't increase their usage then it will be easier to get rid of them in the future. This approach would discourage doing that.

  • I like the idea of type conformance when it comes to inheritance – we should try to ensure that any sub types adhere to the contract of their parent.

    The other part of this chapter describes 'closed behaviour' – all the operations on any class that we inherit from should obey our class' invariant.

    I think this can be where we go wrong when we write classes which extend a List for example. The API of a List will typically have 'Add' and "Remove' operations but on a lot of the application I work on we only want the 'Add' functionality and not the 'Remove' option. Page Jones suggests that if we want to use inheritance in this situation then we should override methods on the super class to make 'Remove' do nothing.

  • I now find that I prefer Page Jones definition of cohesion:

    Class cohesion is the measure of interrelatedness of the features (the attributes and operations) located in the external interface of a class

    I'm inclined to believe that we might be able to tell how related the features are by looking at the clients of the class and seeing whether they are all using the class in similar ways.

    He then outlines three signs that we have cohesion problems with a class:

    • Mixed instance cohesion – a class has some features that are undefined for some objects of the class. I find that this typically happens when we try to make a generic data type to cover everything and then try to jam any variations on the type into the same definition. It is typically solved by pulling out another class. This is the worst type of cohesion.
    • Mixed domain cohesion – a class contains an element that directly couples the class with another class that is unrelated domain wise. This typically happens when we mix infrastructure code into our domain code.
    • Mixed role cohesion – a class contains an element that couples it with an unrelated class in the same domain. I think this is the most typical type of cohesion that I've seen and the main problem is that we end up with classes which have multiple roles which makes them difficult to change.

In Summary

There's way more in this book than I could ever hope to cover here but these are some of the interesting bits that stood out from this reading of it. I'm pretty sure that I'll come back to this one in the future.

While reading the book I had the feeling that some of the ideas are quite similar to those in Domain Driven Design and since this book was published it contributes to my belief that a lot of DDD is covered by just doing OOP well.

Overall this is a really good book, worth reading.

Written by Mark Needham

December 1st, 2009 at 11:26 pm

Posted in Books

Tagged with ,

Zen Mind, Beginners Mind: Book Review

with 7 comments

The Book

Zen Mind, Beginner's Mind by Shunryu Suzuki

The Review

I first came across the actual term beginner's mind when reading through the 'Wear The White Belt' chapter of Apprenticeship Patterns although it was often mentioned to me on one of the first projects I did at ThoughtWorks a couple of years ago that people liked teaching me things because I just took the information in pretty much without questioning.

I find nowadays that I analyse what people tell me way a lot more and then compare it against what I already know to see if it adds to my understanding. In a way this is useful but sometimes prevents me fully understanding ideas since I have already judged them.

I started researching beginner's mind a bit to see if there was anything written on the state of mind required to maximise learning and this was the book that kept being mentioned so I decided to get a copy of it.

It is fundamentally a book on Zen and a lot of the stuff around that area didn't make a lot of sense to me but I think there were some general ideas which can be applied to learning in general.

What did I learn?

  • One of the early chapters sets the message for the book with the following quote:

    In the beginner's mind there are many possibilities. In the experts there are few.

    Straight away it gets to the point which I think describes the problem that we have in software development once we've done a few projects and accumulated a set of ideas of the best way to deliver software – we often stick to those ideas and aren't open to the idea of better ideas being out there.

    On the other hand as Fred Brooks points out there is no silver bullet so perhaps this also explains why there is often skepticism when new ideas are described since its quite likely that potential negative points of these approaches have either not been described or not yet discovered.

  • The author raises some interesting ideas around how to get the best out of people by suggesting that the best way to do this is to let them do what they want but to watch them. Although he then went out to reference this back as a metaphor for controlling our own thoughts I was reminded of the Netflix culture slide show which I came across lately in terms of how they give employees freedom but expect them to act in the organisation's best interest rather than expecting employees to follow a lot of rules.
  • One thing I really liked was the emphasis on listening to what someone says 'without having your own idea [in mind]…forgot what you have in your mind and just listen to what he says'. I think one problem we can run into when listening to other people is that we extract the bits of what they say which fit in with what we believe – something known as the confirmation bias.

    I actually found an old post of mine which lists some mistakes we commonly make when listening to others speak. It makes quite interesting reading.

    Another quote from the book sums up a more useful approach:

    See things as they are, observe things as they are, let everything go as it goes

  • He goes on to suggest that we should have no negative or positive feelings towards what someone says to us and that we should give up our preconceived ideas and subjective opinions which I didn't think made much sense in the software development game since a lot of what we do is about assessing the merits of different approaches.

    The beginner's mind entry on the C2 wiki makes more sense by describing Ward Cunningham's approach:

    You can generally tell when you're dealing with someone who really knows their stuff by the amount of reference they make to the way it has always been done. Folk like our own WardCunningham seem able to ditch all that stuff and approach each problem as if it were completely new and they had never done anything like it before.

    Then, when they have a solution, they'll either recognize it as a Pattern in the standard lexicon, and leverage readymade tools, or not. But they never come in armed for bear when all the customer needs to catch is clams.

    It seems like we only initially need to have an empty mind while we are taking in the new information and then we can make use of the knowledge that we already have later on.

  • The author suggests that 'when you do something just to do it should be your purpose' which seems somewhat similar to the idea of focusing on the process in Agile instead of always on the outcome of what we're doing.

    While a result focus can be helpful I often notice that important things like the quality of what we're making get dropped by the wayside if we focus too much just on completion.

    I do think there is some need to focus on whether what we're doing is actually improving us (although the book advises against this) and I recently came across Chad Fowler's idea of always asking 'Am I better than yesterday?'.

  • It is pointed out then when learning zaizen we cannot expect rapid progress but instead that we will progress little by little which I think is pretty much the same in software development.

    With nearly all skills a lot of practice is needed – as Talent is Overrated points out – we don't just become an overnight sensation but need to work our way through the Dreyfus Model for each skill gradually improving our level.

In Summary

Although this book is about Zen I still found some interesting ideas about learning and I guess its always interesting to read something a bit different.

I'd be interested in knowing if there was a book that covered beginner's mind purely from a learning point of view instead of Zen if anyone knows of any titles!

Written by Mark Needham

August 12th, 2009 at 9:06 am

Posted in Books

Tagged with ,

Brownfield Application Development in .NET: Book Review

without comments

The Book

Brownfield Application Development in .NET by Kyle Baley and Donald Belcham

The Review

I asked to be sent this book to review by Manning as I was quite intrigued to see how well it would complement Michael Feather's Working Effectively with Legacy Code, the other book I'm aware of which covers approaches to dealing with non green field applications.

What did I learn?

  • The authors provide a brief description of the two different approaches to unit testing – state based and behaviour based – I'm currently in favour of the latter approach and Martin Fowler has a well known article which covers pretty much anything you'd want to know about this topic area.
  • I really like the section of the book which talks about 'Zero Defect Count', whereby the highest priority should be to fix any defects that are found in work done previously rather than racing ahead onto the next new piece of functionality:

    Developers are geared towards driving to work on, and complete, new features and tasks. The result is that defect resolution subconsciously takes a back seat in a developer’s mind.

    I think this is quite difficult to achieve when the team is getting pressure to complete new features but then again it will take longer to fix defects if we leave them until later since we need to regain the context around them which is more fresh in our mind the earlier we fix them.

  • Another cool idea is that of time boxing efforts at fixing technical debt in the code base – that way we spend a certain amount of time fixing one area and when the time's up we stop. I think this will work well as an approach as often when trying to fix code we can either get into the mindset of not fixing anything at all because it will take too long to do so or ending up shaving the yak in an attempt to fix a particularly problematic area of code.
  • I like the definition of abstraction that the authors give:

    From the perspective of object- oriented programming, it is the method in which we simplify a complex “thing”, like an object, a set of objects, or a set of services.

    I often end up over complicating code in an attempt to create 'abstractions' but by this definition I'm not really abstracting since I'm not simplifying but complicating! This seems like a useful definition to keep in mind when looking to make changes to code.

  • Maintainability of code is something which is seriously undervalued – I think it's very important to write your code in such a way that the next person who works with it can actually understand what's going on. The authors have a fantastic quote from Perl Best Practices:

    Always code as if the guy who ends up maintaining your code is a violent psychopath who knows where you live.

    Writing code that is easy for the next person to understand is much harder than I would expect it to be although on teams which pair programmed frequently I've found the code easier to understand. I recently read a blog post by Jaibeer Malik where he claims that it is harder to read code than to write code which I think is certainly true in some cases.

  • There is a discussion of some of the design patterns and whether or not we should explicitly call out their use in our code, the suggestion being that we should only do so if it makes our intent clearer.
  • While describing out how to refactor some code to loosen its dependencies it's pointed out that when the responsibilities of a class are a bit fuzzy the name of the class will probably be quite fuzzy too – it seems like this would server as quite a useful indicator for refactoring code to the single responsibility principle. The authors also suggest trying not to append the suffix 'Service' to classes since it tends to be a very overloaded term and a lot of the time doesn't add much value to our code.
  • It is constantly pointed out how important it is to do refactoring in small steps so that we don't break the rest of our code and to allow us to get rapid feedback on whether the refactoring is actually working or not. This is something that we've practiced in coding dojos and Kent mentions it as being one of his tools when dealing with code – I've certainly found that the overall time is much less when doing small step refactorings than trying to do everything in one go.

    I'm quite interested in trying out an idea called 'Bowling Scorecards' which my former colleague Bernardo Heynemann wrote about – the idea to have a card which has a certain number of squares, each square reprsenting a task that needs to be done. These are then crossed off as members of the team do them.

  • An interesting point which is made when talking about how to refactor data access code is to try and make sure that we are getting all the data from a single entry point – this is something which I noticed on a recent project where we were cluttering the controller with two calls to different repositories to retrieve some data when it probably could have been encapsulated into a single call.
  • Although they are talking specifically about poor encapsulation in data access layers, I think the following section about this applies to anywhere in our code base where we expose the inner workings of classes by failing to encapsulate properly:

    Poor encapsulation will lead to the code changes requiring what is known as the Shotgun Effect. Instead of being able to make one change, the code will require you to make changes in a number of scattered places, similar to how the pellets of a shotgun hit a target. The cost of performing this type of change quickly becomes prohibitive and you will see developers pushing to not have to make changes where this will occur.

  • The creation of an anti corruption layer to shield us from 3rd party dependency changes is suggested and I think this is absolutely vital otherwise whenever there is a change in the 3rd party code our code breaks all over the place. The authors also adeptly point out:

    The reality is that when you rely on another company's web service, you are ultimately at their mercy. It's the nature of third-party dependencies. You don't have control over them.

    Even if we do recognise that we are completely reliant on a 3rd party service for our model I think there is still a need for an anti corruption layer even if it is very thin to protect us from changes.

    The authors also describe run time and compile time 3rd party dependencies – I think it's preferable if we can have compile time dependencies since this gives us much quicker feedback and this is an approach we used on a recent project I worked on by making use of generated classes to interact with a SOAP service rather than using WCF message attributes which only provided us feedback at runtime.

In Summary

This book starts off with the very basics of any software development project covering things such as version control, continuous integration servers, automated testing and so on but it gets into some quite interesting areas later on which I think are applicable to any project and not necessarily just 'brownfield' ones.

There is a lot of useful advice about making use of abstractions to protect the code against change both from internal and external dependencies and I particularly like the fact that the are code examples showing the progression of the code through each of the refactoring ideas suggested by the authors.

Definitely worth reading although if you've been working on any type of agile projects then you're probably better off skim reading the first half of the book but paying more attention to the second half.

Written by Mark Needham

July 6th, 2009 at 12:43 am

Posted in Books

Tagged with , ,

Book Club: Arguments and Results (James Noble)

without comments

We restarted our book club again last week by reading James Noble's Arguments and Results paper, a paper I came across from a Michael Feathers blog post a few months ago detailing 10 papers that every programmer should read.

We decided to try out the idea of reading papers/individual chapters from books as it allows us to vary the type of stuff we're reading more frequently and is an approach which Obie seems to be having some success with.

This firs half of paper describes some approaches for detailing with complexity in the arguments that we send to methods and the second half approaches for the results that we get back from methods.

We split the different patterns between us and attempted to come up with examples in code we'd worked on where we'd seen each of the patterns in use.

Arguments Object

This pattern is used to simplify a method's signature by grouping up the common arguments and object and changing the method signature to take in this object instead.

The author quotes Alan Perlis as saying "If you have a procedure with 10 parameters you probably missed some" which I think best sums up the reason why you would want to do this refactoring.

Another advantage of doing this, which Cam pointed out, is that it may help to bring out domain concepts which weren't explicit before.

The disadvantage of this approach is that we make it more difficult for clients to use our API. I think this was best summed up in a comment on a post I wrote about using weak or strong APIs by 'Eric':

The choice is between passing (1) what the client probably has on hand already (the pieces) vs. passing (2) what the class demands (a pre-formed object). Which serves the client better and more naturally?

Which brick-and-mortar shop gets more business–the one taking credit cards (already in the customers' hands), or the one demanding cash in some foreign currency (which the customers first have to go get)?

Subordinate the service's convenience to the client's. Accept what a client likely has at the ready. (At the least, offer an overloaded constructor that does so.)

A simple example from some code I worked on recently involved refactoring a few methods similar to this:

public void Process(string streetName, string streetNumber, string state) { }

to:

public void Process(Address address) { }

Some other examples which we thought of were:

  • The way that Ruby makes use of hashmaps to pass data into constructors instead of passing in each option individually to a separate parameter
  • The specification pattern/Query object pattern

Selector Object

This pattern is used to try and reduce the number of similar methods that exist on an object by creating one method which takes in the original object and an additional 'selector object' argument which is used to determine what exactly we do inside the new method.

The author also describes another way of solving this problem which is to build a small inheritance hierarchy and then make use of the double dispatch pattern to determine which specific method needs to be called.

The advantage of this pattern is that it helps to simplify the API of the object as there is now just one method to call to perform that specific operation.

The disadvantage is that the client of this object needs to do more work to use it although again I feel that this patterns helps to draw out domain concepts and move behaviour to the correct places.

I worked on a project where we did something similar to this although I'm not sure if it's exactly the same:

public abstract class OurObject 
{
	public abstract void Configure(Configuration configuration)
}
 
public class ObjectOne : OurObject
{
	public void Configure(Configuration configuration)
	{
		configuration.ConfigureObjectOne(this);
	}
}
 
public class ObjectTwo : OurObject
{
	public void Configure(Configuration configuration)
	{
		configuration.ConfigureObjectTwo(this);
	}
}
public class Configuration
{
	public void ConfigureObjectOne(ObjectOne objectOne)
	{
		// do config stuff
	}	
 
	public void ConfigureObjectTwo(ObjectTwo objectTwo)
	{
		// do config stuff
	}	
	...
}

We felt that possibly the composite pattern might work well especially for the example described in the paper although we didn't come up with any other examples of this pattern on code we'd worked on.

Curried Object

This pattern is used to help simplify the arguments that a client needs to send to an object by simplifying that interface through the use of a 'curried object' which takes care of any values that the object needs which the client doesn't need to worry about (these could be arguments which don't really change for example).

The client now sends its arguments to the 'curried object' which is then sent to the object.

I've come across the idea of currying while playing around with F# and in the functional world it seems to be about composing functions together, each of which only takes in one argument. I'm not sure if the author uses such a strict definition as that.

The advantage of this pattern is that it helps to simplify things for the client of the object although we now add in a level of indirection into the code because we send data to the 'curried object' which is actually executed by another example.

I'm not sure whether it's strictly currying but an example which seemed to fit into this pattern is where we make calls to external services which might require some arguments passed to them that the rest of our application doesn't care about.

We therefore keep this setup inside a 'Gateway' object which the rest of our code interacts with. The 'Gateway' object can then send the external services this data and the data we pass it.

Iterators are suggested as being the most common use of currying in our code as they shield us from the internals of how the data is stored.

Result Object

This pattern is used to allow us to keep the results of potentially expensive operations so that we don't need to make several of these expensive calls to get the data that we want.

The advantage of doing this is that we are able to make out code more efficient although the client needs to do more work to get the data they care about out of the returned object.

An example of this could be if we are making a call across the network to get some data. If there are three pieces of data that we want then it makes more sense to get all this data in one 'result object'
instead of making individual calls for the data.

I think this pattern is also useful in situations where there are multiple outcomes from an operation and we want to signify this in the result we return.

An example of where this might be useful could be if we want to know whether a call was successful or not and if it wasn't then we want details about the way in which it failed. This could easily be modeled in a result object.

I'm not sure whether an Option/Maybe in functional programming could be considered to be a result object – they do return more information than other data types do although this isn't for performance purposes.

Future Object

This pattern is used when we want to perform an expensive operation and do something else while we wait for that operation to return – effectively we want to asynchronously process a result and then probably call a callback when it's done.

This pattern is useful when we want to go and get some data via a network call but we don't want to freeze up the user interface while we're doing that. I think this pattern is probably more applicable for client side applications than on the web where the typical approach I've seen is to block the use from doing anything while an operation is being executed. Perhaps something like Gmail does make use of this pattern though, I'm not sure.

The concurrency aspects should be taken care of by the 'future object' in this pattern meaning that the future object will be more complicated than other code.

F# asynchronous work flows certainly seem to be an example of this pattern whereby we make use of other threads to make network calls or put data into a database before returning results to the main thread when they're done.

Lazy Object

This pattern is used when we want to return a result but we don't know whether or not that method will actually be called – we therefore only get the data when the method is actually called.

The advantage of this is that we don't get data unnecessarily although it can be difficult to debug since we don't know exactly when the data is going to be fetched.

An example of this is Hibernate which by default lazy loads our data. If we later on try to access some data inside an aggregate root then we need to ensure that we have a Hibernate session open so that it is able to go and fetch the data for us.

F# also has a 'lazy' keyword which we can use to create lazy values which are only evaluated when specifically called:

let foo value = 
    printfn "%d" value
    value > 10
 
let fooBar = lazy foo 10    
 
> fooBar.Force();;
10
false

LINQ in C# also makes use of lazy evaluation.

In Summary

I think this is a really interesting paper and it was the first one that caught my eye from briefly skimming through the 10 that Michael Feathers listed.

I found it quite difficult explaining some of the patterns so if anything doesn't make sense or you can think of a better way describing a pattern then please let me know.

Book club wise it was good to get to discuss what I'd read as others always come up with ideas that you hadn't thought of and we had some interesting discussions.

Next time we are reading 'The Readability of Tests' from Steve Freeman and Nat Pryce's upcoming book 'Growing Object Oriented Software, guided by tests'.

Written by Mark Needham

June 16th, 2009 at 11:37 pm

Real World Functional Programming: Book Review

with 2 comments

The Book

Real World Functional Programming by Tomas Petricek with Jon Skeet (corresponding website)

The Review

I decided to read this book after being somewhat inspired to learn more about functional programming after talking with Phil about his experiences learning Clojure. I'm currently working on a .NET project so it seemed to make sense that F# was the language I picked to learn.

What did I learn?

  • I've worked with C# 3.0 since around July 2008 so I had a bit of experience using some of the functional features in C# before picking up this book. I therefore found it very interesting to read about the history of lambda and the different functional languages and how they came into being. Having this as an opening chapter was a nice way to introduce the functional approach to programming.
  • Immutable state is one of the key ideas in functional programming – this reminded me of a Joe Armstrong video I watched last year where he spoke of his reduced need to use a debugger when coding Erlang due to the fact that there was only one place where state could have been set rather than several as is the case with a more imperative approach. We have been trying to code with immutable state in mind in our coding dojos and while it takes a bit more thinking up front, the code is much easier to read when written that way.
  • Separating the operations from the data is important for allowing us to write code that can be parallelised, focusing on what to do to the data rather than how to do it. Sadek Drobi has a nice illustration of what he calls mosquito programming vs functional programming on page 14 of the slides of his QCon presentation. It describes this idea quite nicely.
  • A cool technique that Phil taught me when reading language related books is to have the PDF of the book on one side of the screen and the REPL (in this case F# interactive) on the other side so that you can try out the examples in real time. The book encourages this approach and all the examples follow on from previous ones which I think works quite well for gradually introducing concepts.
  • Functions are types in functional programming – I have had a bit of exposure to this idea with Funcs in C# but partial function application is certainly a new concept to me. I can certainly see the value in this although it took me a while to get used to the idea. I am intrigued as to where we should use a functional approach and where an OO approach when working in C#. I think both have a place in well written code.
  • F#'s implicit static typing is one of my favourite things about the language – you get safety at compile time but you don't waste a lot of code writing in type information that the compiler should be able to work out for you. It has the strongest type inference of any language that I've worked with and I thought it was quite nice that it was able to work stuff out for me instead of me having to type it all out.
  • I really like the idea of option types which I first learnt about from the book. Having the ability to explicitly define when a query hasn't worked is far superior to having to do null checks in our code or the various strategies we use to get around this.
  • I thought it was cool that in the early chapters the focus with the F# code is to provide examples that you can just get running straight away instead of having to worry about the need to structure your code in a maintainable way. After I had a reasonable grasp of this then the chapter about using record types to structure code in an OO way come up. I still prefer the C# style of structuring code in objects – it just feels more natural to me at the moment and manages the complexity more easily. It is quite easy to switch between the two styles using features like member augmentation so I think it's probably possible to mix the two styles quite easily.
  • We can use modules to make F# functions which don't fit onto any class available from C# code. The code is not as clean as if we were writing just for it to be used by other F# code but it's not too bad:
    module Tests =                                               
        let WithIncome (f:Func<_, _>) client =                  
            { client with Income = f.Invoke(client.Income) }

    We can then call this in our C# code like so:

    Tests.WithIncome(income => income + 5000, client);

    Dave Cameron has written more about this.

  • Although I studied data structures at university I don't really pay a great deal of attention to them in terms of performance normally so it was interesting to see the massive performance hit that you take when appending a value to the end of an F# list compared to adding it to the beginning. F# uses linked lists so if we want to add something to the end then there is a lot of recursion involved to do that which is quite costly. In terms of big O notation we go from O(N) where N is the number of elements to append to O(N*M) in terms of performance.
  • Chapter 13 is about parallel processing of data for which I found I needed to download the Microsoft Parallel Extensions to .NET Framework 3.5, June 2008 Community Technology Preview and then add a reference to 'C:\Program Files\Microsoft Parallel Extensions Jun08 CTP\System.Threading.dll' in order to make use of those features.
  • The author provides a nice introduction to continuations and how you can make use of them in F# by using continuation passing style. I'm intrigued as to how we can make use of these in our code – we do a bit already by making use of callbacks which get fired at a later point in our code – but from what I've read it sounds like we should be able to do even more especially when writing web applications.
  • Asynchronous workflows are also made very accessible in this book – I had previously struggled a bit with them but the author covers the various API methods available to you and then explains what is going on behind the syntactic sugar that F# provides. I have made some use of these in the little twitter appication that I've been working on now and again.

In Summary

I really enjoyed reading this book – it's my first real foray into the world of functional programming since university and I think I understand the functional approach to programming much better than I did back then from reading this book.

It takes an approach of introducing various functional programming concepts before showing examples of where that concept might come in useful when coding. It's also particularly useful that examples are shown in C# and F# as this made it much easier for me to understand what the F# code was doing by comparing it with the code in a more familiar language.

I'd certainly recommend this to any .NET developers curious about learning how to apply ideas derived from functional programming to their C# code and indeed to any developers looking to start out learning about functional programming.

Written by Mark Needham

May 24th, 2009 at 7:25 pm

Posted in Books

Tagged with , , ,

The Five Dysfunctions of a Team: Book Review

with 3 comments

The Book

The Five Dysfunctions of a Team by Patrick Lencioni

The Review

I heard about this book a while ago but I was intrigued to actually get a copy by Darren Cotterill, the Iteration Manager on the project I'm working on at the moment.

I was particularly interested in learning whether the ideas of agile and/or lean help to solve any of these dysfunctions.

What did I learn?

  • The book is split into two sections. In the first section a story is told about an organisation with a dysfunctional team and the dysfunctions are gradually introduced. The second section covers them in more detail and provides ways to overcome. The dysfunctions are as follows:
    1. Absence of Trust – team members are unwilling to be vulnerable within the group
    2. Fear of Conflict – team cannot engage in unfiltered and passionate debate of ideas
    3. Lack of Commitment – team members rarely have buy in or commit to decisions
    4. Avoidance of Accountability – team members don't call their peers on actions/behaviours which hurt the team
    5. Inattention to Results – team members put their individual needs before those of the team
  • One of the most interesting arguments the book raises is around getting everyone to be focused on the same goal whereby the collective ego gets precedence over individual egos. This requires a lack of politics which is defined as 'when people choose their words and actions based on how they want others to react rather than what they really think'. This idea also seems similar to the idea in lean thinking of favouring the big picture over local optimisations – the team as a whole succeeding is more important than any individual success.
  • The other danger of individual goals being favoured over those of the collective is identified as being specialism in teams whereby everyone is responsible for their part and noone else knows anything about it. Pair programming with frequent rotation is one approach that we can use in software development teams to help avoid this specialisation as well as encouraging team members to become generalising specialists rather than expert in just one area.
  • The ideas around healthy conflict are quite interesting. Meetings should have some level of conflict otherwise we probably just have false harmony. This sounds a little similar to the idea in lean that 'no problem is a problem' – i.e. we shouldn't keep things to ourself but instead get them out there and find a way to solve the problem. The author also points out that conflict is never going to feel comfortable but that doesn't mean that we shouldn't engage in it.
  • I particularly liked the ideas for creating trust on a team – team members are given the opportunity to share some information about themselves including their greatest strength and weakness in relation to the team. I've not seen this explicitly done on any teams I've worked on but I think that when pair programming people do share this kind of information so maybe we do actually get some of the benefits of this approach. The idea is that team members should be 'confident that their peers intentions are good'. Reading this reminded me of the retrospective prime directive.
  • An idea which I don't completely agree with is that we should look to make decisions because 'a decision is better than no decision' – the author claims that not making decisions can lead to a lack of confidence in the team and that dysfunctional teams wait until they have enough data to be certain that their decision is correct. He does then go on to point out that if the decision is wrong then we should not be afraid to change it which I do agree with. In software development teams though I question the value of making decisions too early – there is some value in following an approach such as set based concurrent engineering where we try out several approaches before converging on the actual solution later on.

In Summary

I found this book really interesting and I could definitely relate to some of the the things that were talked about.

I think lean/agile ideas do solve some of the problems but certainly not all of them and it would definitely be interesting to try out some of the exercises suggested on future teams I work on.

Written by Mark Needham

April 22nd, 2009 at 6:50 am

Posted in Books

Tagged with ,

Re-reading books

with 5 comments

An interesting thing that I've started to notice recently with regards to software development books is that I get a lot more from reading the book the second time compared to what I did reading the book the first time.

I've noticed this for several books, including The Pragmatic Programmer, Code Complete and Domain Driven Design, so my first thought was that perhaps I had read this books too early when I didn't have the necessary context or experience to gain value from reading them.

A conversation with Ade led me to believe that perhaps this isn't the case and in actual fact reading the book the first time pushes your thinking in certain directions even though you don't necessarily realise it.

Coming back to the same book again seems like it should be a waste of time, but I think we have different ideas about what is important when it comes to developing software and therefore the book affects us in different ways despite the fact that the content is exactly the same.

With the three books I mentioned above, the first time I read each of them the advice seemed fairly obvious and continuing with this attitude I struggled to get much out of them.

The Pragmatic Programmer was the first one I re-read and the second time I read it I was getting into the idea of automation around build and deployment so the parts of the book which talk about automation really stood out for me. A lot of other places where automation would be useful became apparent to me from reading the book the second time.

I started re-reading Code Complete after a recommendation from Dave but this time my focus was heavily on the expressibility of our code as this is the area of coding that I am very interested in at the moment. Some of the ideas around variable naming are superb and are directly linked to some of the mistakes I have made recently in this area. It was very interesting for me to see this in a book I hadn't picked up for a few years.

Domain Driven Design is by far the most recommended book amongst developers at ThoughtWorks and I am currently reading it for the second time but this time as part of a technical book club. I have learnt how the specification pattern can be applied on real projects thanks to examples show to me by Alex but in particular the idea of bounded contexts has started to make way more sense to me due to the fact that we didn't follow this idea on a recent project and really suffered as a consequence.

I'm sure when I read these books again I will learn something else that I didn't learn the first or second times.

More than just books…

I think this can also apply to the way that we learn other things such as different styles of programming.

For example, I studied functional programming at university but I never really saw the benefits that we could get from it – the lecturer just pointed out that it was 'better' than using an imperative language which didn't really resonate with me.

Having played around with Erlang and F# a bit and seeing some of the problems we cause ourselves in non functional languages by having mutable state I am starting to understand and like it much more.

The realisation for me has been that we don't have to understand or get everything the first time we do it, there are plenty more opportunities to do that.

And on a book specific level, to make sure I read books more than once to see what I get out of them the next time!

Written by Mark Needham

March 19th, 2009 at 10:49 am

Talent is Overrated: Book Review

with 8 comments

The Book

Talent is Overrated by Geoff Colvin

The Review

I came across this book on Jason Yip's Twitter feed while the idea of 10,000 hours to become an expert at any given skill was being discussed. I'm reading Outliers as well and the two books seem to complement each other quite well.

I'm interested in how we can apply deliberate practice in software development, perhaps using the medium of coding dojos, to become better developers in a more effective manner than just normal practice.

What did I learn?

  • The first section of the book is spent dismissing the notion that innate talent is what makes people who are world class in their field so good at what they do. Research is cited showing that it is only through 10,000 hours of practice that world class performance can be achieved.

    Although I agree that the best performers do have to put in a lot of practice to become good at what they do, I'm still of the opinion that people have some skills they are naturally better at than others and if these are the ones they chose to practice they are always going to be better than someone who didn't start off with that ability. I think this idea is discussed more in Outliers than in this book though.

  • Deliberate practice is described as something which is:
    • Designed to improve performance
    • Can be repeated a lot
    • Feedback continuously available
    • Highly demanding mentally
    • Not much fun

    Some examples are given of people who have engaged in deliberate practice and approach seems to entail finding something very specific that you want to improve on in a practice session and then working on that repeatedly while maintaining the self awareness to analyse how it is going and adapt accordingly.

    Benjamin Franklin's approach to improving his writing involved comparing his efforts to those of the Spectator, the standard which Franklin strived to reach. Software development wise perhaps this could involve picking an area of improvement such as trying to write code using small methods (less than 5 lines per method for example) and then comparing that code to some open source code written by someone like Uncle Bob for example, analysing where improvement is still needed and then practicing in that area.

  • I am keen to work out whether we can design coding dojo sessions to be about deliberately practicing in a certain area. From the dojos we've run in Sydney we've found that the more specific we can make the problem to solve the more we gain from the session as the practice is much more focused. Areas of practice for future coding dojos could be: Refactoring a code base, using tiny types, coding in a functional way, and so on.

    The key with any approach that we take seems to be to ensure that the tasks we're working on are just slightly above our level of competence, an idea I have previously read about in Apprenticeship Patterns and Pragmatic Learning and Thinking.

  • With regards to improving skills, three models are suggested for non-work related practice:
    • Music Model – Break down activity into smaller pieces; analyse each for ares of improvement; repeatedly practice each area. This is a useful approach for practicing presentations and speeches where we know beforehand what we want to do.
    • Chess Model – Study real games; practice the situations from the games; compare what you did vs what happened in the real game. This approach has been applied in business for many years, disguised as the case method.
    • Sports Model – re-learn the basics of the field; simulate situations that may come up in real life.

    I think some parts of each of these models can be applied to software development. From the sports model we can take the idea of re-learning the underlying principles of computer science and how our code is actually working behind the abstractions languages create for us; from the chess model we can take the idea of considering different options when we have a choice to allow us to select the one which will best solve our problem; and from the music model we can take the idea of identifying specific areas of improvement in our work and relentlessly working on these.

  • Domain knowledge is identified as being one key area where experts have a very important advantage over everyone else. Having a mental model of the domain that we work in provides a framework for learning new information and allows us to learn new information in context rather than on its own, making it much more likely that we will remember this information. I think this is particularly applicable in software development and is something I've forgotten about lately. Knowing the industry that you're working in makes you much more effective when it comes to understanding what users need and what features will be the most valuable to them.
  • Closely linked to this idea is chunking of information to allow us to hold more data in our memory. The example given is around expert chess players being able to remember the positioning of pieces on a board much better than novices since they see the moves which have happened rather than memorising the absolute positioning of the pieces. This can be applied when reading code bases – I've noticed that people more experienced at doing this than myself are able to notice patterns more easily and can separate noise and signal much more easily.
  • I found it quite interesting that the author speaks about creating organisations which are all about building people. This is a very similar idea to that of creating learning organisations which I came across while reading Lean Software Development. A failure to create this type of environment in a consultancy, for example, would result in it effectively being a body shopping operation.

    The problem is that putting people into the roles that best allow them to improve mean that they won't be working in their strongest role and therefore the organisation is not getting the benefits of those skills. Ideas expressed around creating a balance include encouraging employees to take part in communities and giving them additional 'growth projects'.

    I guess the equivalent in the software world would be to contribute to open source projects and participate in user groups and mailing lists to gain skills and insights that we would not otherwise gain.

  • The importance of feedback is also emphasised in helping people to achieve great performance. I'm not convinced that the typical approach to reviewing performance is the optimal approach and my current thinking around this is that it might be useful to measure out progressing skills in different areas against the Dreyfus model and then work out ways to progress to the next level. Retrospectives on agile projects are a way that we share feedback at a project level but I think we need to create shorter and more effective feedback cycles for individuals to help them to get better.
  • The idea of letting employees choose their own projects is raised as one which can help lead to greater innovation inside organisations since people will be working on something they are passionate about and are therefore going to do a much better job at it. Google's 20% time is an example of this idea proving to be reasonably effective. I don't know how that would be achievable at a project level but certainly on agile projects an approach which lets developers choose which stories they want to work on tends to be the most effective approach from my experience.
  • The myth that innovation comes about by accident is addressed and instead an alternate theory, that "the aha moment comes out of hours of thought and study" is proposed. The majority of innovations are shown to have been derived from something that previously existed but was modified to be even better. I think this is true in software too. For example, Mockito is the predominant Java mocking framework at the moment, and although it allows mocking/stubbing in a different way than was previously possible, that idea would not have been possible without JMock and EasyMock having been invented first.

    It is also suggested that creating an environment where time is available for people to try things out is important if we want innovation to actually happen.

  • The idea of motivation is touched on – the suggestion being that intrinsic motivation is predominant in people who are prepared to put in the practice necessary to become world class at something. It is also suggested that for some people practicing skills puts them in a state of flow, meaning that practice is actually enjoyable and not hard work as had been suggested earlier.

In Summary

This area of study still fascinates me and this book certainly gives a great deal of insight into the way that world class performers have made themselves so.

Software development wise I'm looking forward to reading Corey Haines' thoughts on how ideas such as his pair programming journeyman tour can help us to improve as developers and seeing how our understanding of the value of coding dojos continues to develop.

Written by Mark Needham

December 29th, 2008 at 8:52 pm

Posted in Books

Tagged with