Friday 28 October 2011

Mentorship in Software Craftsmanship - part 3

In previous posts I covered:
Part 1: Mentor and mentee roles, gains and sacrifices, mutual respect
Part 2: How to choose mentors and mentees and mentorship misconceptions



Walking the long road together (or at least part of it)

Once the relationship between mentor and mentee is established, it is fair to say that they will be in a journey together. Every software craftsman is on a personal journey towards mastery. They are all walking the long road. Both mentor and mentees will be learning while they share part of their journey with each other.

What mentors and mentees should do during the mentorship?

Well, this may vary a lot depending of the type of mentorship. In general, they are expected to write code, loads of code. Ideally they should build something together, where the mentee should be the most active in terms of writing the code. The mentor is expected to pair-program with the mentee whenever possible and to be reviewing his code.

Agreeing on creating an application would probably be the best option since that would involve not just writing the code but also thinking about requirements, being able to prioritize, defining a development process, deployment strategies, production environment and everything else that is related to a software project in the real life.

Working on katas is also a valid. It's a simpler and quicker approach for the mentee to learn basic skills. This could be used when the mentees are interested in the basics of TDD, naming, refactoring, programming languages paradigms, etc. However, after learning a few basic skills using katas, they should aim to do something larger that really can mimic the sort of applications they would be working on in their professional environments.

Establishing goals and tracking progress

Establishing goals is definitely a good practice in a mentorship. It keeps mentor and mentees focused in whatever they want to achieve. Working towards an objective is always the best way to study and learn something. Goals should be achievable and used to motivate and direct the menteed and not to be treated as a hard deadline. However, they should be as concrete as they can be, for example, writing an application with features X, Yand Z and have it deployed into production or doing a number of katas using TDD, write blog posts, read books, submit patches to open source projects, or whatever the pair agrees on.

It's important that progress is tracked so both mentor and mentees can see how they are getting on and how much the mentee is evolving. Tracking progress is all about feedback. The quicker and shorter the feedback loop is, the better. It's also a good tool to trigger conversation about improvements and refinements.

How long a mentorship should last?

Unfortunately that's another question that does not have an exact answer. This will depend a lot on the type of mentorship, how much the mentee wants to learn from the mentor and also how much the mentor has to offer.

Some say that this should be a lifetime commitment, some say that it should last between 2 to 5 years and some say that it could be as short as a few months. Some mentorships start with very technical and specific things like learning the basics of a language or test disciplines. However they can evolve to an entire project lifecycle or even to a longer term career advice, networking, help with books and conferences, etc.

I, personally, would never try to define that upfront. Just enjoy the journey and let time tell when the mentorship should terminate.

How and when does it terminate?

For the majority of the relationships, both mentor and mentees at some point need to continue their journey in separate ways. This does not mean that they will never talk to each other again or that they don't like each other. This just means that they need to move on, teach or learn from other people. Also, we all change our minds in terms of what our next steps would be and we need to react to that.

One important thing is that regardless who wants to terminate the relationship, this termination should be explicit. It should be clear to both parts that the mentorship is over.

Professionalism, Reputation and Public recognition

Software craftsmanship is all about professionalism and it is almost impossible to talk about professionalism without talking about reputation.

Throughout the mentorship, it is important that the mentor advertises the progress of her mentee. Mentors should public recognise all the skills acquired by the mentee, what would help the mentee to start building her own reputation. However, mentors also need to be aware that every time they vouch for someone, they are also putting their reputations on the line. Mentees are also expected to be recognising their mentors for all the things they've been learning. This mutual recognition is one of the things that may help both to build their reputations.

Raising the bar

Mentorship is at the heart of software craftsmanship and this is probably one of the most efficient ways for us, developers, to help raising the bar of our industry. Sharing our knowledge and experiences with each other is what will help us learn from our mistakes and successes.

We probably can teach many things to someone in a fraction of the time that took us to learn them. With this, mentees could absorb a lot of knowledge in a much shorter space of time, making them, overtime, a much more complete professional than any of the mentors she had in her career.

Regardless of our level of seniority or if we are being mentored by someone else, if we all take the responsibility to mentor someone, we will all be helping to raise the bar of our industry.


For previous parts of this blog post, please check:

Part 1: Mentor and mentee roles, gains and sacrifices, mutual respect
Part 2: How to choose mentors and mentees and mentorship misconceptions

Sunday 23 October 2011

Installing Io language on Ubuntu

Since I'm new to Ubuntu and I had a hard time installing Io language, I've decided to record my steps. Hopefully I'll remember all of them and other people won't struggle as much as I did. I'm running Ubuntu 11.10.

The main problem I had was that I did not have all the dependencies needed to install Io and the installation was failing. The dependencies are yajl and libevent

If you've got then installed, you can skip the next steps.

NOTE: You will need to have cmake and make. You can install them running the following commands from the terminal:
sudo apt-get install cmake
sudo apt-get install make

Installing yajl

  1. Download yajl from here: https://github.com/lloyd/yajl/downloads
    1. In my case it was: lloyd-yajl-2.0.1-0-gf4b2b1a.zip
  2. Extract it into a folder.
  3. Open the terminal and go to the folder you extracted yajl
  4. Run the following commands
    1. mkdir build
    2. cd build
    3. cmake ..
    4. sudo make install

For more information, please check:
https://github.com/lloyd/yajl
https://github.com/lloyd/yajl/blob/master/BUILDING

Installing libevent

  1. Download libevent from here: http://libevent.org/
    1. In my case it was: libevent-2.0.15-stable.tar.gz
  2. Extract it into a folder
  3. Open the terminal and go to the folder you extracted libevent
  4. Run the following commands
    1. ./configure
    2. make
    3. sudo make install

For more information please check:
http://libevent.org/
Also check the README file inside the .tar.gz for your version

Installing Io language

You can go to the Io language website and download the language or click here to go start downloading it. As there is no Ubuntu package for that, you will be downloading the Io's source code. This will point to Steve Dekorte's version. I ended up downloading Jeremy Tregunna's version. It should work the same. Check each one is the most up-to-date.

  1. Download the Io version here: https://github.com/jeremytregunna/io/zipball/master
  2. Extract it into a folder.
  3. Open the terminal and go to the folder you extracted Io
  4. Run the following commands:
    1. mkdir build
    2. cd build
    3. cmake ..
    4. sudo make install

IMPORTANT: When running 'cmake ..', you may get a few errors. Even then, try to run 'sudo make install'. Some libraries may fail to compile because they are OS specific.

For mode information please check:
http://iolanguage.com/
https://github.com/stevedekorte/io
https://github.com/jeremytregunna/io


Updating ld.so.conf

Now we just need to update ld.so.conf so Io can be accessed from anywhere in your computer.

  1. From the terminal, type the following command: sudo gedit /etc/ld.so.conf
  2. Add the following line to the file: include /usr/local/lib
  3. Save and close the file
  4. From the terminal run the following command: sudo ldconfig

Running Io

That's it. Hopefully now you will be able to open a terminal window and type: io
You should see the Io runtime environment: Io> _

Monday 10 October 2011

Mentorship in Software Craftsmanship - part 2


