February 1, 2018

Learn TDD with Codemanship

BDD & Specification By Example - Where Did We Go Wrong?

I've been saving this post up for a while, but with a bit of pre-dinner free time I wanted to put it out there now.

I meet a lot of teams, and one thing many of them tell me is that the "customer tests" they've been driving their designs from are actually written by the developers, not the customer.



Sure, they're written using a "Behaviour-Driven Development" or "Acceptance Testing" tool like Cucumber or Fitnesse. But just because you've built a "granny annex" on your house, if there's no granny living in it, it's just an "annex".

We've dropped the ball on this. The CHAOS report, published every year by the Standish Group, consistently cites lack of customer involvement as the number one factor in project failure. A tool won't fix that.

Especially when that tool wasn't designed with customer collaboration in mind. When your "Getting Started" guide begins "First, install Visual Studio..." or requires your customer to learn a mark-up language or to use version control, arguably you're bound to have a hard time getting them to engage in the process.

Increasingly, I work with teams who want to somehow connect the way their customer actually prefers to capture examples with the way devs like to automate tests. 90% of the time, that means pulling data out of Excel spreadsheets - still the most widely used tool in both communities - into unit tests. Some unit testing frameworks even have that facility built in (e.g., MSTest for .NET). But reading data from spreadsheets is child's play for most developers. With OLD DB or JDBC, for example, a spreadsheet's just a database.

But, regardless of the tools, the problem most teams need to solve is a people problem. I've found that close customer involvement is so critical to the chances of a team succeeding at solving the customer's problems that I actually stop development until they engage at the level we need them to. No play? No code.

The mistake many of us make is to give them a choice. "Would you like to spend a lot of time with us discussing requirements and playing with candidate releases and giving us feedback?" "No thanks, ta very much. See you in a year's time."

We made a rod for our backs by allowing them to be absentee partners and trying to figure out what they want and need for them. Specification By Example presents us with an opportunity to make the relationship clearer. The customer has to be "trained" to understand that if they haven't agreed a test for it, they ain't gonna get it.



January 21, 2018

Learn TDD with Codemanship

