1. 21
  1.  

  2. 25

    I agree that we need to be flexible. There also shouldn’t be a taboo against premarital specs.

    1. 13

      Structure your code in such a way that you don’t have to commit to major decisions up front

      In so doing you have committed a huge decision that will inform the entirely of your design process, and that is the decision to do everything so that you don’t have to make a decision.

      You could never right if you didnt allow yourself to be wrong.

      1. 6

        This implies that the only way to make a code base flexible is to add code that supports any given use case. I don’t agree.

        To make a code base flexible, simply allow the existing code to be changed when (not if) the reality is different than expected.

        The code bases that are most suitable for this in my experience, are the ones that are not designed for the future, but are the best match for the current feature set. Until a new feature comes in and the design is changed to match the new feature set.

        1. 3

          Strongly concur. I’ve lived through ongoing development of products where someone committed to the decision to make every feature flexible in case it might need changing later and it sucked. Everything was much harder to work with, it was much harder to find out where any given decision was being made in code. To add insult to injury, by and large the places we did find we did need flexibility were not the places where it had been preemted.

          The one thing I would advocate for is to stick “v1” in your API URLs somewhere so you can do a phased migration when you eventually decide that the first design was terrible and you want to redo the interfaces

          1. 5

            Completely agree those types of codebases tend to be the worst (and it is frustrating that “flexibility” is not a measurable quantity yet people tend to trade measurable performance and readability for it, but that’s a rant for another day…)

            However, my take-away from the OP was not to build a flexible architecture (and by consequence, end up with Enterprise Solutions as I like to call them), but to instead treat architecture like a game of Sudoku, where you fill in squares as they become obvious but not beforehand.

            (Of course, very hard games of Sudoku (much like architecture) will get to a point where a decision will need to be made which isn’t obvious, and can have drastic consequences down the line, such as an unsolvable game or a complete re-architecture)

            1. 5

              I like tef’s “build code to be easy to throw away” lecture for making this point unambiguously. <3

              1. 4

                my take-away from the OP was not to build a flexible architecture (and by consequence, end up with Enterprise Solutions as I like to call them), but to instead treat architecture like a game of Sudoku, where you fill in squares as they become obvious but not beforehand.

                Yes! Love the sudoku analogy, really nice way to think about it.

            2. 1

              That is an excellent point! As soon as you do anything in a software project you are making major decisions - architectural paradigm, choice of programming language etc. I guess I am trying to be a proponent of avoiding making every major decision up front if you don’t have to.

              1. 2

                I think you can actually go one step further: don’t shy away from changing the architectural paradigm and even the choice of programming language if the changing insight in the functional specification asks for it. If you don’t allow yourself to do this, you will always end up with a sub-par system design. Because as you so eloquently point out in your article, the spec, or at least your understanding of it, always changes during development.

                Of course there is a tradeoff to be made between having the perfect system design and the reality of having to actually deploy the system at some point, but that’s a different discussion. The fundamental insight is that in an ideal case, you never design a system upfront but instead let the design evolve along the way.