In part one I gave a bit of background history and also described the roles and responsibilities of mentors and mentees according to the Software Craftsmanship principles. In this second post I'll be convering a few other areas related to the relationship itself. Remember that the focus here is on mentorships outside work. Let's start from the beginning.

How do we find mentors or mentees?

That's probably the most difficult question to answer. I can think in three possibilities (in no particular order):

  1. Try to find someone that works with you in a daily basis. It will make the approach easier.
  2. Via user groups and communities. If you are an active member of a user group or community you will have the opportunity to meet a lot of people and maybe find the mentor or mentee you are looking for.
  3. Via indication: A friend could recommend/introduce you to someone. 


Choosing a mentor

Although not a rule, normally, in Software Craftsmanship, it is the mentee that chooses the mentor or, at least, start the conversation. The mentee needs to have an idea of the path he wants to take. For example, he may want to learn more about mobile development, work as a consultant, work in high-performance low-latency systems, learn about gaming development, improve his automated testing techniques or, in the best case, just learn how to become a better developer. Whatever the mentee's ambitions are, the mentee needs to make sure that his future mentor is a person that can provide the knowledge he or she is looking for.

Unfortunately, this may be easier said than done. Depending where the mentee is in his career, he may not know exactly what he wants. He may not even know what options he has. Although good developers are good developers and the foundation and priciples of software development always apply, we all know that the skills set used in different types of systems can vary a lot. A well experienced developer that spent the majority of his career doing web-development and became an expert in user experience may take a while to perform well in a completely server-side, asynchronous application with no GUI. Working on an application that heavily rely on algorithms and that don't use any database can be totally different from developing a mobile client application. The same way that working for a consultancy company can be very different from working for a bank or a startup.

Those are some of the things that developers at early stages of their careers may not even have a clue. If you are at this stage in your career, the best suggestion is that you focus purely on being a great developer and learn the basics. Things like Test-Driven Development, clean code, refactoring, Object-Oriented principles, different languages and paradigms. Once you have that, it will be easier for you to choose your next move.

Choosing a mentor involves is not an easy task. Maybe a single mentor won't be able to teach everything a mentee wants to know. Mentees should focus on their very next step(s) instead of focusing in everything they want to learn throughout their entire career. Mentees may change their minds quite often as soon as new opportunities and options are presented to them. They should keep their options open and choose a different mentors as time goes by.  

Choosing a mentee

Mentors, before accepting a mentee, should ask themselves: Would I be able to dedicate time to this person? Can I really help his or her career? If the answer is yes, fantastic.

The first thing to look for in a mentee is passion. Since a mentor will be allocating time to help someone, they should make sure that this person deserves their help. Make sure that the mentee is committed to be better.

Another thing mentors need to decide is what sort of seniority level their future mentee should have. Some mentors will prefer to take graduates, others prefer juniors with one or two years of experience and others prefer to get seniors or mentees on the verge of becoming seniors.

Choosing a mentee is a very personal thing and different mentors will have completely different criteria.  If the mentor already knows the mentee, than it is easier. When the mentor doesn't know the mentee I could suggest a few options that could either be combined or used independently:

  • Introduction letter: The mentor could ask the mentee for a summary of his career so far (not a CV). In this summary, the mentee would describe what he has done, where he thinks he are in his career, the things he learnt, provide (if any) links to his public profile like github account, twitter, blog, web/mobile applications and most importantly, what he expect from the mentor.
  • Coding challenge: The mentor can set up a challenge before considering to speak and accept a mentee. E.g. the mentee, using his preferred language, needs to write a simple blog or wiki application, have it deployed in somewhere (heroku, cloudbees, Google App Engine, Amazon Beanstalk, etc) and code should be public (github, for example). Or it could be simpler like solving a few katas using two different languages or anything along these lines.
  • Blog: Mentee should create a blog, if he or she does not have one, and publish a few posts related to things he has been learning on his own. 

The mentor, if going down this route, should set the challenges according to the level of seniority he is expecting from the mentee. Once the mentor is satisfied with the initial effort by the potential mentee, he could decide if he is going to accept or not the mentee.

Mentorship common misconceptions

The mentor is not better than the mentee. In general the mentor will have more knowledge and experience in the areas where the mentee has chosen to be mentored. However, the mentee can easily have more knowledge than the mentor in other areas. Mentees should not expect the mentor to have all the answers to all the problems and mentors should not be naive to think that the mentee doesn't know anything. Both mentors and mentees have skills and limitations and this needs to be understood by both parts.

Mentors should not be looking for themselves a few years younger. This can be frustrating for the mentor. People are different and the mentor will be missing out when not being more open to the type of mentee he or she is prepared to take on board. There is no reason to be so restrictive. Mentoring someone with different personality, possibly slightly different ambitions can be extremelly enriching for both mentors and mentees. However it is important that both have same values and principles.

Mentees should not expect that mentors will change their lives. The mentors will be there for the mentees, giving them advices and teaching what they know but it is up to the mentee to decide what to do with it. Mentees should do their part to improve and not think they are going to be spoon-fed by mentors. It's up to the mentee to look after his or her own career. 

In the next posts I'll be covering things like different types of mentorship, activities that could be performed by mentors and mentees, public recognition, professional reputation, graduation, mentorship duration, how this could change our industry and a few other points. Watch this space.

Part 3: What mentors and mentees should do, how long it should last, how does it end public recognition and reputation

Part 1: A bit of history, roles of the mentors and mentees, gains and sacrifices and mutual respect


Wednesday 5 October 2011

Mentorship in Software Craftsmanship - part 1

How's mentorship seen in Software Craftsmanship?

First, a little bit of background and metaphor 

In the medieval times, apprentices would work in workshops an would be mentored by senior craftsmen (journeymen) or by the master craftsman himself. The apprentice had the responsibility to learn, observing the master's and everyone else's work, questioning everything and practising as much as he could. This was different from the teacher/student relationship where the teacher had the responsibility to teach. Here it was the apprentice that had to push his own development.

The apprentice, mentored by the master, would learn and refine his skills on a daily basis. Over time, the master would reach his limit as in what he could teach the apprentice and the knowledge and skills gap between both would not be that big any more. The master would then publicly recognise the apprentice as a professional that could take on work on his own and would deliver it with the same quality that the he would deliver himself. The master, at this point, would be putting his own reputation on the line since he was the one that trained the apprentice and was now vouching for his ability. 

This would be the graduation point. Now the apprentice was ready to start his own journey, as a journeyman. As a journeyman, he would then go from town to town, work for and learn from different masters up to a point that he would be recognised by all of these masters and other craftsmen as a master himself. He would then be ready to have his own shop and start mentoring other journeymen and apprentices.

Back to the present

From now on, instead of master/apprentice, I'll be using mentor/mentee. The main reason is that you don't need to be a master craftsman to mentor someone. You also don't need to be an apprentice to have a mentor. Besides that, each developer has different areas of expertise. They can be very senior in certain areas and completely ignorant in other areas. As we all know, software development is not as limited as a blacksmith's workshop in the medieval times. 

The role of the mentor

