Archive for the ‘twu’ tag
While reading some of the rough drafts of Apprenticeship Patterns online I started thinking about the stages I have gone through on my Software Development journey so far.
I have worked in the industry for just over 3 years; 1 year at Reed Business and 2 years at ThoughtWorks. Over that time my thoughts, opinions and ways of doing things have changed, and no doubt these will continue to evolve as I learn more and more.
My time at RBI
I started working at RBI in August 2005 a few months after I finished University. My experience up to this point involved several years coding PHP in a very procedural way and a little bit of Java.
I was hired by RBI as a C# Web Developer and my work there involved working on several internal projects and looking after one of their websites.
At this stage I was still very much convinced that the art of software development lay in learning languages, so I used to spend all my time reading about C# and playing around with all the different APIs.
At this stage I was using Visual Studio without Resharper so I didn’t have the ease of Refactoring or moving code around that I now take for granted.
One of my colleagues took me under his wing and started teaching me how to write better code – separation of code across presentation/business/data layers was my first lesson. Suddenly it became so much easier to make changes! All the code I wrote was still in a non TDD way and after one episode where I created a bug in production I started to think that surely there was a better way to develop software.
Eventually my colleague suggested to me that if I really wanted to learn how to write software then the best place to do so was at ThoughtWorks.
I thought I had a fairly good idea of how to write Object Oriented code but that theory was quickly disproved as I went through Object Boot Camp as part of my TWU training. The Single Responsibility principle was the overwhelming lesson learned as part of this. I also remember believing at this stage that it was all about Design Patterns.
I came back to the UK and did a couple of small projects where I first came across continuous integration and TDD before going onto my first big project.
I remember my first day on that project involved pairing with Darren Hobbs and being amazed at the speed with which he was able to move around the code using IntelliJ. It became clear to me that I had a long way to go.
Working on this project for the best part of the year I learned a lot, including how to write code in a Test Driven way, that everything you do in software is a trade off, but most importantly I learned how to master the IDE – if you can do this then you feel more confident and you can complete tasks much more quickly. This is always the advice I see given to new Graduates at ThoughtWorks – learn how to use your tools!
I moved onto my second project where I was immediately surprised at how much easier I found it to move around the code base than I had at the start of my first project.
We were designing a client side application so a big part of my learning here was around testing presentation logic. Jeremy Miller’s blog proved invaluable at this stage.
It was also the first time I came across the concept of Domain Driven Design – it was amazing how much easier it was to develop software when the developers were using the same language as the BA, QA and in fact the business. InfoQ’s cut down version of Eric Evans’ famous book proved useful in helping me understand the concepts that I was seeing in our code base. I remember thinking at the time that I didn’t need to bother reading DDD as it was all covered in this version – I was wrong!
We had an very lightweight version of Agile being used on this project – we tried to have minimal process and do as many things as possible just when we needed them. It was almost Lean in nature although this was never explicit. It was interesting to me how easy and fun software development could be when it was done like this.
My third project was the first time that I got the opportunity to work with legacy code – i.e. code that hadn’t been unit tested. My early lessons on trade offs came back to me here as I realised that not writing unit tests is a trade off – you can choose to go more quickly initially by not writing them but eventually it comes back to haunt you.
I was working with Alexandre Martins on this project, and his enthusiasm for writing clean Object Orientated code gave me a new outlook on writing code. Working with him got me in the frame of mind of hating exposing the internals of classes and constantly looking for other ways to solve the problem when I was considering doing so.
Halvard Skogsrud’s knowledge around concurrency was another eye opener for me around how non functional requirements should have an impact on the way that software is designed. It also introduced me to the way that other languages such as Erlang handle concurrency – and behind this the idea of having as much of your code immutable as possible to avoid threading issues.
During a debate at a ThoughtWorks Geek Night another colleague brought up Alistair Cockburn’s Hexagonal Architecture, which was the first time that I had come across an Architectural Design Pattern. This is a useful technique when thinking about the design of systems at a higher level.
On my next project I did a lot of work around build and deployment which gave me the insight that developing software is about more than just the code. This was a lesson first taught to me by Chris Read a year before but it finally made sense to me.
A big part of this project was inter process communication between different components of the system which introduced me to the idea of event driven messaging. I immediately saw the benefits of this over the RPC style messaging I had seen previously.
I also had the opportunity to do some work with Ruby on Rails and in particular around the use of Active Resource. This introduced me to the idea of RESTful web services which feels like a much more natural way to communicate over the web than any of the other approaches I have come across.
The interesting thing for me is that I didn’t plan to gain any of these learnings, they came about as a natural progression from my interest in software development and from working on different projects with different people.
The biggest things I have learned since I started working in software development are that it is much more an art than a science and that there is no right or wrong, just trade offs that we should be aware of.
I still have a lot to learn but I thought it would be good to have a look at what I’ve learnt so far in the hope it can help others just starting out on their journey.
It would be interesting to hear about others’ journeys and the similarities and differences you have experienced.
One of the first unusual (to me) things that I noticed from the trainers at ThoughtWorks University was that when they were listening to participants they would often ask questions and re-frame the participants’ comments. Intrigued and impressed by this I spoke to one of the trainers and was told that they were engaging in ‘active listening’. Wikipedia defines the term as follows:
|Active listening is an intent “listening for meaning” in which the listener checks with the speaker to see that a statement has been correctly heard and understood. The goal of active listening is to improve mutual understanding.|
I believe this is a very useful skill to acquire, and I certainly hope to improve my ability in this area.
It reminded me of the 5th Habit that Steven Covey speaks of in his book titled ‘The Seven Habits of Highly Effective People’: Seek First to Understand, Then to be Understood. Certainly easier said than done…but then again we do have two ears and only one mouth so perhaps there is a good reason for that!
Browsing the ThoughtWorks Blogs yesterday evening I came across a link to an interesting site which spoke of the ‘Eight barriers to effective listening’. I found this particularly useful as not only does it point some of the common problems one can have when listening to someone else, but also suggestions as to how these can be overcome.
A couple of months ago I read a book titled ‘Coaching Yourself to Leadership’ – although I found it quite heavy going in places, it too touches on some listening barriers, namely:
|Advising: After hearing only a few words, you believe that you know how to solve the person’s problem and you start offering advice.
Comparing: As you listen to the other person, your insecurities get triggered, and you start comparing yourself to the person—assessing which one of you is better, more knowledgeable, more competent, etc.
Daydreaming: You get triggered by something the other person says and you’re off in your own world. You don’t have a clue what the person said to you.
Derailing: You find the subject matter uncomfortable, so you abruptly change the subject or interrupt with a joke.
Filling-in: You don’t let the other person finish her sentence; instead you finish it for her.
Filtering: You only listen to the part of the message that is important to you, and tune out the rest. You either pay attention to things that might be emotionally threatening (and fail to hear anything good), or you only hear what is good (and fail to hear the parts that are negative).
Identifying: You identify with what the person is telling you and swing the conversation back to yourself, telling how something similar happened to you. You become engrossed in telling your story, and don’t really listen to the other person or allow her the space to continue her story.
Judging: You make hasty judgments about people before completely listening to what they have to say.
Mind Reading: You look for what you perceive to be the truth, and end up making assumptions that have little to do with what the person is actually saying to you.
Placating: You want to be nice and supportive; therefore, you voice agreement with everything that is being said, even if you don’t really agree. Because you don’t really want to disagree, you don’t listen deeply enough to fully examine the other person’s viewpoint.
Rehearsing: Rather than listening, you are mentally preparing what you are going to say. You might look interested, but you’re really concentrating on planning how you’re going to respond.
Sparring: You quickly disagree with the other person because you have a strong point of view. The other person feels like she hasn’t had a chance to be heard.
I hope this is ok to post on here – I’ve just written up the points straight from the book. Copyright of the author Peter O’Brien and all that.
I know I do at least 3 of those, and that’s being kind to myself!
One of the most interesting things I have discovered since starting at ThoughtWorks earlier this month is the emphasis that is placed on giving feedback.
The first lesson we were taught about giving feedback was that it could be one of two types. Either it should Strengthen Confidence or Increase Effectiveness.
In Layman’s term that means that if you want to make a positive comment about somebody’s contribution then you should make reference to something specific that you believe they have done well so that they can continue doing it. Equally if you believe there is an area that they could improve it, a specific example of this behaviour/fault should be noted along with a suggestion for how they can improve.
As a member of Toastmasters since January I was already used to this concept of feedback and there are certainly parallels in the feedback system encouraged at Toastmasters and that used at ThoughtWorks.
Although Toastmasters do not define types of feedback, there is an expectation that evaluators will apply themselves in a certain manner when carrying out their job.
One of the things which is frowned upon is known as ‘whitewashing’. This is where an evaluator would say that a speaker was ‘brilliant’ or give a summary just using complementary adjectives. Although the speaker may well be flattered, it does not really tell them anything or leave room for improvement. The use of the word ‘brilliant’ or ‘superb’ is only the perception of the person using it, and the failure to make use of the word with regards to a specific behaviour or action means that it is rendered meaningless.
Equally when the evaluator believes there is an area that the speaker can improve in they should make a reference to the specific negative behaviour or action so that the speaker can recall their mistake and go about making the improvement. When giving feedback it is very poor practice to attribute your own feelings to the speaker – you are giving them control over something which they do not have control over! For example, if an evaluator were to say: ‘I felt bored listening to your speech, you should make the next speech more interesting’. In this case the evaluator is giving the speaker the power to make them feel bored. It is ridiculous to let someone have that amount of control over you and if we consider that another person listening to the same speech may have felt really engaged, a property of the speech cannot be that it was ‘boring’.
This is very similar to the way that ThoughtWorkers are expected to give feedback, although it is also emphasised that when giving feedback one should speak only for themselves, and not try and speak for a group of people. Doing this would assume that mind reading is possible and as far as I’m aware this feat has yet to be achieved. An example of committing this mistake would be to say something along the lines of: ‘It would be better for us if you could do x’. In this case ‘us’ is not defined and it is unlikely that one person can speak precisely of the feelings of other people.
This concept is very similar to that of Generalisation in the NLP Meta Model, which states the following:
|“Generalization is the process by which elements or pieces of a person’s model become detached from their original experience and come to represent the entire category of which the experience is an example.”|
This is an area that I am actually working on myself, and I am finding it very difficult to speak only for myself because I’m so used to generalising! Of course there are still times when generalisation is vital, and we would find it very difficult to live our daily lives without generalising on some things. Giving feedback, however, is one area where this ‘technique’ is counter productive.
I had heard stories about how inheritance could be misused but I didn’t think I would be stupid enough to fall straight into that trap! We were taught the concept using ‘Measurement’ as the problem domain. So to translate the previous sentence into English: The aim was to design classes which could handle old school measurement types such as Inches, Feet, Yards, and so on.
I went about the task by first creating a base Measurement class and then created Inch, Foot and Yard as sub classes of this. The code looked pretty slick to me and I was quite pleased with how it had turned out. I was feeling pretty confident that I had nailed the objective of the session. Alas, it was not meant to be!
Upon reviewing the code my partner and I had created, one of the trainers pointed out that the sub classes did not actually do very much at all. They were effectively useless classes and there was barely any difference between them! One of the other requirements for the code was that it should be possible to compare an instance of the Inch class with an instance of the Foot class, an instance of the Yard class with the Inch class and so on. No problem I thought and promptly created methods called ‘ConvertToFoot’ in my Inch class and ‘ConvertToInch’ in my Foot class.
One of the cardinal sins of object orientated programming had been committed! I now had 2 methods which did almost the exact same as the other for no additional benefit. What if there were 100 different measurements? That would mean 99 different conversion methods each to convert to all the other types of measurement. Clearly not an optimal solution – I had taken the bait and fallen into the trap of over use of inheritance.
Anyway, the lesson of the session was that in this particular case it was better to use delegation or composition. In this example it means that there is only the need for one Measurement class, each instance of which comprises of a Unit object. The concept of a ‘slug’ was introduced – no not one of those nasty little insects, but in this case meaning an instance of an object with a private constructor and one public static instance. In other words slugs are like a poor man’s Singleton. The code looked something like this:
public static readonly Unit INCH = new Unit(1);
public static readonly Unit FOOT = new Unit(12);
This made it far easier to add future measurement types, and meant that only two classes were needed instead of a potentially infinite amount.
I read an interesting article on this topic by Robert Martin, titled ‘Template Method & Strategy: Inheritance vs Delegation’ which explains the reasoning much better than I have here along with a code example.