When you inherit difficult code it can take weeks to become productive. Having the right tools for the job and knowing how to use them makes a huge difference. These videos show you how.

Sometimes you don’t know what a piece of code is supposed to do, but you do know that people are using it in production, and that it in some sense ‘works’. One approach I often use in this situation is Approval testing. It can get you test coverage quickly without having to understand the code.

Since you don’t know what the code is supposed to do, you can’t define in advance what results you expect. But, what you can do is run the code, accept whatever it does as ‘correct’, then invent scenarios that will exercise all the code branches. I’ve made a video of me doing just this on some rather hairy legacy code – The Gilded Rose Refactoring Kata. With the right tools the tests fall into place relatively easily.

I’d like to credit Llewellyn Falco who showed me this way to solve this exercise.

I recorded a screencast in three parts. This is the first part.

Part 1: Introducing the Gilded Rose kata and writing test cases using Approval Tests

About the Gilded Rose code

One of the exercises I’ve used for years to help programmers improve their skills is the Gilded Rose Kata. It’s a refactoring kata – the code needs cleaning up and tests adding so you can build a new feature. That is a realistic scenario that programmers often face in everyday work, but this exercise adds a fantasy twist. The code you have to work with keeps track of various magical items stocked at the Gilded Rose establishment. The new feature concerns support for “Conjured” items that have slightly different magical properties from the other items. The scenario is just weird enough to be fun and just realistic enough to be a useful exercise.

I didn’t design the kata originally, that was Terry Hughes. I spruced up the code a little to make it a better exercise and added some extra instructions to get you going. I also translated the starting code into a few different programming languages and put it up on GitHub. In the 5 years since then I have been delighted to see how popular it’s become. I’ve had over 50 contributors chip in with various translations and improvements, and at least 800 people have forked the project and presumably had a go at the refactoring.

I think the appeal of the exercise is partly the wacky scenario it throws you into, and partly how utterly terrible the code is at the start. If you do the refactoring well it actually looks really neat at the end, which is very satisfying.

Lift-Up Conditional

When you inherit difficult code it can take weeks to become productive. I’d like to show you the difference it can make when you have the right tools for the job and know how to use them.

Once you’ve got good tests in place you can refactor much more confidently. In my previous post I showed how to get good tests using Approval Testing. I’m pretty confident in these tests, so I’ve made a second video showing some initial refactorings I’d do to get this code cleaned up a little.

One of the techniques I’m using is called ‘Lift-Up Conditional’. It’s a manipulation of a long complex conditional statement that will let you group together all the statements related to one particular conditional. I haven’t seen this particular refactoring described in the literature before – it was Llewellyn Falco who showed it to me originally. It’s perfect for the Gilded Rose code which basically comprises one big complex conditional.

The other star of this show is IntelliJ. It has a lot of automated refactorings that come together to make ‘Lift-Up Conditional’ easy and it makes really short work of cleaning up this code.

This is the second screencast in the series. My aim is to show that with the right tools and refactoring know-how you can quickly become productive with the code, even without fully understanding the byzantine business rules.

Part 2: Refactoring item logic using ‘lift up conditional’

Replace Conditional with Polymorphism

When you inherit difficult code it can take weeks to become productive. I’d like to show you the difference it can make when you have the right tools for the job and know how to use them.

Once you’ve got the code cleaned up to the point where you can see the parts of the logic that belong together, you can start to create a better class structure. A classic refactoring for this is ‘Replace Conditional with Polymorphism’ which was first described in Martin Fowler’s book ‘Refactoring’.

The basic idea is that you create subclasses to encapsulate the logic concerned with each logical case. Your design becomes much more flexible if you need to add new types that are variations on types that are already there – as in this case.

This is the third screencast in the series. My aim is to show that with the right tools and refactoring know-how you can quickly become productive with this code, even without fully understanding the byzantine business rules.

Part 3: Replace Conditional with Polymorphism


Three factors affecting your agility

Let’s talk about cakes and baking. It’s similar to making software. No really! How quickly you can bake a fantastic cake depends on three main factors. Turns out, it’s the same three for software.

Note: This article was first published on Praqma’s blog