Deciding to mentor someone is a big responsibility. The role of a mentor is more than just be available on the phone and answer a few questions here and there. Although this can be very helpful, the role of a mentor goes way beyond than that. The mentor has the responsibility to make the mentee a good professional and that includes the technical and the personal side. More than just teaching the mentee a specific framework or technique, the mentor will also be teaching the mentee how to become a professional software developer, including ethics and code of conduct. From the technical perspective, the mentor will do his best to teach everything he knows. If they don't work together, the mentor is expected to reserve formal time to work with the mentee. From the personal perspective, a mentor should help the mentee in his career (journey), giving some guidance, advices, opening doors or showing the doors he has already opened himself, introducing the mentee to his own professional circle and whatever else the mentor judges that can be important for the mentees.    

The role of the mentee

The mentee is expected to do whatever he or she can to learn from the mentor. The mentee must be open-minded, be able to take criticism on board, be able to listen and also be very proactive in terms of perpetuating the knowledge. Practice is key. The mentee is expected to practice as much as possible, making him or herself better everyday. Mentees are also expected to produce something. Something where the mentor can measure their progress and possibly identify areas of improvement. Besides the direct benefits to the mentee, this is also the best way to keep mentors excited to be helping. Mentees must show passion and a clear desire to learn otherwise mentors will probably loose interest and find it a waste of time.  

Gains and sacrifices

Mentors have the opportunity to perpetuate their knowledge since they need to organise their ideas to teach someone. Mentors will also need to be studying and practising hard to keep feeding his mentee, what obviously is a good thing. They will get the satisfaction of helping developers to progress in their careers, with good foundation, ethics and professionalism. They will be doing their part in rasing the bar of our industry, training the next generation, and this, on its own, is a very noble cause. But there are sacrifices and the main one is time. Mentors are expected to dedicate time to their mentees. If mentor and mentee work together in a daily basis, they won't need much time outside work. However, if they don't, mentors need to be clear they will need to find and reserve time for their mentees, ideally in a regular basis.

Mentees have the opportunity to speed up their development as professional software developers. They benefit from the mentor's experience acquired over the years, shortening the time they would take to learn something and avoiding to commit the same mistakes. They also have someone they trust that could offer a different perspective on the things they are going through (technical issue, problem with a manager, process, bureaucracy, deadlines, estimation, etc). Without any scientific evidence to back me up, I would dare to say that with the right attitude from both parts and a good amount of time together, the mentee could learn in two years what the mentor learned in ten. That gives the mentees a massive head-start in their careers. Time should never be called a sacrifice from the mentees perspective. When someone is getting a lot of knowledge and help for free, possibly saving years of their careers, complaining about time (or lack of it) would be very short-sighted, to say the least. 

Mutual Respect

Both mentors and mentees should respect each other. In order to have a healthy and prosperous relationship, there must be a commitment from both parts. This commitment is the mutual respect. The mentor shows respect with regular interactions with the mentee and time commitment. The mentee shows respect with his commitment to excel and demonstration of progress. That's the minimum a mentee could do for someone that is sacrificing time with family and friends in order to help him. 


In following posts I'll be exploring things like different types of mentorship, activities that could be performed by mentors and mentees, criteria for choosing a mentor and a mentee, public recognition, professional reputation, graduation, mentorship duration, how this could change our industry and a few other points. Watch this space.


Part 2: Choosing a mentor and a mentee and also common mentorship misconceptions 
Part 3: What mentors and mentees should do, how long it should last, how does it end public recognition and reputation


Tuesday 20 September 2011

LSCC's First Code Retreat

On September 10th we had the London Software Craftsmanship Community's First Code Retreat.

We had 22 passionate and talented developers working in Java, C#, Ruby, Python and JavaScript. Some of them travelled two hours, waking up as early as 5am, to come to the code retreat and many others travelled at least one hour to be there.
We started at 8am, with breakfast and informal discussions. Then we had a quick introduction, where I explained the purpose of the day and used some of Corey Haines wise words. Here's a quick summary:

"In our day-to-day job, we need to get things done. We need to achieve something and deliver something. And we want and are committed to it. In order to do so, we end up cutting corners. So that's how we code. We sacrifice quality in order to deliver "faster".

But now imagine you have all the time in the world and all the knowledge in the world. Imagine what would be your idea of perfect code. Now compare it to what you do and how you code in your day-to-day job.



This gap is the measure of how much you suck. The bigger the gap is, the more you suck. The smaller the gap is, the less you suck. :)

But today, during the code retreat, is the day that we will practice perfect code. Today we don't need to deliver. Today we have no pressure, besides writing perfect code. That means the objective of a hands-on session like that, is not to finish the exercise, but to practice new approaches, expand our horizons and learn from others. Today we will reduce the gap from what we do in our day-to-day job and the perfect code, providing better value for our customers and being better professionals. "

It's not practice that leads to perfection, it's perfect practice that leads to it.

I also explained the four rules of simple design:
        - All tests need to pass;
        - No duplication;
        - Reveals intention (good naming)
        - Small
       
I have made this letter longer than usual, only because I have no time to make it shorter.
        Blaise Pascal (sometimes also attributed to Mark Twain)
       
Format of the day