Delegating "Junior" Development Tasks. (SPOILER ALERT: It doesn't work)

When I first took on a leadership role on a software development team 20 years ago, from the reading I did, I learned that the key to managing successfully was apparently delegation.

I would break the work down - GUI, core logic, persistence, etc - and assign it to the people I believed had the necessary skills. The hard stuff I delegated to the most experienced and knowledgeable developers, The "easy" stuff, I left to the juniors.

It only took me a few months to realise that this model of team management simply doesn't work for software development. In code, the devil is in the detail. To delegate a task, I had to explain precisely what I wanted that code to do, and how I wanted it to be (in terms of coding standards, our architecture, and so on).

If the task was trivial enough to give to a "junior" dev, it was usually quicker to do it myself. I spent a lot more time cleaning up after them than I thought I was saving by delegating.

So I changed my focus. I delegated work in big enough chucks to make it worthwhile, which meant it was no longer "junior" work.

Looking back with the benefit of 20 years of hindsight, I realise now that delegating "junior" dev tasks is absurd. It's like a lead screenwriter delegating the easy words to a junior screenwriter. It would also probably be a very frustrating learning experience for them. I'm very glad I never went through a phase in my early career of doing "junior" work (although I probably wrote plenty of "junior" code!)

The value in bringing inexperienced developers in to a team is to give them the opportunity to learn from more seasoned developers. I got that chance, and it was invaluable. Now, I recommend to managers that their noobs pair up with the old hands on proper actual software development, and allow for the fact that it will take them longer.

This necessitates - if you want the team to be productive as a whole - that the experienced developers outnumber the juniors. Actually, let's not call them that. The trainees.

Over time - months and years - the level of mentoring required will fall, until eventually they can be left to get on with it. And to mentor new developers coming in.

But I still see and hear from many, many people who are stuck in the hell of a Thousand Junior Programmers, where senior people - often called "architects" - are greatly outnumbered by people still wet behind the ears, to whom all the "painting by numbers" is delegated. This mindset is deeply embedded in the cultures of some major software companies. The result is invariably software that's much worse, and costs much more.

It also leads to some pretty demoralised developers. This is not the movie industry. We don't need runners to fetch our coffee.


ADDENDUM: It also just occurred to me, while I'm recalling, that whenever I examined those "junior" dev tasks more closely, their entire existence was caused by a problem in the way we were doing things (e.g., bugginess, lack of separation of presentation and logic, duplication in data access code, etc). These days, when it feels like "grunt" work - repetitive grind - I stop and ask myself why.

January 3, 2018

Learn TDD with Codemanship

Professionalism & the "Customer"

Just a few words to add to a post I wrote a few days ago about TDD & "professionalism". I scribbled a quick Venn diagram to illustrate my ideas about stuff software development "professionals" should aim for.



A few good folk have understandably raised objections, which is the natural consequence of saying stuff on the Internet. In particular, some folk object to the idea that a "professional" doesn't write code the customer didn't ask for.

What if the customer doesn't know what they want? Should we build something and see if they like it? Call it an "experiment". We could do that. But before we do that, we could discuss it with the customer and seek their input before we build what we're planning to build. A mock-up, a storyboard, or other lo-fi prototype could clue them in as to what exactly it is we're planning to try for them.

And what if we're building software for the general public? How do we seek permission to try ideas?

This is the problem with words.

What exactly is a "customer"? Different teams will be working in different situations with different kinds of "customer". And there are many understandings of what that word means.

To me, the "customer" is whoever decides what the money gets spent on. In relation to professionalism, we can look at our relationship with our "customer" in many ways.

Think of doctors and patients: the doctor doesn't ask the patient "What medicine would you like me to prescribe?" Instead, she examines the patient, diagnoses the illness, and proposes a treatment. But she still seeks permission from the patient to try it. (Unless the patient is unable to give consent.) Arguably, it would be "unprofessional" of a doctor to administer a treatment without telling the patient what it is, what it's supposed to do, and what side effects it might have. There is a dialogue, then there is consent. The patient decides yay or nay, usually.

Or think of it as gambling. In the casino of software development, decisions are made to bet sums of money on features and changes. Some bets will be bigger than others. Some features will have a potentially larger pay-out than others. In that scenario, where we don't know what the outcome is going to be (which is - let's be honest - how it really is in software development anyway), who are we? Are we the gambler? Or are we the croupier? Do we take their money and tell them to go to the bar while we place bets on their behalf? Or do we ask them to sit at the table, and at least seek consent for every bet before it's placed?

And when it's us deciding what features to try, aren't we the "customer"? In this situation, it's our money we're gambling with. Do we randomly write code and see how it turns out? Or do we take aim before we fire? I've found it to be a bad idea to start writing code without a clear idea of what that code's supposed to do, regardless of whether this is decided in a conversation with a "customer", or in a conversation with myself.

One thing is clear to me (and feel free to disagree): all software development is an experiment. So, personally, I don't distinguish between a "spike" and a "finished solution". They're all spikes. I've found I'm genuinely no quicker producing working code when I cut corners. So my spikes have automated tests, and the code's maintainable. (I rarely even write sample code (e.g., for blog posts) without tests any more.) And they proceed a conversation in which the purpose of the spike is explicitly agreed, and consent - even if it's my own consent - is given to do it.

Now, like I said in the original post: I don't find discussions about professionalism very helpful. Words are difficult. However I spin it, some folk will object. And that's fine. Don't wanna do it my way? Don't do it. I'm not in charge of anyone except myself.

And isn't that, after all is said and done, the real definition of a "professional"?


December 30, 2017

Learn TDD with Codemanship

TDD & "Professionalism"

Much talk (and gnashing of teeth) about the link between Test-Driven Development and "professionalism". It probably won't surprise you to learn that I've given this a bit of thought.

To be clear, I'm not in the business of selling TDD to developers and teams. If you don't want to do TDD, don't do it. (If you do want to do TDD, then maybe I can help.)

But let's talk about "professionalism"...

I believe it's "unprofessional" to ship untested code. Let me qualify that: it's not a good thing to ship code that has been added or changed that hasn't been tested since you added or changed it. At the very least, it's a courtesy to your customers. And, at times, their businesses or even their lives may depend on it.

So, maybe my definition of "professionalism" would include the need to test (and re-test) the software every time I want to ship it. That's a start.

Another courtesy we can do for our customers is to not make them wait a long time for important changes to the software. I've seen many, many businesses brought their knees by long delivery cycle times caused by Big Bang release processes. So, perhaps it's "unprofessional" to have long release cycles.

