Old Dogs, Old Tricks

Given what I do for a living, I tend to get pretty much daily practice at the fundamentals of code craft like TDD and refactoring. And, after 27 years of professional programming, I would probably still make time every day or once a week to mindfully practice this stuff.

Why? Because – from experience – I believe that these aren’t skills you learn once and then retain indefinitely. On occasions when I’ve been away from code for an extended period, coming back to it I found myself doing sloppy work. I’d forget to do things. I’d fallen out of certain habits.

And I also don’t believe these are binary skills. There’s unit testing, and then there’s unit testing. Not all unit tests are created equal. Some are easier to understand than others. Some are less coupled to the implementation than others. Some run faster than others. Some cover more examples with less code than others. Some teams say “We do unit testing” and their code is still riddled with bugs. Some say “We do unit testing” and their code hasn’t had a bug reported since it went live.

No matter how good we think we are at writing tests or making design decisions or refactoring our code and so on, there’s almost always room for improvement. And as we gain experience in these skills, improving takes more and more work.

As a guitar player of some 30 years, I know that the hour or two of practice I get maybe twice a week these days barely keeps me at the level of technical ability I reached 20 years ago. Most of the visible progress I made happened in the first 5 years of playing. But there’s no top to that hill. If I stop practicing for a while – which I have for the last year or so for various reasons – the ball rolls back down. It takes some ongoing effort just to keep it where it is.

It feels the same with code craft: so many managers who came from programming backgrounds tell me that they lost their skills after a few years away from the code. Indeed, many put themselves on my courses just to try and keep their hand in. Use it or lose it.

An hour or two of mindful practice keeps me where I am as a programmer. It takes an hour or two more to move the ball uphill a bit. This is why I’m such a strong advocate of 20% time for developers. At the very least, half a day a week needs to be set aside to learn, to practice, and to try new things. Or an hour a day. Or however you want to slice it.

Putting aside no time – and I’ve seen this so many times – doesn’t just lead to dev teams who don’t improve, it leads to dev teams who progressively get worse. The code craft muscles atrophy, habits get lost, teams get sloppy, code gets crappy, and delivery slows down to a crawl.

If you prefer a mechanical analogy, think of development as a steamboat. Your goal is to deliver goods from London to New York, sailing every two weeks back and forth across the Atlantic. How much time do you set aside to maintain the engine? None? That’s just not sustainable. How many trips could you expect to make before the engine failed?

The developers on your team are the delivery engine of your software and systems. Their skills – not just technical – need regular maintenance, or the engine breaks down. Set aside some time and put aside some budget to help keep the team in good delivery shape. Not just the occasional training day once or twice a year; a regular investment in building and maintaining their skills. Once a week, or an hour a day – whatever works in your organisation.

(You may be thinking “Hey, we pay them to work. They can learn in their own time.” And that might explain why your efforts to increase diversity on your teams haven’t worked.)

My closing message here is that it’s not just junior programmers who need to work on the fundamentals. We all do.

Here’s a tip from an old dog: a great way to reinforce knowledge and skill is to teach them. My advice for managers is to combine regular practice with mentoring. Your more experienced developers mentoring new hires will find – as I have – that the mentoring process forces us to really think about not just what we’re doing, but why we’re doing it. And it encourages us to be perhaps that little bit more exacting about how we do do it, because we’re trying to set a good example. It’s us as programmers, but in our Sunday best.

Just 3 1-day Client Site Workshops Left

A quick plug for the remaining 1-day client site workshops I’m running to celebrate 10 years of Codemanship.

These code craft training workshops are for groups of up to 20 developers, and can be delivered anywhere in the UK for the never-to-be-repeated price of £1,995. That’s as little as £99.75 per person.

Dates remaining are Thurs Aug 15th, Tues Aug 27th and Thurs Aug 29th. You can choose from an action-packed TDD workshop, refactoring workshop or unit testing workshop. All hands-on and jammed full of practical and useful ideas.

Booking’s easy: whip out that company credit card and visit our Eventbrite page.

Code Craft is More Throws Of The Dice

On the occasions founders ask me about the business case for code craft practices like unit testing, Continuous Integration and refactoring, we get to a crunch moment: will this guarantee success for my business?

Honestly? No. Nobody can guarantee that.