After a good breakfast, developers formed pairs and worked on the Conway's Game of Life. We had three sessions in the morning, then lunch and another three sessions in the afternoon. Each session lasted 45 minutes and had a retrospective afterwards where developers discussed their approaches and problems they faced. Then developers deleted the code from their machines. In each session new pairs were formed and worked on the same problem.

  • First session: It was free. Basically the pairs worked with no constraints just to make themselves familiar with the problem.
  • Second session: As a challenge, they were asked to use different data structure other than arrays and we introduced the concept of "primitive obsession".
  • Third session: Developers were asked not to use flags and use polymorphism instead. This was to promote the exploration of abstractions.
  • Lunch: We had nice sandwiches and deserts from a good delicatesse. We had 1.5 hours for lunch. During lunch time, some more senior developers said they haven't been challenged enough so I changed the strategy.
  • Fourth session: In order to satisfy developers from different levels, I asked them to come up with a list of challenges and each pair would then decide which challenge they would take on, according to their level of expertise. The list they came up with was;
    • Maximum 3 lines of code per method;
    • Object-Oriented Programming to extreme.
    • No getters / setters / properties
    • Every line must start with "return" or "final" (Java/C# - functional style)
  • Fifth session: TDD as if you meant it, that means, all code needs to be written inside the test method and then refactored out.
  • Sixth session: Developers were free to do whatever they wanted again but many decided to use some of the challenges from sesson four. 
  • Pub
    
During the sessions, I also asked them to try different testing approaches: outside-in and inside-out. The reason was to compare how different the design would turn up. They were also encouraged to pair-program with developers from other languages, what is an amazing experience and broadens our mind.     

The experiment with each pair choosing the challenge on session four had a mixed feedback. Some developers enjoyed it because they could push themselves. Others said that the retrospective was not so good since pairs were working with different challenges and could not relate to the problems and solutions exposed by other pairs. This is something I'll need to think about for future code retreats. How can I balance the challenges so everyone feels, well, challenged.

Overall, we all had a fantastic day. There were many very interesting discussions during the retrospectives and, according to the feedback, everyone learnt something. I definitely learnt a lot myself and facilitating my first code retreat was an amazing experience that I want to repeat.

I would like to thank Valtech for providing the venue and for the full sponsorship. They provided us everything we needed for this event and were key for its success.

For the full list of attendees, details about the event and more photos, please check http://www.meetup.com/london-software-craftsmanship/events/27600561/

Saturday 20 August 2011

One year of London Software Craftsmanship Community (LSCC)

Without a sense of caring, there can be no sense of community. - Anthony Burgess

Happy Birthday, LSCC!!!!

On 18th of August 2011, the London Software Craftsmanship Community completed one year. And what a great year we had!

How did it all start?

David Green and I had worked together in the past and we kept in touch since. Over one year ago, we were talking to each other about our jobs, pet projects, technologies, etc and we both realised that we couldn't discuss everything we wanted just with the people we knew. We were also aware of our own limitations. So we thought that it would be awesome if there was a group of people that we could meet regularly and share ideas about software development in general.

By then, I was very into the whole Software Craftsmanship thing. David was also very aware of everything that was going on, but we had slightly different views of craftsmanship as a movement. I remember having quite a few interesting conversations with him about that. However, we both always believed in the same principles and values regardless of the labels people were using.

I had been involved with the London Java Community (LJC) even before its existence. At some point I managed to bring David along to one of the LJC's social events. On that evening, David and I had a chat with Barry Cranford, founder of the LJC, and with Martijn Verburg and John Stevenson, LJC organisers and also involved with other user groups and open source communities. We mentioned to them our idea of having a regular meeting where any topic related to software development could be discussed. Maybe show and write some code, discuss design, compare approaches. Completely language agnostic. We also mentioned to them one thing or two about the Software Craftsmanship movement. They all said that we should go ahead and found our own community instead and offered us LJC's support and blessings. I don't think that any of us was really thinking about founding a community. We just wanted to attend this sort of meetings.

David was always a bit more organised than me. But me, I could barely organise a bbq for my own birthday, let alone run a community. We left the pub that night and while walking to the station we though that actually it could be a good idea. Maybe we should give it a go. Why not?

When I got home that night, I went to the meetup.com website and created the London Software Craftsmanship Community.

Summary of our first year

We had our first meeting on 6th of October, 2010 (video). David and I gave a introductory talk on software craftsmanship and for our surprise we had over 100 people subscribed. That was the first sign that our community would take off. Right after we decided to have a monthly meeting called Software Craftsmanship Round-table

The Round-table meetings

This is the meeting that we always wanted to have and that triggered the whole thing. In general they are limited to 25 people. We get together and attendees write the topics they want to discuss on the whiteboard. Any thing related to software development is valid. Then we take a vote. The most voted topics are discussed. Sometimes we discuss just one or two topics, sometimes we discuss up to five topics. No one needs to be an expert on the topic. It's not a presentation. It's just a friendly group discussion.

During the round-table meetings over the year, we had people showing code they were working on, pieces of design and architecture, testing frameworks, and had discussions about a huge amount of other topics. We had discussions about hiring good developers, distributed agile teams, mentors and apprentices, TDD, legacy code, patterns, PaaS comparisons, programming languages, android testing frameworks, the future of web applications, literate programming, DSLs, BDD frameworks, DDD, anti-patterns, specific technologies like Hamcrest, JUnit theories and Spring Roo and many many others that it would be impossible to describe all.

I absolutely love the roundtables and learned a lot from them. Our latest addition to it is a series of lightning talks at the beginning of the night, when people fancy giving one. Another cool thing is that every meeting is different, depending of who is attending, the topics proposed and the ones people voted on. 

Other meetings

During the year we also had a few other great meetings. One was the Software Craftsmanship Panel Discussion - How can craftsmanship move the industry forwards? | video - when we had the pleasure to have Ade Oshineye, Chris Parsons, Dan North and Dave Hoover in the panel. It was great to see them giving their views about many topics relevant to the future of our industry. We had Jason Huggins, creator of Selenium, giving a talk to us about "how to test 'untestable' applications" | video.

We also cross-promoted the Code Retreat Winchester, organised by Despo and Aimee, and the first Cambridge Dojo Day, organised by Alastair Smith, organiser of the Cambridge User Group - CAMDUG.

Future meetings

We will be keeping the monthly Software Craftsmanship Round-table meetings on every second week of the month. From this month onwards, we will have a monthly hands-on session on the last week of the month. Our first one is the Crafting Object-Oriented Code, on the 30th of August. We will be opening the space to our members to submit proposals for any hands-on session they want run in the following months.

We are also very happy to be having LSCC's First Code Retreat on 10th of September.

Our meetings tend to be fully subscribed, on average, in 24 hours after they are announced. We had round-table meetings being booked up in just 5 hours in the past. So, if you want to attend our meetings, make sure you register as soon as you get the email notification.

Community

Throughout the year, we met many extremely passionate and talented people. I learned things that I was not even aware they existed. And that's what this is all about. That's exactly what we always wanted. We met people from all levels of expertise, different backgrounds, working in different industries and with different technologies. All kind enough to share what they know and humble enough to want to learn from others.

LSCC had a lot of support from LJC and we are committed to support other communities as well. With that in mind, we would like to offer our support to any person or group of people thinking to found a software craftsmanship community in the UK or even abroad. We are more than happy to cross-promote any event to our members - if we judge they are relevant to our community and to the software craftsmanship moment as a whole.

The future of LSCC

We have quite a few things in our heads but I don't want to spoil the surprise and neither make promises I may not live up to. But there are a few things I can say. Besides all the regular meetings (round-tables and hands-on sessions), we want to focus more on the Software Craftsmanship movement itself. There are quite a few principles and values that we need to start focusing on. We are already having discussions about some of them so watch this space.

Another thing I personally would like to see is more software craftsmanship communities around the UK and Europe. We will do the best we can to help and support new communities.

As we grow, we will need to do more but one thing is for sure. We will not compromise the quality of our meetings or things we want to do just to bring more people in.

A big thanks

I would like to thank our sponsors - YouDevise, SkillsMatter and Valtech - for their support, for offering their premisses so we can run our events for free and for helping us get fat with all the pizzas and drinks.

A big thanks to all the kindred spirits that support and promote LSCC and, last but not least, a massive thanks to all LSCC members for their dedication to their craft and for making LSCC a great community. You guys rock!

I'm really proud to be a software craftsman and I'm happy to be able to give something back to this amazing community of developers that gave me so much and that helped me to become the professional I am today. Thank you all.

Tuesday 26 July 2011

SRP: Simplicity and Complexity

Simplicity does not precede complexity, but follows it. - Alan Perlis

The Single Responsibility Principle (SRP) - one of the SOLID principles - is definitely one of my favourites principles in Object-Oriented Design. I find its simplicity and, at the same time, its complexity fascinating. I have known this principle for years and wrote about it for the first time over one year ago. Still, I can't stop thinking about how hard it is to apply it. Speaking to and pairing with many developers over the years, I noticed that every single one of them understands what the principle is about but when it comes to write code, either they forget it or they simply can't find a way to adhere to it. I'll give you my view about the problem and what I've seen happening in many occasions.

The outside view

 Every class and method should have just one responsibility

This is what I call outside view and naming plays a big role here.

This view is generally used when we need to add some totally new code. We think what the new code is about, create a class and/or a method, give it an appropriate name that represents what the new code does and we are done. We also use this outside view when reading code. When looking at a class or method name, it should be clear to us what they do.

I don't think anyone ever had a problem understanding this principle.

However, if it is so simple to understand, why don't we all follow it? Why do we still find classes and methods with hundreds, if not thousands of lines? A few things come to my mind to explain that. Maybe we are just bad at naming classes and methods. Maybe the names we give are too generic or too broad, allowing us to write loads of code in there. Maybe some of us just don't care.

The inside view

Classes and methods should have one, and only one, reason to change

This is what I call inside view and it is the other (often forgotten) side of the Single Responsibility Principle.

This view is generally used when we need to change some existing code or add more code to it. That's when we look inside each class and method to see exactly what they do. More often than not, we get frustrated because they do much more than they should do and we need to go through many lines of frustration and WTFs to understand the bloody thing.

However, it is much easier to adhere to the SRP when we keep the inside view in mind instead of the outside view. That means, always think about the number of reasons to change a class or method instead of thinking purely in their responsibilities.

So, when and where do things go wrong?

NOTE: In general I find more SRP violations in systems where developers are not doing TDD and refactoring.

Here is some food for thought. I'm risking to say that the majority of SRP violations are found in the classes and methods that are closer to the interface of the system. For example, in a web application, it's very common to find large controllers, actions or backing bean classes. For swing applications, we tend to find large event handlers. For systems where the entry point is a queue, we tend to find large methods that are responsible for processing the messages. 

In general, this happens because the classes and methods closer to the interface of the system have a more generic and broader responsibility. Quite often, these methods are responsible to trigger loads of business rules and/or complex workflows.

Imaging that the input to our system is a huge XML file representing a trade. Also imagine that the first method invoked to handle that is called "processTrade(tradeXML)", located in a TradeService class. What is the responsibility of this method? It is to process a trade, right? Should it have a different name? Our system is expected to "process" all trades received so it is fair to say that the first method handling the request (or reading from a queue) should be called processTrade.

In another example, imagine that an user added a few items to her shopping basket (web application), provided some payment details and clicked on the "place order" button. In our back end, we will have a method handling this request that probably will be called something like placeOrder(order). Fair, right?

Developing an idea

In general, the closer the code is to the system's interface, the broader and more generic its responsibility will be. The further away the code is from the system's interface, the narrower and more specific its responsibility will be. 

In both examples above, by their names, you can argue that the methods processTrade and placeOrder have a single responsibility. One processes the incoming trade and the other places a customer order. So, when developers take into account just the outside view of the SRP, they feel comfortable to add as much code as they need to satisfy these responsibilities.

The problem is that processing a trade or placing an order may be extremely complicated tasks, where a huge workflow will be triggered, many business rules and requirements need to be satisfied and we will need to write hundreds, if not thousands, of lines for that. So clearly, adding all these lines to a single method doesn't just simply violates the SRP. It's also plain stupid.

So, in order to make our code compliant to the SRP, we need to have just a single reason to change it. This leads to a complementary idea.

In general, the closer the class is to the system's interface, the more delegation the class will do. The further way the class is from the system's interface, less delegation the class will do.

A general example would be, in a traditional Java web application, the controllers, that are closer to the UI, have a broad responsibility and tend to delegate all the business logic to other objects. They just control the flow. At the other end, we have the DAOs that have a very specific and narrow responsibility, almost never delegating anything to another class. In the middle, we have services, that do some business logic of their own but also delegate work to other collaborator classes. Services tend to have a narrower responsibility when compared to a controller but a broader responsibility when compared to DAOs. Still, each class and method have a single responsibility.

Asking a different question

When mentoring and/or pair-programming with other developers, quite often we end up discussing about the amount of code in a method or methods in a class. Just using the SRP's outside view as an argument sometimes is not enough to convince some developers that the code is doing too much. That's why I find the inside view more useful. Instead of asking how many responsibilities a method or class have, I now ask how many reasons we would have to change them.

Monday 18 July 2011

Testing legacy: Hard-wired dependencies (part 2)

In part one, I showed how to unit test a method that uses a Singleton and makes static calls. So now, let's have a look at common code problems we find in legacy code, using the same example:


How many problems can you see? Take your time before reading the ones I found.. :-)

