Author: Chris Johnston

  • Chris’ First Rule of Software Development

    Chris’ First Rule of Software Development

    I once worked with a team that, for some reason, valued complexity. It seemed like their egos were tied directly to how hard something was to do. If something was hard and they completed it then that proved that they were smart 🤷‍♂️? I tried multiple times to introduce the idea of simplicity to them, but it never stuck.

    In response to the above, I developed a simple rule that I follow and I tell every team I work with and every engineer that I teach and it is:

    “If what you are doing is getting more and more complicated, then you are heading down the wrong path. Conversely, if what you are doing is getting simpler, then you are probably headed in the right direction.”

    Me

    That’s it. If what you are doing is hard, then stop, think, maybe backup and figure out what you’re missing. However, if what you are doing is simple, easy to reason about, and straight forward, then keep going.

    You will notice that the complicated path is phrased as an absolute whereas the simple path is less certain. That is because we have to take into account that

    For every complex problem there is an answer that is clear, simple, and wrong.

    H. L. Mencken

    Thankfully, the opposite is also true. There is a solution that is clear, simple, and correct. And, as engineers, this is the solution that we should be constantly aiming for.

    In everything we work on there are two kinds of complexity; Inherent Complexity and Accidental Complexity.

    Inherent Complexity

    This is the complexity that is part of the problem. Think calculating compound interest. There is nothing that can be done to simplify the calculation, it is just complex. However, we can still isolate that complexity, trim it down, and find the simplest form of it to initially implement.

    Accidental Complexity

    This is the complexity that we as developers introduce to the code base by not taking time to refactor or problem understand the problem we are trying to solve. We go for the easiest implementation, shove the new code into place and then call the problem solved. And we don’t take the time to be professionals. I always use the analogy that this is like going to the doctor and finding out that they couldn’t be bothered to sterilize their instruments before seeing you.

    This idea of simple is reinforced by the second rule of Test-Driven Development (TDD). Get the test to pass by implementing the simplest thing that will work. And by the third step of refactoring. If we make a mess, we also need to take the time to clean it up. We need to pride ourselves on the simplicity of our solutions and not how hard it was to implement. This isn’t to say that refactoring is simple.

    “…for each desired change, make the change easy (warning: this may be hard), then make the easy change”

    Kent Beck
  • Thoughts on Static Typing

    Thoughts on Static Typing

    I don’t think I am the only person out there that has noticed a trend in the software engineering community away from dynamically typed languages like Ruby to statically typed languages like TypeScript, Java, and Kotlin. What I don’t entirely understand is why. While statically typed languages do provide some nice tooling and work well with IDEs and VS Code, I don’t think that’s the real reason that people are adopting them.

    I think the current love for Java, TypeScript, etc., is based on a myth and misunderstanding. It’s based on the idea that if the code compiles then “it will just work” The idea that if there are no compile time errors, then the engineer must have gotten it right.

    We are at a point where we have Rails and JS applications that are in the hundreds of thousands of lines of code. And the engineers on those projects are having problems. And they think that the solution is to start using, or to introduce, static typing. Just look as Shopify.

    But will static types solve magically make the code base more understandable and easier to reason about? I don’t think so. Contrary to current belief, it is just as easy to create spaghetti code in Java as it is in Ruby. I personally think the problem is not the type system but the engineers and the code they have created.

    Most code bases I have worked on where engineers are asking for static typing either have no tests or very few tests and the engineers do not use TDD and do not refactor. They have spent years creating terrible code and they are suffering the consequences of that. However, instead of cleaning up their code and adding tests, they want a silver bullet and they look at introducing static types. They think the extra tooling you get and the compile time errors will solve their really bad engineering habits and allow them to, once again, extend the code at speed.

    For me, this just doesn’t make sense. It’s similar to wrapping a failing building in scaffolding to help hold it up instead of repairing or replacing the building. It will work for a while, but the building will eventually fall down.

    If you want a code based that you can extend and maintain in a few years your team needs to be doing TDD with constant refactoring. You need to be following Robert Martin’s Boy Scout rule and clean up the code that you are working in and leave it cleaner than when you arrived. And this includes adding tests. This is the only way to ensure you have code that you can reason about, understand, and continue to work on.

  • What is Agile?

    It’s been more than 20 years since a group of software professionals got together and created the Manifesto for Agile Software Development. And yet, I think this question is still just as valid today as it was in 2001. Most people think “Agile” is about daily stand ups, pairing, TDD and the like. They think it is about the processes and rituals that development teams practice on a daily or weekly basis. However, these practices represent XP (Extreme Programming) or Scrum and not Agile Software Development. So if Agile is not about practices, what is it.

    The reality of the manifesto is twofold: 1) it was a reaction to waterfall and 2) it represents the only points that the people that created it could agree on. Each of the signatories of the manifesto went to Snowbird with different ideas, different processes, and different theories on how to create software better and in the end, the four points in the manifesto really represent the intersection of all those ideas.

    We can get a hint about what the manifesto is about by looking at the words, or word, used. In particular, “Agile”. What is agility? According to the Oxford dictionary, Agile, or Agility, is the “[ability] to move quickly and easily.” This is important. The Manifesto is about moving quickly and easily. It’s not the Manifesto for planning software development or the manifesto for ritualistic software development, it’s the Manifesto for Agile Software Development.

    Let’s look at another definition; “ability to think and understand quickly.” At the heart of both of these is the idea of change. Changing easily and quickly in response to some stimuli. It means changing course, focus, ideas, visions, and most importantly, plans.

    I would posit that planning and agility are antithetical to one another. If you have plans, you have rigidity. You have ideas that cannot change. If you have a 3 or 6 or 12 month plan for features that have to be, or should be, released and ROI calculated on those features, etc., you don’t have Agility. Therefore, in order to be Agile and follow the ideas in the Manifesto, you can’t have plans. The question I know many are asking is how do you develop software without a plan.

    Simple; you develop software through feedback. Remember, a aspect of Agility is the ability to respond quickly. But to respond to what; shareholders, stakeholders, customers, user research, etc.? Yes to all of the above. The basic idea here is that you create an MVP (Minimal Viable Product), release that into the wild, and respond to the feedback that you get. And by MVP, I don’t mean something that you take months to create. This should be something that is created as quickly as possible and then released to see how it fairs. This is an experiment.

    At the heart of Agile Software Development is the idea of generating experiments and see how they do. Some will fail, some will succeed quickly and then plateau, and some will get adopted slowly and then take off. But at the heart of all the experiments is the fact that you now have data. You have experiences and anecdotes and stories that can be used to refine the original idea and make it better. And best of all, you have spent as little money as possible. Instead of waiting for 12 months and releasing something that is perfect only to watch it fail, you can release an idea, gather feedback, and ensure it will succeed by slowly developing it according to what your users really need.

    At the heart of the Manifesto is the idea of eliminating guesswork, “well I guess we need Y in 12 months, or we hope their will be a market for Z in 2 years” and instead, releasing software by knowing exactly what you got right, what you got wrong, and what amplifying the former and reducing the later. Guesswork and hope is replaced with data and the ability to respond quickly to that data.

    That is what Agile is.

Copyrighted Image