In essence, agility is about your ability to respond to change. I can gain a competitive advantage if I can update my software quickly when I see an opportunity in the market. As a software developer, I’m going to work together with other professionals to decide what new features to build at any one time. The important question is, when we’ve agreed on a particular change and realized the cost of delay is significant: how quickly can my team and I make this change?

How quickly can you make a change to your software?

Allow me to answer that question by comparing it with baking. How long does it take to bake a cake? As with software, I think there are three main factors.

The first factor is how complex a cake it is. How many layers? How many kinds of filling? How fancy will the decorations be? Similarly, changes to a piece of software vary in how big and complex they are, and that will affect how long they take.

The second factor is the skill of the baker(s). When you make fancy flowers out of sugar paste how convincing are they? Can you whip cream without it turning into butter? Do you know how to use a thermometer to get perfectly thick and creamy egg custard? If your skills are poor, you might need to throw out your first attempt and make a second batch of custard or cream or flowers, which obviously slows you down. Developing software is similar – skill, experience and knowledge of particular tools all come into play. If your code changes are poorly designed and fail the tests or the code review, that can similarly slow you down.

When baking, the next major factor for how long it will take is the kind of kitchen you’re going to work in. If I’m a contestant on a show like Bake-Off, I will have a sparkling clean workbench and all the gadgets and accessories I could possibly need. Dirty bowls and saucepans vanish as if by magic when the camera is turned the other way. Fantastic mouthwatering creations appear in a very short space of time.

In contrast, if I’m at home, I might need to clear a space on a worktop before I can start. I could waste valuable minutes hunting around for an electric whisk attachment in an overfull drawer. I might belatedly realize my cake tin is too small for the project I have planned or that I set the oven to the wrong temperature. Creating that amazing cake is not going to be as quick and smooth as it could be.

Time to Bake Cake Equation

The worst conditions for baking that I’ve experienced were probably in my shared student house at university. Not only were accessories like whisks and cake tins hard to come by, a huge pile of dirty dishes obscured the sink most of the time. After some weeks, we discovered one of the third years had decided his final exams were so important that he had started to leave all his washing up “for the first years to take care of”, as he put it. I hope you don’t have anyone like that on your team!

Unhappy Chef

In the same way, how long it will take you to build a feature will depend on the state of the environment you’re working in. For a software developer, that environment includes not only the build tools and programming language as you would expect, but also the state of the existing code. Is it clean and easy to understand? Is the current design amenable to the planned change? You might need to spend time cleaning up and fixing things before you can start.

There’s also the build and deployment pipeline the team has set up. Are the regression tests quick to execute and generally passing? Is the deployment automated? Can I observe logs and find bugs in production? If that infrastructure is well oiled and running smoothly, it will make a big difference for how soon my software change can be rolled out.

Time to Build Feature Equation

If you want to be really agile, you need to consider how to improve some or all of the factors in this equation. If you want to build complex, valuable features quickly, you need to make sure you have developers with the skills to build them. You also need to invest in the “kitchen” they are working in.

When I consult with different organizations, I often see problems with developer skill and poor development environments. Investment in both can lead to big gains in agility. You want the time to market for a new feature to be dominated by the essential complexity of that feature, not the accidental complexity that comes from poor code quality, testing and deployment automation. Coding is like baking. Working in a mess is not agile!

A write-up on learning away from work

Note: this post originally appeared on Praqma’s blog

Do you work on any hobby coding projects in your free time? Practice code katas? We all wish we could, but making time for learning away from work isn’t possible for everyone. So, who should pay for learning time?

Recently, I took part in a panel discussion at the Software Craftsmanship Conference in London. One of the questions from the audience was about finding time to learn new skills. Bob Martin, sitting to my right in the picture below, talked about the importance of spending your free time on reading, practicing code katas, and generally sharpening your skills. He said that we need to be able to call upon those skills when there’s a deadline and production software needs to be built. He also said that it’s unrealistic to think these skills can be acquired on the job. That practice needs to be done beforehand, at home, on your own time.

Picture from@cyriux