Refactoring
NOTE: When I've done it, I've done it step by step running the tests after every step. Here I'll just summarise my decisions

The first thing I noticed is that the tripList variable does not need to be created when the logged user is null, since an exception is thrown and nothing else happens. I've decided to invert the outer if and extract the guard clause



Feature Envy

When a class gets data from another class in order to do some calculation or comparison on that data, quite often it means that the client class envies the other class. This is called Feature Envy (code smell) and it is a very common occurrence in long methods and is everywhere in legacy code. In OO, data and the operations on that data should be on the same object. 

So, looking at the code above, clearly the whole thing about determining if an user is friends with another doesn't belong to the TripService class. Let's move it to the User class. First the unit test:


Now, let's move the code to the User class. Here we can use the Java collections API a bit better and remove the whole for loop and the isFriend flag all together.


After a few refactoring steps, here is the new code in the TripService


Right. This is already much better but it is still not good enough.

Layers and dependencies

Some of you may still be annoyed by the protected methods we created in part one in order to isolate dependencies and test the class. Changes like that are meant to be temporary, that means, they are done so we can unit test the whole method. Once we have tests covering the method, we can start doing our refactoring and thinking about the dependencies we could inject.

Many times we would think that we should just inject the dependency into the class. That sounds obvious. TripService should receive an instance of UserSession. Really?

TripService is a service. That means, it dwells in the service layer. UserSession knows about logged users and sessions. It probably talks to the MVC framework and/or HttpSession, etc. Should the TripService be dependant on this class (even if it was an interface instead of being a Singleton)? Probably the whole check if the user is logged in should be done by the controller or whatever the client class may be. In order NOT to change that much (for now) I'll make the TripService receive the logged user as a parameter and remove the dependency on the UserSession completely. I'll need to do some minor changes and clean up in the tests as well.

Naming

No, unfortunately we are not done yet. What does this code do anyway? Return trips from a friend. Looking at the name of the method and parameters, or even the class name, there is no way to know that. The word "friend" is no where to be seen in the TripService's public interface. We need to change that as well.

So here is the final code:


Better, isn't it? We still have the issue with the other protected method, with the TripDAO static call, etc. But I'll leave this last bit for another post on how to remove dependencies on static methods. I'll park my refactoring for now. We can't refactoring the entire system in one day, right? We still need to deliver some features. :-)

Conclusion

This was just a toy example and may not even make sense. However, it represents many of the problems we find when working with legacy (existing) code. It's amazing how many problems we can find in such a tiny piece of code. Now imagine all those classes and methods with hundreds, if not thousands of lines.

We need to keep refactoring our code mercilessly so we never get to a position where we don't understand it any more and the whole business starts slowing down because we cannot adjust the software quick enough.

