markhneedham/blog huggingface dataset:
Group feedback
Date: 2010-07-07 00:17:41

On an internal mailing list my colleague http://uk.linkedin.com/pub/david-pattinson/2/21b/9a2[David Pattinson] recently described a feedback approach he'd used on a project where everyone on the team went into a room and they took turns giving direct feedback to each person.

image::http://farm5.static.flickr.com/4018/4267059618_af54737fc0.jpg[mikado.jpg,300]

Since we were finishing the project that we've been working on for the past few months, http://twitter.com/christianralph[Christian], http://twitter.com/dermotkilroy[Dermot] and I decided to give it a try last week.

One thing to note is that this feedback wasn't linked to any performance review, it was just between the 3 of us to allow us to find ways that we can be more effective on projects that we work on in the future.

Much like David I found this approach to feedback to be the most useful that I've seen in nearly 4 years working at ThoughtWorks.

We took it in turns to receive feedback from the other two guys and each person first explained what they wanted the feedback to focus on.

I've participated in face to face feedback before but what I liked better about this approach was that someone could make an observation about something that you'd done and then that became a discussion point between the three of us.

In general it seems to promote a more conversational style of feedback than often seems to happen when it's just one on one.

I think it was really good being able to get two opinions on each behaviour as people often have different takes on the same situation. Taking both viewpoints together along with your own seemed to make it easier to narrow in on the behaviour and see how it could be improved.

When giving feedback it was useful to have someone else doing so at the same time as it helped remind me about things that I'd forgotten about.

I still need to improve the way I give and receive feedback - Pat Kua details http://www.thekua.com/atwork/2009/04/a-guide-for-receiving-feedback/[a series of tips for extracting behaviours from the actual feedback that people give] and has http://www.thekua.com/atwork/2010/01/giving-feedback-to-defensive-people/[several] http://www.thekua.com/atwork/2009/11/a-guide-to-receiving-feedback-part-vi-its-okay-to-disagree/[other] http://www.thekua.com/atwork/2009/10/a-guide-to-receiving-feedback-part-iv-apply-it-immediately/[posts] on the topic. This is the best resource that I've come across but I'd be interested in knowing of any others.

The key thing that I've noticed when giving feedback is to only point out your observation and the impact it had on you rather than making assumptions about why the person might have done that - you're nearly always wrong!

Overall though I found the group feedback approach to be useful and it's something I'll look to encourage on projects I work on in the future although I'm unsure how well it would scale in a larger team.

_Photo taken from http://www.flickr.com/photos/42232541@N04/4267059618/sizes/m/in/photostream/[AmyZZZ1's Flickr stream] under the Creative Commons licence._
The value of naming things
Date: 2010-07-31 07:05:52

http://twitter.com/hyfather[Nikhil] and I were discussing some of the ideas around Test Driven Development earlier in the week and at one stage I pointed out that I quite liked Bryan Liles' idea of 'http://aac2009.confreaks.com/07-feb-2009-13-30-tatft-the-laymans-guide-bryan-liles.html[make it pass or change the message]'.

Bryan suggests that when we have a failing test our next step should be to make that test pass or at least write some code which results in us getting a different error message and hopefully one step closer to making the test pass.

As I described this to Nikhil he pointed out that this is probably what most people are doing anyway and now the technique just has a name.

I think this is probably a fair assessment but then again I find it very useful when people give a name to common techniques/patterns as it *makes them much easier to talk about* without having to fill in a whole load of context.

For example http://www.markhneedham.com/blog/2010/07/05/the-limited-red-society-joshua-kerievsky/[Joshua Kerievsky has come up with some names to describe incremental refactoring techniques] such as parallel change and narrowed change.

Parallel change describes a technique where we want to change a method signature but don't want to break all the clients of that method by directly changing it.

Instead we create the new method alongside the current one and gradually move the clients to call the new one instead. When they've all moved we can delete the original method.

Narrowed change describes a technique where we try to reduce the number of places where we have to make the change we want to make.

It's much easier to use the vocabulary that Kerievsky has come up with than to have to describe the techniques each time!

However I do think it is possible to go too far with naming things to the point that there are actually so many names that it's incredibly difficult to remember them all.

http://xunitpatterns.com/[xUnit Patterns] seems like an example of this to me.

There are an incredible number of patterns described in that book and while they do all describe slightly different scenarios I'm not necessarily convinced that having this many different patterns makes our discussions easier.

Overall though I think having names for common patterns in software development is a good thing and it does add value even though it seems like we've just 'given something a name'.
TDD: I hate deleting unit tests
Date: 2010-07-15 23:15:54

