Last week I attended QCon London 2010. I was lucky enough to get to two days of tutorials as well as the full three days of the conference.
First up I attended the brilliant Rest In Practice tutorial run by Jim Webber and Ian Robinson. The tutorial is based around their forthcoming book with Savas Parastatidis which now in rough cuts
The tutorial covered a lot of ground, and was well presented. By using Hypermedia you can create very rich services and this tutorial provided a great insight on how and why you should do just that. It provided a good overview of what REST really is using the Leonard Richardson maturity model, and how most services that tout being RESTful are not actually fully RESTful (though they may indeed still be of value).
On day 2 I attended the Resource Oriented Architecture tutorial run by Brian Sletten. Before going in I wondered if I'd made a mistake selecting two REST tutorials - but it turned out to be a great choice, it was complementary to the day before.
One of the most memorable parts of the tutorial was the 'musical interlude' where Brian did a brilliant job of explaining derivative works, and how public data opens up a world of possibilities.
The conference proper kicked off on Wednesday. The opening key note by Bob Martin, whilst at times a bit preachy, was entertaining and re-enforced some good development practices.
As usual it was difficult at times to chose which talk to attend, which became irritating when you hit a slot where there were no talks that stood out. This year was also much busier, with rooms becoming crowded and at times overcrowded. I felt that it wasn't quite as well organised this year, things didn't flow quite as well and some of the speakers seemed ill prepared.
However many of the talks were of high standard, and very enjoyable.
Unlike last year I am not going to try and summarise every talk I went to, I just don't have the time these days. But some stand outs for me included:
The Counter-Intuitive Web by Ian Robinson
One of the best talks of QCon, Ian delved into the differences between Operation and Resource centric architectures - some overlap with Mondays tutorial, but was in many ways complimentary.
He talked about how to map Domains on to Resources and how HTTP can be used appropriately as the Application Transfer Protocol and not just treated as a Transport Protocol. One of the best tag-lines of the talk was 'Intention should be written on the wire'. The idea that contracts can be expressed simply in the combination of link relations, media types, HTTP idioms and an entry point URI.
Simplicity - The Way of the Unusual Architect by Dan North
Dan is a great speaker, entertaining and engaging. The talk started with a comical biblical style story with one of my favourite lines being - "And Maven brought forth a Plague of Apache Commons, and there was a flood of all the Libraries of the Internet as a judgement upon the people"
The talk was about how we over complicate things, gradually over time we introduce further and further complexity. Dan presented some techniques to try and address these tendencies.
How to do over 100K contended complex business transactions per second at less than 1ms latency - Dave Farley & Martin Thompson
Ok, the only thing I can say is - this hurt my brain. Their solution was computer engineering elegance, hitting the sweet spot at every point in the chain - really forced me to think about how to approach problems and really reminded me of the early days of PC's where every bit of performance was eeked out of the system.
Some random thoughts, usually about software, systems and process.
All views expressed are mine and not necessarily those of my employers past, present and future.
Monday, 15 March 2010
Sunday, 18 October 2009
The Freedom to Fail
Recently I had a discussion with a colleague about his strong 'fear of failure'. We spoke about it and hopefully I put his fears into context, and I will try and build on that here.
Now the Fear of Failure is important, it helps keep us motivated, it keeps us diligent and for some people its is truly what drives them. However in our industry it also stifles growth, innovation and promotes over conservative behaviour.
I am quite lucky in my current role, I lead a team of engineers who have explicitly been given 'The Freedom to Fail' - it is actually in the team mission statement, how neat is that?
Now that doesn’t mean its ok to sit back relax and just let projects crash on to the rocks. There are some projects that we should not ever fail on, those where a solution is self-evident, where we have more than adequate resources and where risks are contained.
But what it does mean is, we can be more experimental in our approach, we can truly try and learn whilst tackling the challenge, and we can try things that normally would be considered risky. We get a chance to learn and grow.
In an organisation that in many ways is very conservative, and in a current climate that promotes that conservatism, we break the mold.
Now that doesn't mean we do things purely because we like the idea of them (well I lie, we occasionally do but as a learning exercise). But we question the traditional approaches, we ask ourselves if the "typical" solution is appropriate, if the corporate template is appropriate and seek out other approaches which may indeed prove to be a better fit.
Perhaps luckily our choices have proved successful more often than not. But things do go wrong, we on occasion do fail and wind up either having to restart, rework or abandon a piece of work.
It is not wrong to fail, however it is very very wrong to hide, deny or ignore failure. That failure may only be partial or minor, but it is still a failure and needs to be addressed.
So here is what is important...
Identify Failure
Have a way of identifying failure (and subsequently success). There are many useful techniques that can be applied here, including time boxing, acceptance testing and "done means done".
Time boxing can be vitally important. Estimated work often overruns its a fact of life, we are poor at estimating and often something simple takes a lot longer than expected. Using a time-box you can identify that you have failed, and you need help, need to change approach or need to give up.
Acceptance testing lets you prove that you haven't failed. In many cases I take a pessimistic view of success, if its not passing all the tests its a fail.
Done means done" - all too often you can ask if feature X finished and you'll get the reply "oh yes that's done but this part needs tweaking". Sorry pal, if that part needs tweaking its not done, now put that card back into "in progress" and finish it properly before declaring it done.
Understand the consequences of Failure
It is important to understand what the consequence of failure is at every point. There are varying magnitudes to this, both at a project planning "will we get this done on time" point of view and real life consequences of failure of the project after release.<
It is important to know what can be done (if anything) to mitigate the failure. Can a different approach be taken, can another team undertake the work, can we just ditch it?
Structure what you do to ensure any failure occurs as early as possible in the process. Failing quickly increases the chances that we can mitigate the failure or if that is not possible then stop work before more resources are wasted.<
Understand the Root Cause of the Failure
All too often the root cause of a failure is not fully understood. "We think its because the connection pool was used up and that caused ..." - wait up here, stop, "We think?"
In some cases the root cause is obvious and at other times it requires investigation (root cause analysis) however something that is often over looked is what I consider "people problems".
Dealing with people is hard, especially in an industry known for having anti-social tendencies. Quite often people without the correct skills, experience or support are given problems they are just not equipped to handle - and thats a management failure.
Disseminate the Failure
This is the bit a lot of people shy away from. I have a great deal of respect for someone who can stand up in a meeting and say, "yeah I screwed that up, I need help to find a way to resolve it".
In my experience the failure to discuss failure is worse than the original failure - it dooms others to repeat it. And covering up a failure is far far worse than than actually failing, perpetuating a lie that something works when it doesn't.
Honesty is indeed the best policy. Of course I don't mean that companies should publicly air their dirty laundry but rather within your team (and hopefully within your entire company) there should be open, honest and frank communication.
Final Whitterings
Does your team fear failure to the extent they don't think outside what they think is expected of them? Worse yet do they fear it to the extent they will actively hide or deny it? Are you holding your team back through your own fears?
Building a sense of trust within a team is vital, how you address the issue of failure I think is vital.
If you work in an environment where failure is expensive then try and create a space where it is acceptable. Code Dojo's, Hack Days and similar events give people a chance to flex their mental muscles, their creativity and lets them grow, it gives them that freedom to fail.
Can't afford to fail? Can't afford not to learn from failure.
Now the Fear of Failure is important, it helps keep us motivated, it keeps us diligent and for some people its is truly what drives them. However in our industry it also stifles growth, innovation and promotes over conservative behaviour.
I am quite lucky in my current role, I lead a team of engineers who have explicitly been given 'The Freedom to Fail' - it is actually in the team mission statement, how neat is that?
Now that doesn’t mean its ok to sit back relax and just let projects crash on to the rocks. There are some projects that we should not ever fail on, those where a solution is self-evident, where we have more than adequate resources and where risks are contained.
But what it does mean is, we can be more experimental in our approach, we can truly try and learn whilst tackling the challenge, and we can try things that normally would be considered risky. We get a chance to learn and grow.
In an organisation that in many ways is very conservative, and in a current climate that promotes that conservatism, we break the mold.
Now that doesn't mean we do things purely because we like the idea of them (well I lie, we occasionally do but as a learning exercise). But we question the traditional approaches, we ask ourselves if the "typical" solution is appropriate, if the corporate template is appropriate and seek out other approaches which may indeed prove to be a better fit.
Perhaps luckily our choices have proved successful more often than not. But things do go wrong, we on occasion do fail and wind up either having to restart, rework or abandon a piece of work.
It is not wrong to fail, however it is very very wrong to hide, deny or ignore failure. That failure may only be partial or minor, but it is still a failure and needs to be addressed.
So here is what is important...
Identify Failure
Have a way of identifying failure (and subsequently success). There are many useful techniques that can be applied here, including time boxing, acceptance testing and "done means done".
Time boxing can be vitally important. Estimated work often overruns its a fact of life, we are poor at estimating and often something simple takes a lot longer than expected. Using a time-box you can identify that you have failed, and you need help, need to change approach or need to give up.
Acceptance testing lets you prove that you haven't failed. In many cases I take a pessimistic view of success, if its not passing all the tests its a fail.
Done means done" - all too often you can ask if feature X finished and you'll get the reply "oh yes that's done but this part needs tweaking". Sorry pal, if that part needs tweaking its not done, now put that card back into "in progress" and finish it properly before declaring it done.
Understand the consequences of Failure
It is important to understand what the consequence of failure is at every point. There are varying magnitudes to this, both at a project planning "will we get this done on time" point of view and real life consequences of failure of the project after release.<
It is important to know what can be done (if anything) to mitigate the failure. Can a different approach be taken, can another team undertake the work, can we just ditch it?
Structure what you do to ensure any failure occurs as early as possible in the process. Failing quickly increases the chances that we can mitigate the failure or if that is not possible then stop work before more resources are wasted.<
Understand the Root Cause of the Failure
All too often the root cause of a failure is not fully understood. "We think its because the connection pool was used up and that caused ..." - wait up here, stop, "We think?"
In some cases the root cause is obvious and at other times it requires investigation (root cause analysis) however something that is often over looked is what I consider "people problems".
Dealing with people is hard, especially in an industry known for having anti-social tendencies. Quite often people without the correct skills, experience or support are given problems they are just not equipped to handle - and thats a management failure.
Disseminate the Failure
This is the bit a lot of people shy away from. I have a great deal of respect for someone who can stand up in a meeting and say, "yeah I screwed that up, I need help to find a way to resolve it".
In my experience the failure to discuss failure is worse than the original failure - it dooms others to repeat it. And covering up a failure is far far worse than than actually failing, perpetuating a lie that something works when it doesn't.
Honesty is indeed the best policy. Of course I don't mean that companies should publicly air their dirty laundry but rather within your team (and hopefully within your entire company) there should be open, honest and frank communication.
Final Whitterings
Does your team fear failure to the extent they don't think outside what they think is expected of them? Worse yet do they fear it to the extent they will actively hide or deny it? Are you holding your team back through your own fears?
Building a sense of trust within a team is vital, how you address the issue of failure I think is vital.
If you work in an environment where failure is expensive then try and create a space where it is acceptable. Code Dojo's, Hack Days and similar events give people a chance to flex their mental muscles, their creativity and lets them grow, it gives them that freedom to fail.
Can't afford to fail? Can't afford not to learn from failure.
Tuesday, 25 August 2009
Learning Scala when Sleep Deprived
So I've not blogged anything in a while, usual excuse of being busy, the not so usual excuse of becoming a Dad for the second time. So as well as being busy I am somewhat sleep deprived.
I've been doing some stuff with Scala and Lift, and hit a really basic issue that took me a moment (in my current state that equals about an hour) to understand.
I had a couple of classes and was trying to access a field in one class from another ... well I thought it was a field.
When I compiled I got this error:
error: value name is not a member of foo.A
Huh? Fields are public by default in Scala, what is going on here. It really had me stumped, my addled brain failed to find any reason for this, and a google search found nothing really useful.
So I changed my code to...
Now I was calling a method which simply returned name, this compiled and ran fine. So why did my original code not work? And why if I first thought that perhaps constructor parameter generated fields were private, but why did I not get an accessibility error?
Then I had a thought, how does the compiler know if 'name' is a val or a var? What if I explicitly state so?
This worked. Interestingly using 'var' worked as well - I can only assume that the compiler is getting confused if its not specifying it and so silently doesn't create a field. Even though you can still reference it internally in the class it has no external representation.
Perhaps a case for either a warning or better error granularity?
Or perhaps just a case for me to get more sleep?
I've been doing some stuff with Scala and Lift, and hit a really basic issue that took me a moment (in my current state that equals about an hour) to understand.
I had a couple of classes and was trying to access a field in one class from another ... well I thought it was a field.
package foo
class A( name: String ) { }
class B() {
val myA = new A("foobar")
println( myA.name )
}
When I compiled I got this error:
error: value name is not a member of foo.A
Huh? Fields are public by default in Scala, what is going on here. It really had me stumped, my addled brain failed to find any reason for this, and a google search found nothing really useful.
So I changed my code to...
class A( name: String ) {
def getName = { name }
}
class B() {
val myA = new A("foobar")
println( myA.getName )
}
Now I was calling a method which simply returned name, this compiled and ran fine. So why did my original code not work? And why if I first thought that perhaps constructor parameter generated fields were private, but why did I not get an accessibility error?
Then I had a thought, how does the compiler know if 'name' is a val or a var? What if I explicitly state so?
class A( val name: String ) { }
class B() {
val myA = new A("foobar")
println( myA.name )
}
This worked. Interestingly using 'var' worked as well - I can only assume that the compiler is getting confused if its not specifying it and so silently doesn't create a field. Even though you can still reference it internally in the class it has no external representation.
Perhaps a case for either a warning or better error granularity?
Or perhaps just a case for me to get more sleep?
Labels:
Scala
Thursday, 4 June 2009
In order to ...
Lately I've been doing some story generation for a few projects, and I've really been focusing on the idea of putting value first.
Its a subtle, but powerful idea. I was introduced to it by Dan North during his tutorial on BDD at QCon London 2009 and it really clicked.
I've been doing quite a bit of process work involving Kanban, which really focuses on value - so it has a kind of synergy (pardon me while I wash my mouth out for using management speak). Liz Keogh also wrote a good article for InfoQ recently on Kanban and BDD.
So the format we've chosen is the same Liz describes in her article:
In order to ...
As a ...
I want ...
And its working really well so far. By putting the value first it makes more sense to our domain experts, who typically being non-technical in most cases got stuck on "As a", and "I want". And we've found that we keep our scope better contained as people stop thinking about "I want" and concentrate on the end value of "In order to".
So if you are working on stories I would really encourage you to try this one simple change. Hopefully you'll see the benefits.
Its a subtle, but powerful idea. I was introduced to it by Dan North during his tutorial on BDD at QCon London 2009 and it really clicked.
I've been doing quite a bit of process work involving Kanban, which really focuses on value - so it has a kind of synergy (pardon me while I wash my mouth out for using management speak). Liz Keogh also wrote a good article for InfoQ recently on Kanban and BDD.
So the format we've chosen is the same Liz describes in her article:
In order to ...
As a ...
I want ...
And its working really well so far. By putting the value first it makes more sense to our domain experts, who typically being non-technical in most cases got stuck on "As a", and "I want". And we've found that we keep our scope better contained as people stop thinking about "I want" and concentrate on the end value of "In order to".
So if you are working on stories I would really encourage you to try this one simple change. Hopefully you'll see the benefits.
Thursday, 28 May 2009
IVY
One of the things I have been using lately is Ivy.
In the past I have had to use Maven on various projects - and must admit, I hated it. Whilst it might be really trendy at the moment to use "convention over configuration" to me doesn't sit well in a build system. Several times what I've needed to do hasn't fit into the Maven model and I really dislike having to "wedge things in" to appease a tool.
But one thing I did like was the dependency management.
Well Ivy gives you this, without all the other stuff you don't need. You use it from Ant, its clean and easy to manage dependencies, and it leverages the existing Maven repositories.
And something else neat is the ability to bootstrap it from Ant, so you don't have to rely on someone having Ivy already installed, you can install it from within your Ant build and use it on the fly.
What I do is this, create an install-ivy.xml with the following contents:
One of the good things I find is that, I work on a variety of machines, and I don't need to install ivy, my build scripts do it for me as and when.
In the past I have had to use Maven on various projects - and must admit, I hated it. Whilst it might be really trendy at the moment to use "convention over configuration" to me doesn't sit well in a build system. Several times what I've needed to do hasn't fit into the Maven model and I really dislike having to "wedge things in" to appease a tool.
But one thing I did like was the dependency management.
Well Ivy gives you this, without all the other stuff you don't need. You use it from Ant, its clean and easy to manage dependencies, and it leverages the existing Maven repositories.
And something else neat is the ability to bootstrap it from Ant, so you don't have to rely on someone having Ivy already installed, you can install it from within your Ant build and use it on the fly.
What I do is this, create an install-ivy.xml with the following contents:
<project ivy="antlib:org.apache.ivy.ant">
<property name="ivy.install.version" value="2.1.0-rc1">
<property name="ivy.jar.dir" value="${basedir}/.ivy">
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar">
<target name="download-ivy" unless="skip.download">
<mkdir dir="${ivy.jar.dir}">
<get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/>
</target>
<target name="install-ivy" depends="download-ivy">
<path id="ivy.lib.path">
<fileset dir="${ivy.jar.dir}" includes="*.jar">
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path">
</target>
<target name="clean-ivy">
<delete dir="${ivy.jar.dir}">
</target>
<target name="clean-ivy-cache" depends="install-ivy">
<ivy:cleancache>
</target>
</project>
Then in the build.xml I add an:
<import file="install-ivy.xml">
Then have a target like:
<target name="resolve" depends="prepare,install-ivy">
<ivy:retrieve>
</target>
Then its just a matter of setting up your ivy.xml with your dependencies, which could be something simple like:
<ivy-module version="2.0">
<info organisation="org.apache" module="hello-ivy">
<dependencies>
<dependency org="com.thoughtworks.xstream" name="xstream" rev="1.3.1">
<dependency org="commons-lang" name="commons-lang" rev="2.4">
<dependency org="junit" name="junit" rev="4.5">
<dependency org="org.mockito" name="mockito-all" rev="1.7">
</dependencies>
</ivy-module>
One of the good things I find is that, I work on a variety of machines, and I don't need to install ivy, my build scripts do it for me as and when.
Subscribe to:
Posts (Atom)