Refactoring is not just about extracting methods or making a few tweaks in the logic. We need to think about the dependencies, the responsibilities that each class and method should have, the architectural layers, the design of our application and also the names we give to every class, method, parameter and variable. We should try to have the business domain expressed in the code.

We should treat our code base as if it was a big garden. If we want it to be pleasant and maintainable, we need to be constantly looking after it .

If you haven't read it yet, check the part one of this post. If you want to give this code a go or find more details about the implementation, check: https://github.com/sandromancuso/testing_legacy_code

Sunday 17 July 2011

Testing legacy: Hard-wired dependencies (part 1)

When pairing with some developers, I've noticed that one of the reasons they are not unit testing existing code is because, quite often, they don't know how to overcome certain problems. The most common one is related to hard-wired dependencies - Singletons and static calls.

Let's look at this piece of code:

public List<Trip> getTripsByUser(User user) throws UserNotLoggedInException {
    List<Trip> tripList = new ArrayList<Trip>();
    User loggedUser = UserSession.getInstance().getLoggedUser();
    boolean isFriend = false;
    if (loggedUser != null) {
        for (User friend : user.getFriends()) {
            if (friend.equals(loggedUser)) {
                isFriend = true;
                break;
            }
        }
        if (isFriend) {
            tripList = TripDAO.findTripsByUser(user);
        }
        return tripList;
    } else {
        throw new UserNotLoggedInException();
    }
}

Horrendous, isn't it? The code above has loads of problems, but before we change it, we need to have it covered by tests.

There are two challenges when unit testing the method above. They are:

User loggedUser = UserSession.getInstance().getLoggedUser(); // Line 3  
   
tripList = TripDAO.findTripsByUser(user);                    // Line 13

As we know, unit tests should test just one class and not its dependencies. That means that we need to find a way to mock the Singleton and the static call. In general we do that injecting the dependencies, but we have a rule, remember?

We can't change any existing code if not covered by tests. The only exception is if we need to change the code to add unit tests, but in this case, just automated refactorings (via IDE) are allowed.

Besides that, many of the mocking frameworks are not be able to mock static methods anyway, so injecting the TripDAO would not solve the problem.

Overcoming the hard-dependencies problem

NOTE: In real life I would be writing tests first and making the change just when I needed but in order to keep the post short and focused I will not go step by step here .

First of all, let's isolate the Singleton dependency on it's own method. Let's make it protected as well. But wait, this need to be done via automated "extract method" refactoring. Select just the following piece of code on TripService.java:

UserSession.getInstance().getLoggedUser()

Go to your IDE's refactoring menu, choose extract method and give it a name. After this step, the code will look like that:

public class TripService {

    public List<Trip> getTripsByUser(User user) throws UserNotLoggedInException {
        ...
        User loggedUser = loggedUser();
        ...
    }

    protected User loggedUser() {
        return UserSession.getInstance().getLoggedUser();
    }
}

Doing the same thing for TripDAO.findTripsByUser(user), we will have:

public List<Trip> getTripsByUser(User user) throws UserNotLoggedInException {
    ...
    User loggedUser = loggedUser();
    ...
        if (isFriend) {
            tripList = findTripsByUser(user);
        }
    ...
}  
 
protected List<Trip> findTripsByUser(User user) {
    return TripDAO.findTripsByUser(user);
} 
 
protected User loggedUser() {
    return UserSession.getInstance().getLoggedUser();
}

In our test class, we can now extend the TripService class and override the protected methods we created, making them return whatever we need for our unit tests:

private TripService createTripService() {
    return new TripService() {
        @Override protected User loggedUser() {
            return loggedUser;
        }
        @Override protected List<Trip> findTripsByUser(User user) {
            return user.trips();
        }
    };
}

And this is it. Our TripService is now testable.

First we write all the tests we need to make sure the class/method is fully tested and all code branches are exercised. I use Eclipse's eclEmma plugin for that and I strongly recommend it. If you are not using Java and/or Eclipse, try to use a code coverage tool specific to your language/IDE while writing tests for existing code. It helps a lot.

So here is the my final test class:

public class TripServiceTest {
        
    private static final User UNUSED_USER = null;
    private static final User NON_LOGGED_USER = null;
    private User loggedUser = new User();
    private User targetUser = new User();
    private TripService tripService;

    @Before
    public void initialise() {
        tripService  = createTripService();
    } 
        
    @Test(expected=UserNotLoggedInException.class) public void 
    shouldThrowExceptionWhenUserIsNotLoggedIn() throws Exception {
        loggedUser = NON_LOGGED_USER;
                 
        tripService.getTripsByUser(UNUSED_USER);
    }
        
    @Test public void 
    shouldNotReturnTripsWhenLoggedUserIsNotAFriend() throws Exception {             
        List<Trip> trips = tripService.getTripsByUser(targetUser);
                 
        assertThat(trips.size(), is(equalTo(0)));
    }
        
    @Test public void 
    shouldReturnTripsWhenLoggedUserIsAFriend() throws Exception {
        User john = anUser().friendsWith(loggedUser)
                            .withTrips(new Trip(), new Trip())
                            .build();
                 
        List<Trip> trips = tripService.getTripsByUser(john);
                 
        assertThat(trips, is(equalTo(john.trips())));
    }

    private TripService createTripService() {
        return new TripService() {
            @Override protected User loggedUser() {
                return loggedUser;
            }
            @Override protected List<Trip> findTripsByUser(User user) {
                return user.trips();
            }
        };
    }        
}

Are we done?

Of course not. We still need to refactor the TripService class. Check the part two of this post.

If you want to give it a go, here is the full code: https://github.com/sandromancuso/testing_legacy_code

Sunday 3 July 2011

Working with legacy code

Context

Large organisations' systems may have from tens of thousands to a few million lines of code and a good part of those lines is legacy code. By legacy code I mean code without tests. Many of these systems started being written many years ago, before the existence of cool things and frameworks we take for granted today. Due to how some systems are configured (database, properties file, proprietary xml) , we cannot simply change a class constructor or method signature to pass in the dependencies without undertaking a much larger refactoring. Changing one piece of code can break completely unknown parts of the system. Developers are not comfortable in making changes in certain areas of the system. Test-first and unit testing is not widely used by developers.

The Rule

In our commitment to make the existing systems better, more reliable, easier to deal with (changing and adding more features), we established the following rule: We can not change existing code if it is not covered by tests. In case we need to change the existing code to be able to write the tests, we should do it only using the automated refactoring tools provided by our IDEs. Eclipse and IntelliJ are great for that, if you are a Java developer like me. 

That means, before we make any change, we need to have the current code under test, guaranteeing that we don't break its current behaviour. Once the existing code is under test, we then write a new test for the new feature (or change an existing test if it's a change in existing behaviour) and finally we are can change the code.

Problem

There is an eternal discussion on forums, mailing lists and user groups about TDD being responsible for the increase or decrease of the team's velocity. I don't want to start this discussion here because we are not doing TDD for majority of the time. With legacy code, we spend the majority of our time trying to test existing code before we can do TDD to satisfy the new requirement. And this is slow. Very slow. It can be, in our experience, somewhere between 5 to 20 times slower than just making the change we need and manually test it.