When I draw my imaginary Venn diagram of "Doesn't ship untested code" and "Doesn't make the customer wait for changes", I see that the intersection of those two sets implies "Doesn't take long to test the software". If sufficiently good testing takes weeks, then we're going to have to make the customer wait. If we skimp on the testing, we're going to have to ship untrustworthy code.

There's no magic bullet for rapidly testing (and re-testing) code. The only technique we've found after 70-odd years of writing software is to write programs that automate test execution. And for those tests - of which there could be tens of thousands - to run genuinely fast enough to ensure customers aren't left waiting for too long, they need to be written to run fast. That typically means our tests should mostly have no external dependencies that would slow them down. Sometimes referred to as "unit tests".

So, to avoid shipping broken code, we test it every time. To avoid making the customer wait too long, we test it automatically. And to avoid our automated tests being slow, we write mostly "unit tests" (tests without external dependencies).

None of this mandates TDD. There are other ways. But my line in the sand is that these outcomes are mandated. I will not ship untested code. I will not make my customer wait too long. Therefore I will write many fast-running automated "unit tests".

And this is not a complete picture, of course. Time taken to test (and re-test) the code is one factor in how long my customer might have to wait. And it's a big factor. But there are other factors.

For example, how difficult it becomes to make the changes the customer wants. As the code grows, complexity and entropy can overwhelm us. It's basic physics. As it expands, code can become complicated, difficult to understand, highly interconnected and easy to break.

So I add a third set to my imaginary Venn diagram, "Minimises entropy in the code". In the intersection of all three sets, we have a sweet spot that I might still call "professionalism"; never shipping untested code, not making our customers wait too long, and sustaining that pace of delivery for as long as our customer needs changes by keeping the code "clean".

I achieve those goals by writing fast-running automated "unit tests", and continually refactoring my code to minimise entropy.

Lastly - but by no means leastly - I believe it's "unprofessional" to ship code the customer didn't ask for. Software is expensive to produce. Even very simple features can rack up a total cost of thousands of dollars to deliver in a working end product. I don't make my customers pay for stuff they didn't ask for.

So, a "professional" developer clearly, unambiguously establishes what the customer requires from the code before they write it.

Now my Venn diagram is complete.



ASIDE: In reality, these are fuzzy sets. Some teams ship better-tested code than others. Some teams release more frequently than others, and so have shorter lead times. Some teams write cleaner code than others. Some teams waste less time on unwanted features than others.

So there are degrees of "professionalism" in these respects. And this is before I add the other sets relating to things like ethics and environmental responsibility. It's not a simple binary choice of "professional" or "unprofessional". It's complicated. Personally, I don't think discussions about "professionalism" are very helpful.


Like I said at the start, TDD isn't mandatory. But I do have to wonder, when teams aren't doing TDD, what are they doing to keep themselves in that sweet spot?



December 17, 2017

Learn TDD with Codemanship

Dev Teams As Assets

One of the biggest giveaways about how a lot of employers view software developers is the way they handle their high-performing teams.

I've seen it happen many, many times; a dev team does a great job delivering something of high value to the business, and at the end the business splits them up without a second thought.


A high-performing team, yesterday


In other lines of work, this would be considered very ill-judged. I struggle to imagine the execs at Apple Records saying "Thanks, John, Paul, George, Ringo. That first album album sold gangbusters. Time to split you up."

Some managers misguidedly do it in the hope of "spreading the love", moving developers from their most successful teams on to other teams that may be struggling, hoping some of the magic will rub off.

But development teams are holistic. They succeed or fail as a single unit. I've seen high-performing teams of mediocre developers, and I've seen teams made of 100% code ninja fail pitifully.

The "magic" we're seeking to replicate exists between team members.

Faced with a lack of control over who they get to work with, some teams take the bold step to move the whole kit and caboodle out of that organisation to retain the magic and apply it somewhere else, for some other client's benefit.

But most developers, with mortgages and school fees and wotnot to pay, can't justify the risks, so they accept their fate and go back to the seemingly much more popular choice of Not SucceedingTM for the remainder of their careers.

In these instances, you lose your high-performing dev team and gain a bunch of newly miserable and demotivated devs. High five!