I agree strongly that software developers need to learn throughout their career. As professional knowledge workers it’s crucial for us to keep up to date and continually expand our toolboxes. Skills like Test-Driven Development (TDD) take time and practice before you become effective with them. Our industry moves very fast and new tools and techniques come along frequently.

I also agree that you need to practice in safe situations before applying a technique in production code. When I see badly designed code it’s often due to developers not fully understanding the libraries and frameworks they use. This causes them to skip testing or do it badly. What’s more, they often also lack techniques for refactoring and can’t improve the design once they’ve learnt more.

The problem is only getting bigger

Software is taking an ever larger role in our society. Bob Martin pointed out in his keynote speech that there is very little you can do in this life without interacting with computers and the software they run. You can’t buy anything, watch tv, do your washing, or probably arrange to meet your friends and go out for a drink without some form of interaction with information technology. Software is everywhere and skilled software developers are needed now in unprecedented numbers.

Not everyone has free time for this

I agree with Bob Martin about the problem: developers need to improve their skills. However, I just don’t think it’s realistic to expect people to spend their free time on this. At least, not in any sustained way and over a whole career. I actually think it’s pretty unhelpful to suggest this should be the main way skill acquisition happens. Several people at the conference agreed with me – not people in the panel, I should say – but regular conference attendees. At least half a dozen people approached me the following day and thanked me for saying this.

At times in my career I have had the luxury of enough free time to spend some of it on learning, reading, practicing and improving my software development skills. But at other times I’ve had family commitments, caring responsibilities, and other priorities that have completely prevented this. Expecting people to learn skills like TDD solely in their free time will cut off a large section of software developers from progressing and becoming more productive. We need those developers too!

Let’s look at better solutions.

One consequence of the current shortage of skilled software developers is our ability to vote with our feet. If your employer does not provide paid on-the-job time for learning, you can probably find another one that will. I am very happy to work for Praqma where our policy is that everyone should spend a good proportion of their time studying, going to conferences, reading, giving internal seminars and generally keeping themselves updated on what’s going on.

Giving developers time to learn makes good business sense in a competitive world where attracting and retaining skilled people is an advantage in the marketplace. You have the power to choose your employer. I don’t think Praqma is the only company that has realized providing time for learning is attractive to smart people and actually a win/win proposition. There may be a similar company close to you too. Have a look around!

What if I can’t change jobs?

Just as having free time for learning can be an unattainable luxury, there may be times in a career where changing jobs is not an option either. In this case you may need to talk persuasively with your manager and affect change from within. I really believe that a developer who improves their skills will work more effectively and be a bigger asset to their team than one who works only on production code and never does any practice. I think you should be able to persuade your boss that a small investment in training time now will reap dividends later.

I’ve also seen people spending a lot of time at work on code that never makes it to production. Have you seen that? Can you bring your boss examples of time you’ve wasted on proof-of-concept projects that never got to production, or long-lived feature branches that were impossible to merge and had to be thrown away? Perhaps you could spend some of that time practicing instead, and avoid some of those costly mistakes.

We need industry-wide skill acquisition

I think Bob Martin is right about the problem but wrong about the solution. When asked how an individual can improve their skills the answer can’t rely on them using their free time. It’s elitist, only those with that luxury of having free time will be able to do it. We need training and skills acquisition on a broad front that will work for the majority of developers. I think employers must put up some time for this as part of the working week. As individual developers we can argue for this, and vote with our feet if necessary. The learning of new skills shouldn’t be a luxury that’s only available to those with free time on their hands. Software, and its role in our world, is too important to rely on such a tenuous and poorly distributed resource.

Note: this article was first published on Praqma’s website

Experiences Pairing with Llewellyn Falco

How does a Technical Agile Coach improve work in a development team? When Llewellyn Falco asked me to pair with him at a client I jumped at the chance to see how effective mob programming is for introducing technical agile practices.

Day one: head first into the mob

My first day as a visiting Technical Agile Coach begins with coding, in a mob. All the developers in the team and I enter our names into a mob timer. It will prompt us to switch roles every 5 minutes, so we will all take a turn at the keyboard. Llewellyn takes the facilitator role, sitting at the back. I find mob programming is great way to get to know a team and their codebase. After only a few minutes, I take the Driver role, which forces to very quickly pick up what’s going on. I need to understand both the current task, the IDE and the particular code we’re working on. The Navigator prompts me and the whole team helps me to find where to click and what to type.