Unit testing can’t guarantee that. Test-Driven Development can’t guarantee that. Refactoring can’t guarantee it. Automated builds can’t guarantee it. Microservices can’t. The Cloud can’t. Event sourcing can’t. NoSQL can’t. Lean can’t. Scrum can’t. Kanban can’t. Agile can’t. Nothing can.

And that is the whole point of code craft. In the crap game of technology, every release of our product or system is almost certainly not a winning throw of the dice. You’re going to need to throw again. And again. And again. And again.

What code craft offers is more throws of the dice. It’s a very simple value proposition. Releasing working software sooner, more often and for longer improves your chances of hitting the jackpot. More so than any other discipline in software development.

The Mentoring Paradox

I recently ran a pair of Twitter polls asking experienced developers if mentoring was an official part of their duties, and asking inexperienced developers if they received regular dedicated mentoring.

It’s a tale in two parts: 3/4 experienced devs said mentoring was part of their job, 8/9 inexperienced devs said they don’t get regular dedicated mentoring.

At first glance, this might appear to be a paradox. But I think it can be explained with two extra pieces of information:

  • Our profession is a pyramid, with the most experienced developers greatly outnumbered by less experienced developers
  • Opinions differ widely on what we mean by “mentoring”

Some developers equate mentoring with practices like pair programming. If an experienced developer pairs with a less experienced developer, they might class that as “mentoring”. What we’ve found at Codemanship, though, is that pairing != mentoring necessarily. It’s unstructured, lacks clear goals for what the mentee needs or wants to learn, and is often done in a naive way by people who may well be technically strong but who lack mentoring skills and experience. And we also need to remember that pair programming’s still pretty rare. Most employers don’t allow it.

A lot of new developers report that pair programming with experienced developers can be a frustrating and demoralising experience. Being a great violinist doesn’t necessarily make you a good violin teacher. In a lot of cases, whatever the mentor thinks they’re doing, the mentee doesn’t see it as mentoring.

The other problem with this kind of ad hoc it’s-kind-of-mentoring-but-not-in-a-structured-way mentoring is that it promotes mostly reactive learning. Mentees learn stuff that just happens to come up. To give a developer a solid and well-rounded foundation in dev fundamentals, there needs to be a game plan, and thought needs to be put into creating the necessary learning opportunities within a reasonable timeframe. This necessitates a balance with proactive learning. Even some of the most advanced employers I speak to admit they have no such plan, and little time and resources dedicated to creating the necessary learning opportunities.

To give you an example, let’s imagine we agree it’s time a new hire learns how to refactor Feature Envy. In a reactive environment, we wait until Feature Envy crops up. In coaching developers, I’ve learned that it can be a long wait. And when it does crop up, we may be too busy or distracted dealing with the 1,001 other things we need to think about to take advantage of the opportunity. You need to be super-super on the ball. It’s far easier to enccourage the team to “bottle” code smells* before they eliminate them, so a learning opportunity like this comes ready-made and easy to locate.

*Check in the code with a commit message that identifies the location of the code smell

We found that devs learn refactoring skills much faster when the opportunities to practice come ready-made like this. (There’s also the side effect when a team does a lot of refactoring that certain code smells get eliminated completely from the code base. Like diseases we wiped out, there is value in keeping some samples in the freezer to experiment on.)

Bottling code smells takes extra thought and effort. Practicing refactoring on code smells that have already been eliminated adds no value to the current code base. Proactive learning comes at a cost that most employers are unwilling to pay. So, instead, they pay in an increased cost of changing code, with the knock-on effect that has on their business. (And I’ve seen a high cost of changing code kill some pretty big businesses.)

Effective long-term mentoring of junior developers costs time and money. There’s no way around that – no magic fix, no silver bullet. You’ll need to give junior developers time out for proactive learning. You’ll need to sacrifice the “productive” time of senior developers to provide good mentoring – which includes time to plan and prepare to mentor. (I spend a good deal of my time learning stuff so I can stay one step ahead of devs I’m mentoring – learning the shiny new languages, tools and techniques – filling the gaps in my knowledge before I try to fill the gaps in theirs.)

Nowhere is this more evident than in the UK government’s Software Developer Apprenticeship programme. While there are some shining beacons who do a superb job with apprentices, I hear from many employers who grossly underestimated the investment they’d have to make – especially in dedicated structured mentoring. There are too many places where apprentices are left to figure it out for themselves.

I would argue that possibly the most productive way experienced developers could use their time is in helping less experienced developers build their skills. At my level of experience, I choose to be almost completely dedicated to it. Devs with more than two decades of professional experience are outnumbered 13 to 1, and I’m not a 13x developer.