Following on from http://www.markhneedham.com/blog/2010/07/11/a-new-found-respect-for-acceptance-tests/[my post about the value we found in acceptance tests on our project when doing a large scale refactoring] I had an interesting discussion with http://twitter.com/JakCharlton[Jak Charlton] and http://twitter.com/Ben_Hall[Ben Hall] about deleting unit tests when they're no longer needed.

The following is part of our discussion:

http://twitter.com/JakCharlton/status/18308678581[Ben]:

____
@JakCharlton @markhneedham a lot (not all) of the unit tests created can be deleted once the acceptance tests are passing\...
____

http://twitter.com/Ben_Hall/status/18308860222[Jak]:

____
@Ben_Hall @markhneedham yep I agree, but that isn't what TDD really advocates - its a balance, unit tests work well in some places
____

http://twitter.com/markhneedham/status/18312293752[Me]:

____
@Ben_Hall @JakCharlton gotta be courageous to do that.Its like you're ripping away the safety net. Even if it might be an illusion of safety
____

http://twitter.com/markhneedham/status/18312293752[Jak]:

____
@markhneedham one of the XP principles \... Courage :)
____

image::{{<siteurl>}}/uploads/2010/07/dragons2.jpg[dragons2.jpg,300]

While Jak and Ben are probably right I do *find myself feeling way more anxious about deleting test code than I would deleting production code*.

I think that this is mostly because when I delete production code we usually have some tests around that code so there is a degree of safety in doing so.

Deleting tests seems a bit more risky because there's *much more judgement involved* in working out whether we're removing the safety net that we created by writing those tests in the first place.

The diagram on the right hand side shows the way I see the various safety nets that we create to protect us from making breaking changes in production code.

In this case it might seem that a unit test is providing safety but it's now an illusion of safety and in actual fact it's barely protecting us at all.

I find it much easier to delete a unit test if it's an obvious duplicate or if we've completely changed the way a piece of code works such that the test will never pass again anyway...

..and I find it more difficult to judge when we end up with tests which overlap while testing similar bits of functionality.

Do others feel like this as well or am I just being overly paranoid?

Either way does anyone have any approaches that give you ore confidence that you're not deleting something that will come back to haunt you later?
The prepared mind vs having context when learning new ideas
Date: 2010-07-22 04:06:40

I'm currently working as a trainer for http://www.thoughtworks.com/thoughtworks-university[ThoughtWorks University (TWU)] and the participants have some http://industriallogic.com/elearning/[Industrial Logic e-learning material] to work through before they take part in the 6 week training program.

I've been working through the https://elearning.industriallogic.com/gh/submit?Action=AlbumContentsAction&album=foundations&devLanguage=Java[refactoring]/https://elearning.industriallogic.com/gh/submit?Action=AlbumContentsAction&album=recognizingSmells&devLanguage=Java[code smells] courses myself and while I've been finding it really useful, I think this was partly because I've been able to link the material to situations that I've seen in code bases that I've worked on over the past few years.

It would have been interesting to see if I'd have got as much value from going through the material 4 years ago before I started working at ThoughtWorks and didn't have a range of code bases to relate the patterns to.

My thinking is that I would have found it more difficult to see the value of the material and that the approaches described would just have seemed 'obvious' despite the fact that I've made pretty much all of the mistakes that the training looks to address!

About a year ago I wrote http://www.markhneedham.com/blog/2009/03/19/re-reading-books/[a blog post where I described the value of re-reading books] and one point which I'd forgotten is that even though it may be hard to relate to some ideas the first time you come across them it's still valuable to read about them anyway.

It helps to prepare your mind for when you eventually come across some code where the idea can be applied and http://twitter.com/krishnannair[Krishnan] pointed out that this was actually part of the feedback received from the current TWU participants.

I think this is probably a good example of a variation of http://youarenotsosmart.com/2010/06/23/confirmation-bias/[confirmation bias] at work in that since we've been prepared to see certain patterns/potential to use different refactorings in code when we do come across those situations in code we're much more likely to see those situations.

Krishnan pointed out that it would still be very useful for the TWU trainers to refer back to the Industrial Logic material when we come across those patterns in the project simulation that we run as part of TWU.

I think this is the most important part of the process as it will help to reinforce the learning.

I'm still curious whether there ever is a time when it makes sense to delay learning about something until we have more context.

I find that when I'm learning about something which goes way over my head I'll often stop doing that and pick something else to look at which I can relate to a bit better.

I try to go back to the original material again later on but what I find often happens is that I'll come across it in the future more by coincidence than design and this time it will make more sense.
Technical Debt around release time
Date: 2010-07-25 14:21:34