Llewellyn has worked with this client on and off for half a year, and he was here all the previous week. This team has quite a bit of experience mob programming with him and a couple of other visiting coaches. Llewellyn gets involved facilitating the mob from time to time, usually to draw our attention to some improvement we could make in the code, or in the way we’re working together. When the team is stuck, or going in the wrong direction, he will step in and take the Navigator role for a while. That can happen when we’re doing a tricky refactoring, or if he spots we aren’t taking full advantage of our tools.

After 90 minutes the team has to go to their stand-up meeting. Usually we’d mob for about 2 hours with a team, but today we have a longer breathing space before the Learning Hour. Llewellyn and I take the chance to discuss the challenges this team is facing and how we can coach them more effectively when we meet them again tomorrow. Later this week he’s going to get me to take the Facilitator role and he’ll be in the mob instead. Next week he’ll fly home and leave me here for a week coaching by myself, so we’re already preparing for that handover.

2

The Learning Hour

The Learning Hour is a fixture in the calendar of everyone in the department. It’s one hour devoted to learning new techniques in software development, every day, led by Llewellyn or a visiting coach like me. Not everyone can make it every day, so the planned topics are circulated in advance with an indication of whether it’s a coding session or not. When it’s coding not as many managers/scrum masters/product owners turn up. Actually some of them do enjoy attending these more technical sessions to get a better insight into what challenges their developers are facing.

The lesson I’ve decided to begin with uses the Tennis Refactoring Kata, an exercise I’ve done many times with teams. I am hoping it will be fun and not too difficult, especially compared with the production code they are used to. The exercise has comprehensive unit tests that quickly fail if you make a mistake. The developers aren’t used to having that, and they soon find they like having fast feedback on the accuracy of their work.

Lunch dating

Lunch is next up, and it turns out I’m not eating with Llewellyn. He’s set me up to go out with one of the developers from a team I won’t otherwise be working with. It’s a very deliberate policy Llewellyn has to help me to get to know the wider organization outside of the teams I mob with. He’s found that daily one-on-one chats with key people preferably in a social setting, is an effective way of becoming well-connected in an organization. Today it also gives me an opportunity to offer some career advice to an ambitious developer in a similar position to where I was ten or so years ago.

After lunch Llewellyn introduces me to a second team that I’ll be mob programming with, then leaves me to it. He’s confident this team is working well together and it will be straightforward for me to facilitate without him. We get stuck straight in to some front-end development work, improving a new account creation form. My javascript is a little rusty, but I find that’s not really a problem – they know their tools. I just need to keep an eye on how the mob is running, and think a little outside the box. I spot that what they’re doing will likely break some of the automated GUI tests, so we have a chat about how to handle that.

In the meantime, Llewellyn is working with a different team who are new to him. He begins teaching them the basics of mob programming, and getting to know their specific challenges. A future visiting coach might get to work with them once they’re up to speed.

Managing up and down

At the end of the session, we take a short break together and discuss how things are going. We have a little slack in our schedule, and Llewellyn spots one of the senior managers having a coffee. He takes the chance to greet him and book a short meeting the following day. Llewellyn’s heard there are plans afoot to break apart some of the teams, and he wants to ask the boss to protect a particular team from that reorganization because they are really starting to gel and mob well together.

For the third mobbing session of the day Llewellyn and I are pair-coaching again. It’s similar to the first session. All the teams we’re working with are really struggling with code quality and lack of automated tests. Even if ostensibly we’re working on adding a feature, most of the time we’re addressing code smells and adding unit tests.

The last thing Llewellyn and I do before we leave for the day is send a very short email to the department managers – the people authorizing our invoices. We write one sentence about each mobbing session and the learning hour, summarizing what we’ve done. It makes our work more visible to the decision makers.

Moving in the right direction