A rare few organisations recognise the value of dev teams, see them as assets, and invest in them as whole units. They work to ensure the team retains cohesion, even after individual members leave, and as new members join. They know that the better way to spread the love is not to scatter high-performing team members to the winds, but to embed trainees in the team. What you want to rub off on them is likely to be find there, not carried by individual team members.





December 7, 2017

Learn TDD with Codemanship

"This would never have happened if we'd written it in Haskell" - Bah Humbug!

Spurred on by a spate of social media activity of the "We replaced a system written in X with one written in Y, and it was way better" kind, I just wanted to throw my hat into the ring on this topic.

As someone with practical insights into high-integrity software development, I can confidently attest that this is bunk of the highest order. There is no programming language that assures reliability.

Sure, there are languages with built-in features that can help, but you actually have to do stuff to make sure your code works 99.999999999% of the time. Y'know? Like testing and wotnot.

For example, you can inflict all kinds of damage in C, thanks to direct manipulation of memory, but you don't have to abuse those features of the language. A Bugatti Veyron has a top speed of 254 mph, but you don't have to drive it at 254 mph.

"We would never have had that crash if we'd been driving a Volvo" really means "We'd never have had that crash if we'd been driving slower".

If you want to avoid dangling pointers in a C program, you can. It just takes a bit of know-how and a bit of discipline. Don't blame the language for any shortcomings you might have in either. The difference the language makes is small compared to the difference you make.


ADDENDUM: Just to clarify, I'm not saying better languages and tools don't help. What I'm saying is that the difference they make can be very small compared to other factors. How do I know this? Well, I've been programming for 35 years and have worked in a dozen or more languages on real projects. So there's that. But also, I've worked with a lot of teams, and noticed how the same team using different tools gets similar results, while different teams using identical tools can get strikingly different results. So I conclude that the team makes the bigger difference, by orders of magnitude. So I choose to focus more on teams and how they work than on the tools, by orders of magnitude. And it's not as if tools and technology don't get enough focus within the industry :)



October 18, 2017

Learn TDD with Codemanship

12 Things a Professional Computer Programmer Needs to Learn

The last few years has seen an explosion of great learning resources for people interesting in getting into computer programming.

But alongside that, I've noticed a growing number of people, who have ambitions to work in the industry as programmers, being bamboozled into believing all it takes is a few weeks of self-paced JavaScript tutorials to reach a professional level.

Nothing could be further from the truth, though. Programming languages are just one small aspect of writing software as a professional (albeit a crucial one).

When learners ask me "What else do I need to know how to do?", I'm typically unprepared to answer. Unhelpfully, I might just say "Loads!"

Here, I'm going to attempt to structure some thoughts on this.

1. Learn to code. Well, obviously. This is your starter for 10. You need to be able to make computers do stuff to order. There's no getting around that, I'm afraid. If you want to do it for a living, you're probably best off learning programming languages that are in demand. As unhip and uncool as they may be these days, languages like Java and C# are still very much in demand. And JavaScript is at the top of the list. To become an in-demand "full-stack" software developer, you're going to need to learn several languages, including JavaScript. Research the kinds of applications you want to work on. Find out what technologies are used to create them. Those are the languages you need to learn.

2. Learn to use Version Control. Version Control Systems (VCSs) are seatbelts for programmers. If your code has a nasty accident, you want to be able to easily go back to a versin of it that worked. And most professional developers collaborate with other developers on the same source code, so to do it for a living you'll want to know how to use VCSs like Git and Mercurial to effectively manage collaborating without tripping over each other.

3. Learn to work with customers. Typically, when we're learning to code, we tackle our own projects, so - in essence - we are the customer. It gets a bit more complicated when we're creating software for someone else. We need to get a clear understanding of their requirements, and so it's important to learn some simple techniques for exploring and capturing those requirements. Look into use cases and user stories to get you started. Then learn about Specification by Example.

4. Learn to test software. There's more to making sure our code works than running the application and randomly clicking buttons. You'll need to understand how to turn requirement specifications into structured test scripts that really give the code a proper, in-depth workout. How do make sure every requirement is satisfied? How do make sure every line of code is put through its paces? How do we identify combinations of inputs that the code can't handle?

5. Learn to write automated tests. Automated tests are commonly used in Specification by Example to really nail down exactly what the customer wants. They are also crucial to maintaining our code as it grows. Without a decent set of fast-running automated tests, changing code becomes a very risky and expensive business. We're likely to break it and not find out for a long time. Learn how to write automated unit tests for your code, and how to automate other kinds of tests (like system tests that check the whole thing through the user interface or API, and integration tests that check system components work together).

