David Scott Bernstein's Blog, page 27
April 29, 2016
Scrum Master Toolbox Podcast
I spoke with Vasco Duarte at Scrum Master Toolbox Podcast the week of April 18, 2016 on several different topics. Here’re links to our five episodes:
Monday (18 Apr 2016): David Bernstein on learning to break stories down
Tuesday (19 Apr 2016): David Bernstein on the Us vs Them mentality
Wednesday (20 Apr 2016): David Bernstein on metaphor as a change catalyst
Thursday (21 Apr 2016): David Bernstein shares 7 strategies to measure value
Friday (22 Apr 2016): David Bernstein on understanding the whole system before starting to change it
Enjoy!
April 27, 2016
Technical Excellence
Ten years after the Agile Manifesto was signed into being, the original authors got back together to review the progress made in the last decade. It was Jeff Sutherland who said, “Demanding technical excellence is a top priority for the next ten years.”
But what is technical excellence? Given the state of the software industry and the lack of maintainability that most software’s produced with, I think it’s fair to assume that most of us don’t really know what “technical excellence” means when it’s applied to software.
Given that over 80% of the cost of software happens after its initial release, I would propose that a key aspect of technical excellence is being able to deliver software that is maintainable. I’ve asked developers what they do to increase the maintainability of their code, and often got back blank stares.
Maintainability of software is not a subject that is discussed in any depth in computer science curriculums or even in professional software development circles. As an industry, we’re just starting to become aware of the importance of writing maintainable software.
The nine practices I propose in my book, Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software, support the creation of maintainable software. When not only adopted but understood, these nine practices help us rapidly build maintainable software.
I propose that the core of maintainable software comes from practice five: Create CLEAN Code.
CLEAN is my acronym for five key code qualities that support maintainability: Cohesive, Loosely coupled, Encapsulated, Assertive, and Non-redundant. These certainly aren’t the only qualities we can look at, but they represent a set of code qualities that are easiest for most people to recognize and understand. I won’t go into detail of each of these qualities here, since I cover them in depth in my book, but though these qualities seem simple, almost trivial, we find that when they aren’t present in code, that code becomes difficult to work with and extend.
By paying attention to code quality and building testable behaviors, we can build software that is better adapted to the needs of the user and that’s easier to work with in the future.
April 20, 2016
The Iron Triangle
There are three main constraints in manufacturing that are sometimes referred to as the “iron triangle.” These are scope, time, and resources.
In manufacturing they say, “Pick two of these three things to flex, but one must remain fixed.”
But this model does not apply to software development.
Scope refers to the size of the project or the amount of work to be done.
Time refers to when the project will be finished or how long it will take.
The “resources” for developing software are people. And because developing software requires a great deal of communication and coordination among people, when we add more people to a project it almost always has the short-term effect of slowing the project down. Assembling software is not like assembling a car. In software development, resources are generally fixed because adding more people to a project doesn’t make it go faster.
On a Waterfall project, scope and time are also fixed, which often creates a nearly impossible situation.
If scope, time, and resources are all fixed then what’s left to flex? Developers know the answer to this question because they often find themselves in this situation. When all three sides of the iron triangle are fixed the only thing that can flex is the quality of their own work—and this is the one thing that developers must not compromise on.
As we start cutting corners and rushing we start making little mistakes that cluster into big mistakes that cost considerable time (and therefore money) to find and fix. Teams very quickly get on a downward spiral that puts them in a reactive rather than proactive development environment.
A real and sincere effort toward quality software has been the hallmark of every highly productive team I’ve ever seen.
April 13, 2016
Think Like an Expert
Experts in any field organize their knowledge in specific ways. They have their own unique vocabulary and draw on specific analogies and metaphors. They have established key beliefs and distinctions around their expertise, and though they understand their subject their understanding maybe different and deeper than the rest of us.
All experts draw on skills that are learnable. This means that if we know the things they know and do the things they do then we can get the results they get. Experts were not born that way, they simply have a few key distinctions that the rest of us don’t have and expert software developers are no exception to this rule.
One of the key characteristics that I find in virtually all expert software developers is that they are expert problem solvers. They are able to penetrate into the core essence of a problem and create organic solutions based on that insight. And their solutions are both understandable by others and also extendible.
The best developers I know, the top experts in their field, are not sloppy coders. They are incredibly neat and they focus on keeping their code clean. I used to think that in order to be fast you have to be a little sloppy but the top developers I’ve met are also the neatest, I suspect there is a correlation.
When we don’t understand something it tends to seem complicated. The very best teachers are able to show us the simplicity in the world around us. They help us make sense of things. This is also what good software does. When we read the code or use the program it just makes sense. But this doesn’t happen by serendipity. It takes a great deal of intention as well as skill to pull it off.
Expert software developers have to figure a lot out on their own because many of the rules and finer points of developing software have not really been written down by anyone.
April 6, 2016
Stop Anticipating
I generally find that developers engage in one of two different activities when it comes to making future changes: they either anticipate or accommodate.
Anticipating change comes from a good place, a place of caring, but can be ineffective and stressful. I spent much of my career trying to anticipate code changes so that my software would be able to handle them if they ever came up. This was a losing battle. Change will always come from a direction I hadn’t anticipated. Anticipating change is no fun. It’s fraught with stress and we know we’re going to be wrong at least some of the time.
Rather than anticipate change, developers must rely on a series of standards and practices that support accommodating change when it needs to happen.
There are several advantages to this. First of all, we are not making changes sooner than needed. A great deal of a developer’s time is lost to overbuilding and gold plating, simply because they don’t know how their code is going to be used. But if they get clear on that by defining a good set of acceptance tests, then they know they can move on when the test passes and if later they need additional functionality, they can address it then.
One of the main reasons developers don’t have time to do important things is that they’re wasting a lot of their time on unimportant things.
I believe that the software development industry must have a series of practices to help us accommodate change. Such practices do exist, but they are not well known. They are not taught in schools. They are not sung from the rafters.
But they should be.
I have devoted my life to discovering the core pieces of knowledge that great software developers must possess. What I found is that there aren’t very many of them, and that they are easy to learn. But what holds us back is having a shared context for software development. In other words, different developers have different ideas about what software development should be and because we all have different goals and objectives, it’s very difficult to be aligned on principles and practices.
By shared context, I mean: What’s the purpose of software development, or its overarching goal?
Research shows that 80% of the cost of software happens after the initial release. Given the enormous cost of building software and the much more enormous costs of maintaining and extending software, I believe the context of software development must be that software has to provide value not only now but also into the future. In order to do that, in order to provide longevity, we must build software in a very different way than it is mostly being built today. We must build software to be changeable.
And we can.
The things I wrote about in Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software and teach in classes, all support the notion of building maintainable software. It’s not hard to do but we have to pay attention to it.
When these ideas start making their way into college curriculums and become part of what it means to be a professional software developer, the industry will really take off and every other industry will benefit from this well-defined context.
March 30, 2016
Use Flexible Feature Flags
In my last post, Stop Hitting Yourself, I described (long-lived) branching in version control as an anti-pattern. It’s something we want to avoid.
But then what are the alternatives to branching for integrating code as it’s being built into a production system? We can’t let half-baked features slip out into production. If we do, the users will try to access those features and they will fail.
We want to integrate code as it’s being built so we can get immediate feedback if our code is causing any problems in the system. If we build code in its own branch, then we’re shutting out that feedback until the branch gets integrated into a trunk, which often happens too late.
Instead of branching, we can use flexible feature flags. The feature flag is simply a Boolean whose state determines if a feature is under development or ready for production. If a feature is under-developed then it is excluded from the UI so the user cannot gain access to it but it’s still a part of the build. So the code under development gets built with the rest of the system and we can be alerted if there are any issues.
Once the feature is ready for production we can either flip the feature flag or remove the conditional entirely.
There are several ways to implement feature flags. Straightforward conditional logic is my favorite approach. Avoid using conditional compiles because the whole point of using feature flags is to include work under development in the compile, but just don’t let it be accessible in production.
This is a simple solution to a major issue but you know what Occam once said: the simplest explanation is usually the right one.
March 23, 2016
Stop Hitting Yourself
If there was a button on your computer that said “DO NOT PUSH,” would you push it?
If you push the button and a hand comes out of the monitor and slaps you on the face, would you push it again and again?
Of course not! But then why do you continue to use branching in version control? I understand that there are some legitimate uses for branching but it’s often overused, and feature branches are almost always a bad idea.
As soon as a branch is created, the system’s capabilities become divergent and the cost of bringing those pieces back together again can be very high. Branching development either by team or feature may seem like a good idea up front because nobody’s code affects the other people, but this can cause problems when integrating code later. Creating branches in this way is only postponing the inevitable, and postponing these little problems along the way causes them to become big problems later on. Integrating code becomes a bigger problem the longer you wait. So it’s better to integrate as soon as possible and best to integrate continuously.
Continuous integration may take some time to set up, but it pays back huge dividends rather quickly. The pain of integration and testing goes away and is replaced by a build system that gives valuable and immediate feedback to developers as soon as they check in their code.
Continuous integration provides the infrastructure for agility. In fact, I believe that continuous integration is at the very essence of Agile. If you integrate code as it’s built, you’re doing Agile. And if you wait to integrate code, even if it’s just a few weeks, then you are not doing Agile no matter how many stand up meetings you have. Iterations must end with integration, and ideally, developers integrate their code as they’re building it.
But how do we integrate features into a production system as it’s being built without using branching?
I’m glad you asked. It’s a good question and the answer to that question can be found in my next blog post: Use Flexible Feature Flags.
Until then, happy coding.
March 16, 2016
Outside In or Inside Out
Most of the time when we’re building software, we’re thinking inside out. We focus on the behavior that we want to create, and build the system up from that. We do this because we’re anxious to get at the heart of the problem and solve the core issues. But there’s a problem with this approach because as we move up levels of abstraction connecting those core issues to a broader system, it can be hard to forge the right interfaces. This is inside out programming.
By contrast, outside in programming starts from the big picture, from the caller’s perspective, and drills down into the system.
One approach is not better than the other, they are both useful and valid, but we want to draw on both to build good robust systems that have strong interfaces.
Test first development is a powerful way to do outside in programming. As my associate Scott Bain likes to say, “Think of the test as your first client.” I love this statement because it really summarizes a whole range of benefits that you get from doing TDD. By writing the test first, you’re thinking from the client’s perspective, about what you want rather than how to get it, and this ripples through the design and implementation of the system, keeping it well encapsulated and easy to understand.
Sometimes we need to figure out an implementation and so we do inside out programming, but usually I want some context for an implementation so I start with the test.
Regardless of how I start, I generally want to think in both directions. How do clients want to call the service that I am about to create? And then once I call that way how can I best go about doing the task at hand?
This often reveals some intermediary steps that I want to separate out. For example, if a client wants me to process a document at a URL that it passes me I should separate out the retrieval of the document from the processing because by doing so, I make both steps far more testable and easier to integrate.
It’s generally advisable to separate out perspective in code regardless of what they are. The UML calls out three perspectives in code that are good to separate out. These are the conceptual, the specification, and the implementation perspectives.
The conceptual perspective shows what we want but not how to get it. This typically maps to abstractions or interfaces in code.
The specification perspective shows how the different entities communicate with each other in order to accomplish their tasks. This maps to method signatures that determine how methods are evoked and what they return.
Finally, the implementation perspective is the code itself.
It’s a good idea to separate these perspectives out when building software, and in fact if we look at the twenty-three design patterns from the Gang of Four we would notice that by and large these three perspectives are separated out, and this is one of the reasons patterns are so useful and so easily maintainable.
March 12, 2016
Discussing Beyond Legacy Code on Agile for Humans
Listen to a great interview with me, Ryan Ripley, and Woody Zuill on [PODCAST] Agile for Humans where we discuss my book, Beyond Legacy Code, the software industry, and many other topics: http://ryanripley.com/beyond-legacy-code-with-david-bernstein-and-woody-zuill/ (11 Mar 2016)
March 9, 2016
Getting Started Writing Beyond Legacy Code
Most fundamentally, I wrote my book because I wanted to make the world of software development accessible to many more people outside the software industry.
I had accumulated a lifetime of experience as a software developer. In that time, I had come in contact with many individuals who I would consider to be outstanding developers. I study these people to understand what they knew that made them so great.
What I learned is that everything that experts know, we can know. And when we do, we can get very similar results.
I’ve seen team after team reinvent the wheel, so to speak, until I tried to help them normalize around certain practices that would give them the most benefit. This is really what *Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software* is about. It discusses what I have learned about applying these practices correctly and some of the pitfalls that teams can fall into when they don’t understand the purpose behind practices.
I feel like there are a lot of how-to books on the market that cover most of the practices in Agile, but very few books really delve into *why* the practices are important. My book focuses on the motivation behind the practices so we can better understand and use them more effectively.
I knew these practices were effective because I helped some of the top teams in the world apply them. I saw developers struggling to make many of these practices work but only because they failed to see some key distinctions. When I showed developers these distinctions, they were typically able to overcome many of the challenges they were experiencing. Many continue to use these practices years later.
Since I was successful in coaching and teaching teams how to use these practices, they avoided many of the common pitfalls of adoption. I wanted to be able to find a way to write this down and share it with a larger audience through a book, but I found writing a very challenging process. I tried for nearly a decade to sit down and write out my ideas, but they always came out rather boring.I figured if my text bored me then it will surely bore a reader, so I threw it out and started over.
And over.
And over.
It was nearly a decade of trying and I had accumulated a lot of text but it wasn’t forming a coherent whole.
And then I came across a book with a strange title by Steven Manning called How to Write A Book on Anything in 14 Days or Less Guaranteed. I thought it was a joke but I picked it up and I started reading.
The first thing I noticed was how easy it was to read his text. The information just seem to flow. The author was very encouraging to the reader and this was something I wanted to do in my book as well. There are also several misspellings and punctuation errors leading me to believe he used the techniques he was suggesting to write his own book.
His ideas are sound: have something to say, write an outline and then expand that outline into what he calls a blueprint that includes keywords and phrases that you want to use as well as transitions from one topic to the next. I think of the blueprint as my script, living with my filmmaker wife, I get exposed to narrative storytelling and I try to incorporate that in my non-fiction writing as well.
I used beats to map out my blueprint. A beat in scriptwriting is the character’s next objective. Actors map these out on their scripts so that they know at any moment what their character is doing or thinking or feeling. I try to do the same thing with the material I bring to my dictation sessions so I have a good sense of not just what I want to say but how I want to say it. I also leave a lot of time for unscripted material though after I go over an idea, I’ll just keep talking about it, asking and answering myself questions about it to deepen my understanding.
Manning says the faster you write, the better your write and I think that’s true for me.
It always seemed that I had a bandwidth problem in the past. My mind would go faster than my hand could capture. I tried typing and writing out on hand but I still could write fast enough so I’d lose my place and get confused.