I’m impressed with how much Llewellyn and the other visiting coaches have already achieved with these developers. Most people have a positive, curious outlook, and consider learning new skills to be a normal part of work. Llewellyn will often pause the mob timer, pull out his laptop, and spend five minutes showing some relevant presentation slides. Some of the developers here know certain refactorings so well I find myself learning techniques from the teams not just from Llewellyn.

3

Optimising for when we’re not there

That’s not to say there aren’t problems. The codebase is still large, badly structured, slow to build, and lacking automated tests in many areas. Many developers in the mobbing teams are relatively new to the company, and most have little previous experience of Test-Driven Development or refactoring techniques. However, their starting point isn’t what’s important, the crucial thing is that they are continuing to improve and learn. What we’re doing here is creating momentum in the right direction, teaching skills and strategies so people can continue to make things better when we’re no longer present.

4

The wider organisation is also just beginning to adopt Agile practices and DevOps, and it’s not working smoothly yet. Many teams are still sitting in cubicles. The test, build and deployment infrastructure relies too much on manually executed steps.

There are several other agile coaches here at the same time as Llewellyn and me who are more focussed on improving process and product management. Later in the week I attend a sprint demo where there is much talk of A/B testing and hypothesis-driven development. People seem really keen to understand their customer needs and to verify they are building the right thing. The thing is, the starting point is less important than the direction of travel.

After a week of pair-coaching I feel confident I can pick up and continue Llewellyn’s work with the development teams at this client. I’ve got to know the people, the particular challenges they face, and have a structure in place that will let me continue the changes Llewellyn is initiating. I’m actually quite surprised how smoothly the handover has gone.

Visiting Technical Agile Coach

Not many coaches are generous enough to invite visitors to pair with them. Llewellyn has a whole list of people he’s inviting to visit in 2018, and I feel lucky to be one of them. It seems to me that everyone’s a winner. Of course Llewellyn wants to show off and spread his coaching methods to the visitors, but also to learn from them and get their feedback on his work. At the same time the client gets the benefit of teaching & advice from many different visitors. They do have to pay two coaches rather than one during the week we overlap, but having such a smooth handover gives them the ability to get more weeks of coaching than Llewellyn could provide by himself. So far the client seems to feel it’s worth the additional expense.

Taking what I’ve learnt home with me

I plan to start recommending this style of Technical Agile Coaching to my clients back home in Sweden. For a start I really enjoy coding, mobbing and teaching all day, but more importantly it seems to be more effective than what I’ve been doing until now. For years I’ve used Coding Dojos to teach the theory and practice of TDD, but all too often the initiative fizzles out and the dojos stop happening when I’m no longer there.

I think this combination of daily mob programming sessions with a learning hour is particularly effective at teaching both theory and practice. The lunches, the presence of other agile coaches, and sending daily summary mails connects me better with the wider organization. This has been a really valuable two weeks for me. I feel pair-coaching with Llewellyn has taught me an effective way to introduce technical agile practices and change developer behaviour for the better.

5

This post was originally published on Praqma’s blog

A short story about Pre-tested Integration

the three

Continuous Integration and Code Review are strongly correlated with success. Many use Pull Requests for code review, but for co-located teams this can be an obstacle for CI. Is there a better way?

There are three developers on the (fictitious) team: Annika, Boris and Carol. Annika is a recent hire, fresh from university, Boris is the team lead, and Carol has been around the longest. Each of them is working on a different task. They all synchronized their work with their shared master branch when they arrived at the office today, and now it’s approaching morning coffee time. They have all made some changes in the code which they’d like to share with the rest of the team.

Annika is working on a local branch called ‘red’. She checks it’s up-to-date with master and pushes it to a remote branch named ‘ready/red’. It’s similar for Boris and Carol. They are on blue and orange branches respectively and push their changes to ready/blue and ready/orange.

the three

The Build Server is set up so that it detects new branches on the Version Control Server that follow a naming convention. Any branch beginning with ‘ready/’ is scheduled for integration, and only one of these integration builds runs at a time. The Build Server delegates builds to one or more agents,and since the ready-job agent is idle, it picks up the ‘ready/red’ change straight away and leaves the other two ready-branch builds in the queue.