6. Learn to write code that's easy to change. On average, software costs 7-10x as much to maintain over its lifetime as it did to write in the first place. And if there's one thing we've learned from 70 years of writing software, it's that it'll need to change. But, even though we call it "software" - as opposed to "hardware" - because it's easier to change than the design of, say, a printed circuit board, it can still be pretty hard to change code without breaking it. You'll need to learn what kind of things we can do in code tend to make it harder to change and easier to break, and how to avoid doing them. Learn about writing code that's easy to read. Learn about simple design. Learn how to avoid writing "spaghetti code", where the logic gets complicated and tangled. Learn how to shield modules in your code from knowing too much about each other, creating a dense web of dependencies in which even the smallest changes can have catastrophic impact. Learn how to use abstractions to make it easier to swap out different parts of the code when they need to be replaced or extended.

7. Learn to improve the code without breaking it. We call this skill "refactoring", and it's really, really important. Good programmers can write code that works. Great programmers can improve the code - to make it easier to understand and easier to change - in ways that ensure it still works. A function getting too complicated to understand? Refactor it into smaller functions. A module doing too much? Refactor it into multiple modules that do one job. This skill is very closely connected to #5 and #6. You need to know bad code when you see it, and know how to make it better. And you need to be able to re-test the code quickly to make sure you haven't broken anything. Automated Tests + Design Smarts + Refactoring form a Golden Circle for code that works today and can be easily changed tomorrow to meet new customer requirements.

8. Learn to automate donkeywork like building and deploying the software. Good software developers don't manually copy and paste files to production servers, run database scripts, and all of that repetitive stuff, when they want to create test or production builds of their systems and deploy them to a live environment. They program computers to do it. Learn how to automate builds, to do Continuous Integration, and automate your deployments, so that whole delivery process can become as easy and as frictionless as possible.

9. Learn about software architecture. Is your application a mobile app? A website? A Cloud service? Does it need huge amounts of data to be stored? Does it need to be super-secure? Will some features be used by millions of users every day? Will it have a GUI? An API? Is the data really sensitive (e.g., medical records)? We have 7 decades of knowledge - accumulated through trial and error - about how to design software and systems. We have principles for software architecture and the different qualities we might need our software to have: availability, speed, scalability, security, and many more. And there are hundreds of architectural patterns we can learn about that encapsulate much of this knowledge.

10. Learn to manage your time (and yourself). You might enjoy the occasional late night working on your own projects as a beginner, but a professional programmer's in this for lomg haul. So you need to learn to work at a sustainable pace, and to prioritise effectively so that the important stuff gets done. You need to learn what kinds of environments you work best in, and how to change your working environment to maximise your productive time. For example, I tend to work best in the morning, so I like to get an early start. And I rarely spend more than 7-8 hours in a day programming. Learn to manage your time and get the best out of yourself, and to avoid burning out. Work smarter, not harder, and pace yourself. Writing software's a marathon, not a sprint.

11. Learn to collaborate effectively. Typically, writing software is a team sport. Teams that work well together get more done. I've seen teams made up of programmers who are all individually great, but who couldn't work together. They couldn't make decisions, or reach a consensus, and stuff didn't get done because they were too busy arguing and treading on each others' toes. And I've seen teams where everyone was individually technically average, but as a single unit they absolutely shone. Arguably, this is the hardest skill, and the one that takes the longest to master. You may think code's hard. But people are way harder. Much has been written about managing software teams over the decades, but one author I highly recommend is Tom DeMarco (author of "Peopleware"). In practice, this is something you can really only learn from lots and lots of experience. And increasingly important is your ability to work well with diverse teams. The days when computer programming was predominanly a pursuit for western, white, middle class heterosexual men are thankfully changing. If you're one of those people who thinks "girls can't code", or that people from third-world countries are probably not as educated as you, or that people with disabilties probably aren't as smart, then I heartily recommend a different career.