One of the requirements that the ThoughtWorks University grads have been given on the internal project they're working on is to ensure that they leave the code base in a good state so that the next batch can potentially continue from where they left off.

The application will be deployed on Thursday and this means that a lot of the time  this week will be spent refactoring certain areas of the code base rather than only adding new functionality.

When this was suggested http://dudadornelles.wordpress.com/[Duda] pointed out that it's often the case that we might accept a certain amount of technical debt in order to get the application out there.

While he is right and this is quite an unusual situation, we did see a similar situation on the last project I worked on.

On that project there was quite a tight delivery deadline for the first release so we knowingly incurred some technical debt in order to make sure that we met that date.

I've http://www.markhneedham.com/blog/2010/06/20/coding-controlled-technical-debt/[written previously] http://www.markhneedham.com/blog/2010/07/11/a-new-found-respect-for-acceptance-tests/[about some of the technical debt that we incurred] in that first release and while I think most of the time we made the right call I think there were still some occasions when we thought we were taking on http://martinfowler.com/bliki/TechnicalDebtQuadrant.html[deliberate prudent debt but were actually taking on deliberate imprudent debt].

Luckily it didn't really come back to bite us and in the second release we had a much more relaxed pace and were therefore able to go through the code base and refactor certain parts of it to make it more maintainable.

image::{{<siteurl>}}/uploads/2010/07/kitchen1.jpg[kitchen.jpg,430]

http://tech.groups.yahoo.com/group/testdrivendevelopment/message/33121[J.B. Rainsberger has a really cool analogy] about refactoring where he talks about *cleaning the kitchen* and *cleaning the garage*.

Cleaning the kitchen is what we endeavour to do all the time such that we'll write a bit of code and then clean up after ourselves. Sometimes we don't clean up enough and we end up with a bit of a mess which takes much longer to clean up - i.e. we need to clean the garage.

<img src="{{+++<siteurl>+++}}/uploads/2010/07/garage.jpg" alt="garage.jpg" border="0" width="430" height="198"style="float: left;" />+++</siteurl>+++

I think we sometimes drift towards thinking that we don't need to clean the kitchen so often and end up cleaning the garage too often as a result.

This is something that Uncle Bob covered in a post he wrote around a year ago where where http://blog.objectmentor.com/articles/2009/10/15/we-must-ship-now-and-deal-with-consequences[he points out that we're more likely to take on technical debt when we didn't need to rather than the other way around].

Finding the right balance between cleaning the kitchen and cleaning the garage seems to be something that comes from the experience of taking either approach too far.
Bundler: Don't forget to call 'source'
Date: 2010-07-25 11:48:51

http://twitter.com/bguthrie[Brian], http://twitter.com/tdinkar[Tejas] and I (well mainly them) have been working on http://developer.yahoo.com/hacku/hackuhandler.php?appid=hacku&op=showhack&hackid=1094[an application to give badges to people based on their GitHub activity at the Yahoo Open Hack Day] in Bangalore and we've been making use of http://gembundler.com/[Bundler] to pull in our dependencies.

Our Gemfile was originally like this:

[source,ruby]
----

gem "sinatra", "1.0"
gem "haml", "3.0.13"
gem "activesupport", "3.0.0.beta4", :require => false
gem "tzinfo", "0.3.22"
gem "nokogiri", "1.4.2"
...
----

For quite a while we were wondering why 'bundle install' wasn't actually resolving anything at all before we http://en.wikipedia.org/wiki/RTFM[RTFM] and realised that we needed to call 'source' at the top so that bundler knows where to pull the dependencies from.

Changing the file to look like this solved that problem:

[source,ruby]
----

source "http://rubygems.org"

gem "sinatra", "1.0"
gem "haml", "3.0.13"
gem "activesupport", "3.0.0.beta4", :require => false
gem "tzinfo", "0.3.22"
gem "nokogiri", "1.4.2"
...
----

bundler still seemed to have problems resolving 'nokogiri' whereby I was getting various error messages, eventually ending up with this one:

[source,text]
----