The way I see it, if companies are happy to promote their most experienced developers into non-technical management roles – losing most of the benefit of that experience – they might as well promote them into hands-on mentoring roles instead. Either way, less experienced developers will be writing the code. At least this way, they’ll be writing better code sooner.

I also genuinely believe that mentoring has many benefits for even the most experienced developers. I’ve had to learn a tonne of stuff specifically so I can explain and demonstrate it to someone else. And to explain it, you’ve really got to wrap your head around it. There’s all sorts of things I kind-of-sort-of understood, but not really, that I’m now 100% clear on purely because I had to get my story straight before I told it to other people. It’s taken me many years to build my Explaining Fu – and while I’m no Richard Feynman, that clarity has definitely benefitted me and my mentees. It also finds its way into my code quite often. I’m way more S.O.L.I.D. aware than I used to be, for example. That’s because I’ve done example after example after example. It’s like ear training for musicians.

These experiences have built my confidence, as well. I’ve given the fundamentals so much thought, and explained and demonstrated them so many times in front of so many very different audiences, that I feel my horizons have widened considerably. Need to learn Kotlin? No probs. Need to prepare a workshop? No worries. Need to present to the board? No sweat. I’m much more fearless after two decades of teaching and mentoring. Sure, it scared the crap out of me in 1999. In 2019, give me a spear and show me where the mammoth’s are at.

So, not only are there people out there who are better developers because of my mentoring, I’m also a better developer for it, too.

This is why I believe structured mentoring needs to be part of the developer journey. First, as a mentee, and then eventually as a dedicated mentor. Our profession needs to be structured so this is normal: the rule and not the exception.

 

If you’d like to talk about developer training and mentoring in your team or organisation, drop me a line.

 

 

Software Development – What Are The ‘Basics’?

Okay, so here’s a hot take…

I’ve been grappling for more than a year now on what I would focus on in a guide to software development for people progressing from learning programming to building more complex systems for real end users.

I’m acutely aware – based on my own experience, and the accounts of many others – of the skills I really wish I’d learned when I started out. As a trainer and coach, I’m also very aware just how many developers get through seemingly their entire careers without being exposed to some of these foundational skills. Hence the need for a “Software Development 101” introduction.

I’m clear in my own mind about some of these things:

  • A developer should know how to drive design directly from users’ needs
  • A developer should know how to use version control (basically, seatbelts for programmers)
  • A developer should be capable of enumerating test cases given either a set of requirements, some behavioural model of the system (e.g., a UX flow diagram), or a copy of the code itself (e.g., what could go wrong with this line of code?)
  • A developer should be capable of automating the execution of their tests so they run fast and consistently
  • A developer should be capable of writing code that’s open to change (that’s a whole can of worms in itself)
  • A developer should recognise potential code quality issues when they see them, and know how to fix them
  • A developer should be capable of changing code without breaking it
  • A developer should be capable of visualising and clearly communicating multiple aspects of their work and their ideas – e.g., architecture/design, workflow, UI/UX, business rules etc. Partly because it can help enormously in bulding understanding, and also because communicating with pictures tends to be so much more effective in many instances.
  • A developer should be capable of automating their software delivery “pipeline” so that getting working code from their desktop to end users is as frictionless as possible
  • A developer should be capable of rapidly iterating their designs based on real user feedback
  • A DEVELOPER SHOULD BE CAPABLE OF A DIRECT, CONSTRUCTIVE WORKING RELATIONSHIP WITH THEIR CUSTOMERS & END USERS
  • A DEVELOPER SHOULD BE CAPABLE OF WORKING HARMONIOUSLY & CONSTRUCTIVELY WITH OTHER DEVELOPERS
  • A developer should be capable of research – nobody arrives on the job knowing everything they need to know for that particular job. A tonne of stuff must be learned along the way. A developer needs to be an auto-didact, because ain’t nobody gonna teach you everything.
  • A developer should be capable of setting themselves goals and managing their own time and resources – contentious, I know. But so many of the issues I see devs and dev teams facing can be boiled down to the perceived need of organisations to micro-manage them, and developers surrendering control over themselves and their work.
  • A developer should be capable of objectively, honestly and transparently communicating progress and making projections about how long it might be before a feature or release is ready. Again, a whole can of worms. But, at the very least, developers can build a reputation for actually being done when they said they were done, even if they’re unable to predict in advance when that might be. It’s bad when the train is late. It’s worse when we claim it’s still on time.