12. Learn to learn. For computer programmers, there's 70 years of learning to catch up on, and a technology landscape that's constantly evolving. This is not a profession where you can let the grass grow under your feet. People with busy lives and limited time have to be good at making the most of their learning opportunities. If you thought you'd learned to learn at college... oh boy, are you in for shock? So many professional programmers I know said they learned more in the first 6 months doing it for a living than they did in 3-4 years of full-time study. But this is one of the reasons I love this job. It never gets boring, and there's always something more to learn. But I've had to work hard to improve how I learn over the years. So will you. Hopefully, the more you learn, the clearer the gaps that need filling will become.

So, there are my twelve things I think you need to learn to be a professional computer programmer. Agree? What would be on your list? You can tweet your thoughts to @jasongorman.






October 13, 2017

Learn TDD with Codemanship

Time for the Chief Software Developer?

A blog post by Extreme Programming co-creator Kent Beck about ageism in software development has set me thinking again about this whole issue.

As 50 looms on the horizon, I'm becoming only too aware of this predilection employers have for younger - cheaper - developers. "Do you think they might be a little old?" is a question I routinely hear from hiring managers in start-ups in particular.

The net effect of this - aside from throwing great talent and experience on the scrapheap - is we're a profession of perpetual beginners. Young people entering software development are very lucky if they're exposed to industry veterans in any practical way.

So insights about refactoring, say, that date back to the 1980s have to be rediscovered and reinvented year after year. The upshot is that most developers can't refactor code. So most code suffers from a severe lack of maintainability. By the time developers have learned to write better code, our industry dictates that they move away from the code-face. And around we go.

My solution to the "How come you're not a CTO yet?" question that inevitably comes up with someone of my vintage has been to sidestep it. As a developer, I'm getting too old and too expensive for most employers. But as a trainer and coach, 25 years of professional experience is a distinct advantage. So I code every day, and work with other developers on actual software, instead of sitting in meetings or being a PowerPoint jockey.

But sidestepping the job shouldn't be necessary. There should be a viable career path for people who want to stay hands-on. They're both necessary and valuable, especially to technology companies.

I maintain that there should be such a thing as a Chief Software Developer, who sits on the board like a CTO or CIO, but writes code on a day-to-day basis. They would be there to defend the reality of writing software from the uninformed "optimism" of bosses who think it's easy, and who just want everything yesterday, at half the price, and hang the consequences for the business.

I can think of many, many start-ups who could have avoided The Hell of A Thousand Complete Rewrites had such a person had one hand on the wheel. Indeed, I can think of a few very large companies who'd still be trading today if someone with genuine authority had said "No, let's do this right".

I'm a realist, though. I appreciate that history teaches us such authority is rarely given freely. Development teams need to take it. Perhaps one way teams could pave the way would be to identify who in their team would be a Chief Software Developer, and then just start calling them that. After a few years of many teams in many businesses doing it, the drip-drip-drip effect might just make it an officially acknowledged reality.

Who would be your Chief Software Developer?




August 19, 2017

Learn TDD with Codemanship

Time For Learning - An Inconvenient Truth

I've watched many tweet debates ("twebates"?) recently on the subject of finding time for learning in software development.

In the culture of the code craft movement, the consensus has been that you have to put in the hours. And by that, they tend to mean your own hours, outside of the day job. I've seen many job ads stipulating that candidates would need to show evidence of this extra-curricular commitment: blogs, speaking at conferences, OSS contributions, personal projects and all that.

The counter argument comes chiefly from people advocating greater diversity in software. Single parents, for example, have a lot on their plate that makes popping along to the Extreme Tuesday Club or speaking at a conference in, say, Norway, logistically difficult. Where's the time in their day/week/year to read all three volumes of the Art of Computer Programming?

My perspective on all this, I'm afraid, is cold and sobering. It takes a lot of reading and talking and sharing and experimentation (also known as "trying new stuff") to get good at writing software - and to stay good at it.

That's an inescapable reality. It's an inconvenient truth about software development. Everyone wants those skills, but nobody's willing to pay to develop them. Cui bono? Demonstrably, the employer benefits from more skilled developers. So they should make a contribution to bulding those skills. Simples.

What we're really debating is where does that time come from? Most employers aren't willing to support learning out of their own budgets. They expect developers to arrive fully formed, and that means that anything aside from direct on-the-job experience is down to us to learn in our own time. It's wholly inadequate to the task because we can only learn things that have immediate relevance to what we're doing.