build servers

The build job has several steps. First, the agent merges the ready-branch into a local copy of the master branch. Annika’s changes get a simple fast-forward. The agent performs a full build, static analysis, code style check, and unit test. Everything goes well, so the agent pushes the merge result up to the Version Control Server and posts a message on the team message board.

Things start out similarly for Boris’ ready/blue branch. The build agent takes a copy of master from the git server and merges in the ready-branch. This isn’t a fast-forward merge, since there is a new commit in master for the ‘red’ changes, but it’s still ok. So long as the agent can do the merge without finding any conflicts the build can continue.

The agent then proceeds to the next build steps. Unfortunately, Boris hadn’t noticed that one of his changes caused a test failure. The team has previously agreed that the code in master should always pass the tests, so this means Boris’ changes shouldn’t be shared. The build agent sends a message to Boris telling him about the failed tests, discards its merged branch, and moves on. Carol’s ready/orange branch is up next. The build agent starts again with a fresh copy of the latest master taken from the git server. Carol’s changes also merge without difficulty and this time both build and tests pass. The build agent pushes the merge commit to the server and notifies the team.

build servers

Boris and Carol are having a cup of coffee while they wait for the build server to integrate their changes. Annika is chatting with the Product Owner about the new feature she plans to work on next, ‘cyan’. When they get back to their desks they see the messages from the build server.

Annika is happy to see her changes integrated successfully. She fetches the latest master from the remote git server. She’s now completed the work on the ‘red’ task, and her changes should undergo a code review. She marks the ‘red’ task as finished in the issue tracker and adds an agenda item to the team’s next scheduled code review meeting, which is later that week. Annika selects a new task to work on and checks out a local branch from master called ‘cyan’. Boris sees the message about his failed tests and realizes immediately what he missed. He’s a little embarrassed about his mistake, but happy his teammates are not affected. They may not even notice what’s happened. Boris takes the opportunity to merge the latest changes from master into his ‘blue’ branch. He is quickly able to address the problem with the tests and pushes an update to ready/blue. The build agent gets to work straight away.

Carol is not finished with the ‘orange’ task, but is happy to see her initial changes integrated successfully. She fetches master and merges it into ‘orange’ before continuing work there. She’s noticed a design change that would make her task easier. She plans the refactoring in steps so she can push small changes frequently as she completes the re-design. Sharing her changes with the team often will make it easier for everyone to avoid costly merges. Later that week, in the code review meeting, the team looks at Annika’s changes for the ‘red’ task. It represents a couple of days’ work. The code review tool presents a summary of all the commits involved and they discuss all the changes in the development of the ‘red’ feature.

Unfortunately, Boris and Carol are not happy with a part of the design Annika has made and the code formatting needs improving in places. The outcome of the meeting is that they agree to pair program with Annika on a refactoring of the design, and encourage her to initiate informal design discussions more often during development. The idea is that the more experienced developers, Boris and Carol, should help Annika to learn better design skills. The team finds the code-formatting issues a bit annoying since this kind of detail shouldn’t be in focus for a code review meeting. They create a task to improve the code-style checker in the pre-tested integration build to catch any similar code formatting problem in future.

Commentary

This development process is working really well for Annika, Boris and Carol, and pre-tested integration is a small but important piece. They are not using pull requests, but they have checks on what code is allowed into the master branch, and they have good code-review culture. Integration to master happens at a faster cadence than the flow of work-items. That’s important. Integration is less painful the more often you do it and you might not want to break your work items down to the same small granularity that would be best for code changes. You also don’t necessarily want to delay your integration by waiting for a teammate to review your pull request.

Strictly speaking, this process is not Trunk-Based development since there are more branches involved than just trunk, but so long as the integration is frequent in practice it’s indistinguishable. The benefit of this over Trunk-Based development is, of course, that Boris or any other developer can’t unwittingly break master for the rest of the team.

If you’re using Jenkins you can easily automate the integration process with our Pretested Integration plugin. It’s not difficult to implement this functionality yourself for other build servers. Whichever approach your team chooses, I recommend you settle on a process that results in frequent integration together with collaborative and constructive code-reviews.