You may be asking, why does it take so much longer? My answer is: If you haven't, try unit testing all the possible execution paths in a 2000+ line class? Have you tried to do it with a 1000 line method, full of multiple return statements, hard-wired dependencies, loads of duplication, a big chain of nested IFs and loops, etc? Believe me, it will take you a bloody long time. Remember, you can't change the existing code before writing tests. Just automated re-factorings. Safety first. :-)

Why are we "under-performing"?

Quite often, after start following this rule, management will enquire why the team is under-performing. Although it is a fact that the team is taking longer to implement a feature, this is also a very naive view of the problem. When management and development teams talk about team's velocity, they just take into consideration the amount of time taken to write the code related to a few specific requirements.

Over the time, management and teams just forget how much time they spend in things that are caused by the lack of quality and tests in their code. They never take into consideration that there is absolutely no way that developers would be able to manually test the entire system and guarantee they didn't break anything. That would take days, for every piece of code they write or change.  So they leave that to QA.

By not increasing the test coverage, the team will never have a regression test suite. Manually testing the system, as it grows in size and complexity, will start taking longer and longer by the QA team. It will also be more error prone, since testing scripts need to be kept in sync with the current behaviour of the system. This is also waste of time.

Also, just hacking code all the time will make the system more fragile and way more complicated to understand, which will make developers to take longer to hack more code in.

Because we can't press a button and just unit test a specific piece of code, the team is forced to spend a lot of time debugging the application, meaning that the team needs to spend time compiling and deploying it. In certain systems, in order to test a small piece of code, you need to rely on other systems to trigger something so your system can respond. Or you need to manually send messages to a queue so your piece of code is invoked. Sometimes, depending of the complexity of your system and it's dependencies, you can't even run it locally, meaning that you need to copy your application to another environment (smoke, UAT, or whatever name you use in your company) in order to test the small piece of code you wrote or changed. And when you finally manage to do all that to execute that line of code you just added, you realise that the code is wrong. Sigh. Let's start over.

Since I started practising TDD, I realised that I very rarely use my debugger and very rarely have to deploy and run my application in order to test it.

So basically, when people think we are spending too much time to write a feature because we were writing tests for the existing code first, they are rarely considering the time spend elsewhere. I've seen it many times: "We don't have time to do it now. Let's just do a quick fix.". And then, contradicting the laws of physics, more time is created when bugs are found and the QA phase needs to be extended. Panic takes over: "Oh, we need to abort the release. We can't go live like that.". Exactly.




The graphic above is not based in any formal research. It is purely based on my own experience during my career. I also believe that the decrease in the team's velocity is related to the state of the untested code. There are untested code out there that is very well written and writing tests to it is quite straightforward. However, in my experience, this would be an exception.

In summary, if you are constantly applying the "Boy Scout Rule" and always keep improving the code you need to touch, over the time you will be making your code better and you will be going faster and easier. If you don't do that, you will have a false impression of good velocity at start but gradually and quite often without noticing, you will start to slow down. Things that used to take a few days, now take a few weeks. Because this lost of velocity happened slowly (over months or even years), no one really noticed until it was too late and everything now take months.   

Drifting away and losing focus

One interesting side effect of constantly making legacy code better, writing tests and refactoring, is that it is too easy to be carried away. More than once I've seen pairs, while trying to clean a piece of code, drifting away from the task/story they were working on. That also happened to me quite a few times. We get carried away when making progress and making things better.

Very recently I was asked by one of the developers: "When do we stop?". My answer was: "When we finish the task.". In that context, that meant that the focus is always on task at hand. We need to keep delivering what was agreed with our product owners (or whoever the person in charge of the requirements are). So, make the system better but always keep the focus on the task. Don't go crazy with the refactoring trying to re-write the whole system in a few days. Do enough to finish the task and try to isolate the parts that are still not good enough. Baby steps. 

A more positive side effect

Another very common problem in legacy systems is the lack of understanding about the system and also about the business. Quite often we find situations where the developers and business people are long gone and no one really knows how the system behave.

Writing tests for the existing code force us to understand what it does. We try to mine some hidden business concepts in the middle of the procedural code and try to make them very explicit when naming our tests. That is a great way to drive our refactoring later own, using the business concepts captured by the tests. Quite often, we also get the business people involved, asking them questions and checking if certain assumptions make sense.

In writing the tests and refactoring the code, the previously completely unknown behaviour of the system is now well documented by the tests and code.

Quality is a long term investment

In a recent conversation, we were discussing how we could measure our "investment" in quality. A quick and simple answer would be that we could measure that by the number of bugs and the velocity that the teams are delivering new requirements. However, this is never too simple. The question is, why do you think you need quality? Which problems do you have today that makes you think they are quality related? What does quality mean anyway?

When working with legacy, after many years, we tend to forget how things were in the past. We just "accept" that things take a long time to be done because they have been taking a long time to be done for a long time. We just accept a (long) QA phase. It's part of the process, isn't it? And this is just wrong.

Constantly increasing the quality level in a legacy system can make a massive difference in the amount of time and money spend on that project. That's what we are pursuing. We want to deliver more, faster and with no bugs.

It's up to us, professional software developers, to revert this situation showing a great attitude and respect for our customers. We should never allow ourselves to get into a situation where our velocity and quality of our work decreases because of our own incompetence.

Tuesday 21 June 2011

A change in attitude - Legacy code

Attitude is a little thing that makes a big difference.  ~Winston Churchill 
 
Not long ago, I gave a talk about Software Craftsmanship where I asked who liked to work on greenfield projects. Almost everyone raised their hands. Then I asked who liked to work with legacy code. Besides one or two friends that were there, almost everyone kept their hands down.
 
It is always nice to start a project from scratch, be able to choose the technology, use the latest frameworks and have a lot of fun writing code without worrying about breaking existing features or having to understand existing code. Working on greenfield is great, mainly with an experienced and disciplined team using TDD since day one. Progress flows naturally and quickly.
But as soon as we are working with code written by people that are long gone, no tests, no documentation, we go mental. We notice we are going mental by the number of WTF we say during the day. We may get moody and start hating to work on a specific system or in parts of it. Frustration becomes a constant.

A change in attitude

If you don't like something change it; if you can't change it, change the way you think about it.  ~Mary Engelbreit
 
Although I wrote "we" and "us", that was really how I used to feel when working with legacy code. However, in the past few years, I learned many things. An obvious one is that moaning, complaining and cursing won't make my life easier or better. If I want things to be better I need to do something about it.
 
Today, when I look at legacy code, instead of moaning and getting frustrated, my attitude is to try to understand it and make it better, constantly applying the Boy Scout Rule.
As my friend David Green said in a twitter conversation, what I agree 100%, improving and understanding legacy code can be massively rewarding. The process of trying to make sense of a big ball of mud seems daunting but if we just focus in small parts of it, one at a time, and start improving them (writing tests, extracting methods and classes, renaming variables, etc), bit by bit, things become much easier and enjoyable. 