Installing nokogiri (1.4.2) from .gem files at /Users/mneedham/.rvm/gems/ruby-1.8.7-p299/cache with native extensions /Library/Ruby/Site/1.8/rubygems/installer.rb:482:in `build_extensions': ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError)

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb
checking for iconv.h... yes
checking for libxml/parser.h... yes
checking for libxslt/xslt.h... yes
checking for libexslt/exslt.h... yes
checking for gzopen() in -lz... no
-----
zlib is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
----

I had to http://nokogiri.org/tutorials/installing_nokogiri.html[follow the instructions on their website] to get that working which isn't ideal as it means not everything is being resolved through bundler.

I'm not sure if there's a way to get around having to do that so if anyone know a way let me know!
Design Simplicity: Partially updating an object
Date: 2010-09-05 17:32:00

One of the most common discussions that I have with my colleagues is around designing bits of code in the simplest way possible.

I've never quite been able to put my finger on exactly what makes a design simple and there is frequently disagreement about what is even considered simple.

On the last project I worked on we had an interesting problem where we wanted to partially update different parts of an object from different pages of the application.

image::{{<siteurl>}}/uploads/2010/08/design-simplicity.jpg[design-simplicity.jpg,457]

We had access to the id of the object from the URL so my initial thought was that when we submitted each page we could load the full object from the database and update it with the values that had just been submitted from that page.

The problem with that solution was that it meant we needed to make another database call without any real benefit from doing so.

We had already created objects representing the data submitted from these pages so http://twitter.com/christianralph[Christian] suggested that an alternative approach would be to create NHibernate mappings for those objects instead so that we could just map the updated values straight to the database.

We had bit of duplication in our objects as we had one object representing every bit of data the user had provided so far and then two smaller objects just representing the data provided for each of the pages.

[source,csharp]
----

public class TheObject
{
	public string Page1Property { get; set; }
	public string Page2Property { get; set; }
}
----

[source,csharp]
----

public class PartialObject1
{
	public string Page1Property { get; set; }
}
----

[source,csharp]
----

public class PartialObject2
{
	public string Page2Property { get; set; }
}
----

We then created NHibernate mappings for each of those objects:

[source,csharp]
----

public class TheObjectMapping : ClassMap<TheObject>
{
	Map(x => x.Page1Property);
	Map(x => x.Page2Property);
}
----

[source,csharp]
----

public class PartialObject1Mapping : ClassMap<PartialObject1>
{
	Map(x => x.Page1Property);
----

[source,csharp]
----

public class PartialObject2Mapping : ClassMap<PartialObject2>
{
	Map(x => x.Page2Property);
----

When loading the object from the database onto the page we used 'TheObject' and its associated mappings and when updating the object from the individual pages we could use the partial object mappings.

I think this was quite a neat approach as it allowed us to reduce the complexity of our controller code when updating an object as well as removing the need for one trip to the database.

The trade off was that we ended up writing more mapping code but that seemed to be a reasonable trade off to make.
Learning cycles at an overall project level
Date: 2010-09-20 18:56:20

I was looking back over http://www.markhneedham.com/blog/2008/12/07/learning-cycles/[a post I wrote a couple of years ago where I described some learning cycles that I'd noticed myself going through with respect to code] and although at the time I was thinking of those cycles in terms of code I think they are applicable at a project level as well.

The cycles I described were as follows:

. Don't know what is good and what's bad
. Learn what's good and what's bad but don't know how to fix something that's bad
. Learn how to make something that's bad good

I think I've followed similar cycles with respect to how an overall project is run.

To start with I didn't really know what it was that made a project run with an agile mindset different to anything I'd seen previously so I spent a lot of time observing the approaches my colleagues used, the processes they tried to drive and generally trying to understand what made a project tick.

Having worked on quite a few projects and seen similar underlying concepts working despite differing contexts I started to notice that the situations coming up were often the same or very similar to ones that I'd seen before.

At this stage I was more convinced that some of the approaches I'd already learnt could be useful but often deferred to more experienced colleagues or suggested improvements and relied on them to help drive them.

When I worked with http://twitter.com/dermotkilroy[Dermot] he pointed out that the next step was to now be the one who can drive the changes that I want to see rather than relying on someone else to do it.

I've been trying to do that more recently and it's not all that different to the way that I already try and influence the way that code is designed except it covers a wider spectrum of situations.

Books like http://www.amazon.com/Fearless-Change-Patterns-Introducing-Ideas/dp/0201741571/ref=sr_1_1?s=gateway&ie=UTF8&qid=1285008400&sr=8-1['Fearless Change'] and 'http://www.amazon.com/Agile-Coaching-Rachel-Davies/dp/1934356433/ref=sr_1_1?s=gateway&ie=UTF8&qid=1285008462&sr=8-1[Agile Coaching]' certainly have good tips for how to influence change but I find that more often than not I only really understand how to do something after I've made a complete mess of it the first time around.

I guess the downside of trying to influence situations more is that you put yourself in a position to be shot down so perseverance and knowing when to push and when to back off seem to be skills that will be particularly useful.