Just Good Enough. That is what we need.
I need code just good enough to work, then you can make it beautiful, after its working.
I need requirements just good enough to start a conversation, then we can refine and revise.
I need architecture and design just good enough to ensure feasibility for a delivery cycle, then we can harden, and make it more robust.
I need plans just good enough to get started, then we can add detail and revise ad nauseum.
If you want to go fast, you need just good enough. Sure just good enough may not be good enough for ever. Just good enough to start may not be good enough to finish. That is the point.
In order to work using the Just Good Enough principle, I need people who are willing and able to deal with the emergence of information, who can adapt to new information without having a nervous breakdown.
The problem with Just Good Enough is that no one knows what it means. Just Good Enough needs a decision. When is something good enough? What will be good enough? Everything you do Just Good Enough needs a decision! And initially that decision will be made wrong.
This is the difference between having static definitions of process that may or may not apply to your situation, but will certainly pass an audit, and having just enough information to proceed.
Ultimately, making those decisions repeatedly, reveals some commonality that can be institutionalized. Call them informal rules of thumb about what is Just Good Enough. But rather than developing some universal framework or process that can be (must be) applied to everything, you end up with only the rules that apply to your specific situation.
One asks how does one know what is Just Good Enough? From experience. How does one get experience? By doing things that turned out to be not good enough.
Aye, there’s the rub. Ultimately following the Just Good Enough mantra will lead to a tuned efficient and effective process. You learn what is good enough, and what is not, trying to avoid the unnecessary. Good enough reduces the chances that you will fail increasing your effectiveness. Avoiding the unnecessary reduces your wasted time and effort increasing your efficiency.
Here is another! Just Good Enough for me is not good enough for you. Or Just Good Enough for me is Too Damned Good for you. The responsibility is always on “us all” to decide what is Just Good Enough.
The Agile community has a Just Good Enough rule that they espouse. It follows the acronym YAGNI – Ya Ain’t Gonna Need It. For software developers it means don’t build capabilities that haven’t been requested because they might be useful “someday”.
When I was in College, I had a professor Sam Uselton who I remember having said that every system would end up being constructed three times. The first was an experiment, a opportunity to learn about the essence of the domain. The second was an expansion of capabilities exploring the boundaries of the utility of the system. The third was with full knowledge of both the essence and the boundaries of usefulness and delivering a product true to the essence, but only expressing the capabilities of sufficient utility to warrant inclusion.
I know Sam was a huge fan of Fred Brooks (author of “The Mythical Man Month”). I am quite sure that this was wisdom Fred would have sanctioned and approved of.
Here are some other rules supporting Just Good Enough:
1) Generalize the third variant – when I have something that seems that is re-usable, resist the urge to abstract the re-usable portion until I have three variants. Having two things that are similar is OK. Having three things that are similar is an abomination.
2) Working, Then Working Correctly, then Correctly Implemented, Then Done Right. – when I build something, I make a quick foray to make something that I can “demo” to get feedback. You can’t get good feedback on non-working software. Then I take that feedback and make it work correctly. Then I refine the implementation so that it is clean, has proper structure, remove all extraneous crap. Then and only then do I ensure that it is polished and following all coding standards and practices. I ask where in this structure would you implement automated unit tests? No sooner than Working Correctly. Then as I Change the implementation and refine the code, the tests keep me from breaking the functions.
3) Don’t use a platform when a framework will do – Frameworks are small. Platforms are big. If you need a framework for persistence, don’t use one that is part of a larger more sophisticated platform that will make you jump through other hoops to do persistence. Building your own small purpose built frameworks isn’t as bad as adopting a vended or vendor-less platform that rules your life.
So feel free to be Just Good Enough.