Working with legacy code is almost like solving a big jigsaw puzzle. We don't do that all at once. We start by separating the pieces into groups, often starting with the edges and corners and then separating other small pieces by colour, pattern, etc. We now have a few (logical) groups and we start to form a higher level model in our head. What before was a bunch of random pieces (or a big ball of mud), now is a bunch of smaller groups of random pieces. Still not very helpful or encouraging, but nonetheless some progress. Bit by bit, we start working on one of these groups (parts of the code) and we start putting some pieces together (writing tests for the existing code, which will help with our understanding of the code, and refactoring it).

Once we start putting some pieces together, we start seeing a small part of our jigsaw puzzle picture. We get excited because now it's getting real. It's starting to make sense and we are happy we are making progress. The more pieces we put together the more excited we are about finishing the jigsaw puzzle. The more pieces we put together, the easier it gets to put more pieces together. And that's exactly the feeling I've got when working with legacy code now. For every piece of code I make better, more I want to make the whole code better. The feeling of achievement is really rewarding. What before was something I could barely read and took ages to understand, now reads like a story and every developer can understand it with no effort at all. Maybe when a good part of the code is stable (covered by tests, loosely coupled, well defined responsibilities, etc), I could even introduce the cool and new frameworks that I always wanted to use. I could upgrade some library versions. I could even throw a lot of code away and replace it with a framework because now my code is clean and modularised and replacing one part of the system will not break another. I don't even need to envy my friends working on greenfield projects any more. 

Different challenges 

Another cool thing about legacy code is that it forces you to think in a different way. In greenfield projects, when developing a new feature, we write a test and start implementing stuff. In legacy, sometimes you can't even instantiate a class in order to test it due to all its dependencies. A change in one place can cause an impact in obscure parts of the system. We have an option here. We can see these challenges as a pain in the ass or can be see them as very interesting problems to solve. I prefer the latter.

The professional side 

Although it is OK to have fun and enjoy what we are doing, we always need to remember that we are professionals and being paid to write software. Software is an asset and a lot of money and time is invested on it. As every investment, clients want to maximise the return of their investment. The more we improve and keep the software clean, the longer the client will be able to benefit from it. Stretching the lifespan of a software also maximises the client's return of investment.

Conclusion

At the end of the day, it does not matter if you are working on a green or brownfield project. It's your attitude towards your job that will make it more or less enjoyable.

Tuesday 17 May 2011

Re-drawing my own map: A new milestone

For every step you take towards mastery, your destination moves two steps further away. Embrace mastery as a lifelong endeavour. Learn to love the journey.
--George Leonard, Mastery
It is with a mixture of sadness and excitement that I would like to announce that, after over five years, I'm leaving Valtech on the 18th of May. The decision was not an easy one and took me months to figure out what the next step in my long road would be. As I said in a recent interview, I love working for consultancy companies and that's the main reason I spent over ten years (two-thirds of my career) working as a consultant.  

Working for Valtech

Valtech is a fantastic company to work for and had a huge impact in my personal and professional life. During my time there I had the opportunity to work on a great variety of projects, different companies, different industries and different technologies. Most importantly, I had the opportunity to meet and work with a lot of great people that helped me to become a much better professional.

If there is one thing that I will never complain about Valtech is that I did not have recognition for the work I've done. I have started at a Valtech in a relatively junior role, according to Valtech's grade scheme, and bit by bit, with a lot of support and trust from my colleagues I was given more and more responsibility and gradually climbed my way up to one of the most senior positions.

There is no such a thing as a perfect company but if I had to point out the best thing about Valtech, I would say that, beyond the shadow of a doubt, it is its people. People that I learnt a lot from, that helped me to feel at home in the UK, that helped me with personal issues, people that challenged me, that pushed me to my limits, that gave me constructive criticism, that trusted me and empowered me to do my job, people that helped me to be better.

I may not be in the office or in a client site full time any more but I will always be around. As it happened before (I took a year off to work on a startup idea and came back) I'll always be around for drinks and events.

Special thanks

I would like to thank you everyone at Valtech that had to put up with me for all this time. I know I can be a pain in the neck quite often sometimes. :-)

It's always tricky to mention names since there is always the risk of people left out feeling a bit upset but I feel that I need to thank some people in a more personal level, so apologies for the ones I did not mention. In no particular order: Toby Mckenzie for caring about me and every single consultant during tough times, all his herculean effort to keep every one happy, finding us good projects; David Draper for challenging many of my beliefs and opinions, for the many advices, for supporting my involvement with user groups and events and for the effort in making Valtech a place of excellence; Mashooq Badar for the fantastic time we had together in many projects, for all the things I learnt from him and for making me open my mind about so many things. Ah, and for all the Blazing hot! moments; Phil Hall for the support and keeping the doors open to me and LSCC; Kevin Harkin (I can't believe he does not use twitter) for the fun we had together, for his friendship, advices, ranting sessions and memorable nights at the pub; Andrew Rendell for his professionalism, trust and for being a great role model for every Valtech consultant; And last but not least, Akbar Zamir, for pushing me and challenging me to be better, for all the advice, trust, knowledge and help, for being a great career manager and most important of all, for being a great friend.

Thanks for the great five years that I spent there. It was an absolute pleasure to work with all of you and be part of this great company.

The future

It’s not just a question of conquering a summit previously unknown, but of tracing, step by step, a new pathway to it.
--Gustav Mahler, musician and composer
I'm joining UBS as a senior developer at a director level, starting on the 23rd of May. Due to my involvement with the software craftsmanship movement, this came as a surprise to many people, including myself, mainly because investment banks tend to be almost a hostile environment for agile and software craftsmanship initiatives. When I started re-drawing my own map, investment banks were an avenue that I was not considering to explore.

As I said before, choosing my next step was not easy. I had a few things in mind that were non-negotiable: I wanted different challenges, that means, things that I haven't done before, keep having fun and loving my job, a potential long term commitment where I would have time enough to put into practice many ideas and beliefs and most importantly, have a long term career as a software developer but with a lot of space to keep growing as a professional.

I was fortunate to have had many opportunities during this time but the majority of them could not satisfy all the items above. I was determined to keep doing what I had been doing throughout my entire professional life that is just to work for companies that I really want to work for, I mean, companies that would be able to offer me what I was looking for at that point in time. For me, that's the best way to keep fuelling the passion that I have for what I do. Joining a company just because of money is and always has been totally out of question.

UBS came along with a very interesting proposition. They want to improve the quality of their software and recognise that agile and software craftsmanship are a great way to get there. They were interested in people with no previous investment bank experience, what is very unusual for an investment bank. They want people that can think different, that are passionate and can help them drive this transformation. I had five interviews and was very pleased to see so many people striving to be and do better.

As far as I understand, my main role will be to work as a hands-on developer, embedded in a team, helping to improve quality, leading by example and mentoring other developers. They also expect me to give internal talks, training, promote events, disseminate passion and promote the craftsmanship values and techniques. In the future I'll be working with other teams in the UK and in other offices around the world. But make no mistake. I'll have a hell of interesting and tough challenges ahead of me and I hope to live up to all their expectations.    

Besides that, I'll keep running the London Software Craftsmanship Community (LSCC) alongside my friend David Green and try my best to give something back to the wider and great community of software developers out there that some many times I benefited from.

Thanks everyone for being part of long road journey.