A software developer should be a competent programmer who can be trusted to reliably deliver what customers need, when they need it.

They deliver working software frequently. They listen and are responsive to customer feedback.

They don’t deliver broken software. They don’t wander far from working, shippable code. They don’t make irreversible changes to code. They test their software continuously, and never assume it’s working – either on their machine or anyone else’s.

They can sustain the pace of innovation on a system far beyond a first release, for as long as the customer needs.

They know problem code when they see it. They know how to improve code to reduce or eliminate those problems, without breaking it. They don’t let large batches of problems build up. They address issues early, and continuously.

They build a close working relationship with their customers, and earn trust by delivering what they promised. They don’t make promises they don’t know they can keep.

They can work effectively with other developers, and are open to collaboration. They make sensible, informed choices based on the customer’s and the team’s needs.

They learn what they need to learn, and when they don’t know, they say “I don’t know”. Then they do what they need to find out.

They report progress honestly and objectively, and never say “Take my word for it.”

They work hard to make themselves clearly understood – face-to-face, with pictures, in writing, and especially in code. They work hard to understand what others are telling them, and are constantly testing their own understanding (e.g., with examples).

They are largely self-managing. They set themselves goals. They prioritise and manage their own time effectively. They make time to learn and improve at their job. (And they don’t ask for permission to do that.)

What I’ve learned, after nearly three decades as a software developer, is that all of these skills are needed, and all of them can be learned. Probably not overnight, for sure.

It may take a few years to build a set of skills like this to a level of competency where you can be trusted to just get on with it. Which, I think, would be my single-sentence definition of a “software developer” – as opposed to a trainee or apprentice. And, yes, I know there are lots of people out there who say “Hey, if you’re getting paid to write code, you’re a software developer.” I certainly don’t own the term, and they’re welcome to their own interpretations. This is not my attempt to legally define it. I’m just getting things clear in my head, about what I mean when I say someone is a software developer. And, if there was an introductory guide for that, what would I include?

You are now free to start throwing the furniture around.

 

When Do We Learn?

whendowelearn

It’s always interesting when something you post on social media seems to chime with what a lot of people think. Yesterday, I posted this:

Judging by the likes and retweets, as well as the replies and comments, this is a debate many of us have had.

I’ve posted many times before about how most employers of software developers have an expectation that we arrive fully formed with all the skills and experience they need. They make little time and offer little support for learning as part of the job. This is one of the underlying causes of the so-called “skills crisis” in our industry: employers will wait to find someone with Java 9 experience, but won’t wait for someone with Java 8 to get up to speed.

But be absolutely sure: learning is part of this job. Arguably learning is the job. We’re innovating all the time, and that implies that we’re continually solving new problems and continually learning. It’s one of my fundamental principles of software development: it’s a learning process.

If you condemn developers to learning entirely by trial and error, with no input from other, more experienced developers who’ve “been there, done that and got the t-shirt” – whether it’s in person, from books, from blogs, from videos – then a great deal of their time – and your money – will be wasted making all the same mistakes all over again.

And if you give them no time to learn and adapt from their own mistakes – through retrospectives, root cause analysis, Kaizen and the other continuous improvement activities – then you condemn your dev teams to perpetual Groundhog Day, doing everything the hard way, again and again and again.

The smart dev organisations make time and space and assign resources to learning, sharing knowledge and continuously improving. It could be through ongoing training (pretty rare),  or dedicated 10-20% time for teams to learn, experiment and improve (very rare),  or structured long-term mentoring (vanishingly rare).

Many organisations expect these things to happen outside of working hours, in the developer’s own time. Indeed, many developers expect that, too. It’s a regrettable fact in this industry that if you want to learn and progress, you will probably have to invest a lot of your own time, energy and money into making that happen. This is bad news for us all when potentially great developers, with bags of smarts and heaps of aptitude, also have tonnes of outside commitments – young children, elderly relatives, volunteering in their communities, or just generally having a life outside of software.

When the signal goes out, loud and clear, “If you want to be successful as a software developer, forget having a life”, we shouldn’t wonder why the profession lacks diversity.

How do we change this? I’ve said this before, but it bears saying again: the time and resources for continuous learning will not be freely given, even when we know it’s in the best interests of employers. We must take it.