Imagine if doctors had to learn everything that way. "Well, Mr Gorman, I'm afraid you have a burst appendix. This hasn't come up before, so I'm going on a course to learn how to treat it. See you in 2 weeks."

This also excludes people whose backgrounds and situations make finding those extra hours every week very difficult. This is why I believe offering developers "10% time" or "20% time" is really very necessary if we want a more diverse profession. This is another inconvenient truth about software development. Job ads that demand large amounts of extra hours of "elective" work are effectively restricting applications to people with not a lot else going on in their lives.

In practice, the code crafter landscape is still pretty homogenous. When I run public events, we still get about 85% men, and most of those are white. Very occasionally, someone with a disability comes along - and I always try to make sure the event's accessible, and advertise that fact.

But the fact remains that there are a lot of potentially great developers out there who, much as they'd like to, can't get along to a Saturday workshop, and whose employers won't let them take time out for learning during the working week.

Those are the people we in the dev community rarely see. But we shouldn't assume that they're not there because they don't want to learn.

If your job ads say you're committed to increasing diversity, and then demand a large portfolio of extra-curricular activities, you have a cognitive dissonance.

So, my question is this: how do we square this circle? My current belief is that we must adapt the very nature of our jobs so that time for learning and deliberate practice is built into the working week. I believe that this should become the norm, whereas today it's very much the exception.

I come from the school of "if this needs to happen, then let's just do it". We made the mistake, as professionals, of letting other people manage our time. If we're to move forward then that needs to stop. As "prima donna" as this sounds, we should take that time, and not ask for permission.

Because if we ask for permission, we know what the answer will be.




August 11, 2017

Learn TDD with Codemanship

Update: Code Craft "Driving Test" FxCop Rules



I've been continuing work on a tool to automatically analyse .NET code submitted for the Code Craft "Driving Test".

Despite tying myself in knots for the first week trying to build a whole code analysis and reporting framework - when will I ever learn?! - I'm making good progress with Plan B this week.

Plan B is to go with the Visual Studio code analysis infrastructure (basically, FxCop). It's been more than a decade since I wrote FxCop rules, and it's been an uphill battle wrapping my head around it again (along with all the changes they've made since 2006).

But I now have 8 code quality rules that are kind of sort of working. Some work well. Some need more thought.

1. Methods can't be longer than 10 LOC

2. Methods can't have > 2 branches

3. Identifiers must be <= 20 characters. (Plan is to exempt test fixture/method names. TO-DO.)

4. Classes can't have > 8 methods (so max class size is 80 LOC)

5. Methods can't use more than one feature of another class. (My very basic interpretation of "Feature Envy". Again, TO-DO to improve that. Again, test code may be exempt.)

6. Boolean parameters are not allowed

7. Methods can't have > 3 parameters

8. Methods can't instantiate project types, unless they are factory or builder methods that return an abstract type. (The beginning of my Dependency Inversion "pincer movement". 2 more rules to come preventing invocation of static project methods, and methods that aren't virtual or abstract. Again, factories and builders will be exempt, as well as test code.)

What's been really fun about the last couple of weeks has been eating my own dog food. As each new rule emerges, I've been applying it frequently to my own code. I'm a great believer in the power of Continuous Inspection, and this has been a timely reminder of just how powerful it can be.

Red-Green-INSPECT-Refactor


After passing every test, and performing every refactoring, I run a code analysis that will eventually systematically check all my code for 15 or so issues. I fix any problems it raises there and then. I don't commit or push code that fails code analysis.



In Continuous Inspection, this is the equivalent of all my tests being green. Of course, as with functional tests, the resulting code quality may only be as good as the code quality tests. And I'm refining them with more and more examples, and applying them to real code to see what designs they encourage. So far, not so shabby.

And for those inevitable occasions when blindly obeying the design rules would make our code worse, the tool will have a mechanism for opting out of a rule. (Probably a custom attribute that you can apply to classes and fields and methods etc, specifying which rule you're breaking and - most importantly - documenting why. Again, a TO-DO.) In the Driving Test, I'm thinking candidates will get 3 such "hall passes".

If you want to see the work so far, and try it out for yourself, the source code's at https://github.com/jasongorman/CodeCraft.FxCop

And I've made a handful more tickets available for the trial Code Craft "Driving Test" for C# developers on Sept 16th. It's free this time, in exchange for your adventerous and forgiving participation in this business experiment :)

Powered by Eventbrite