As we prepare to bring some new developers on board, it’s worth taking a look at a few of the things we do that make us successful. Sometimes we internalize these things and, not having had to explain them to anyone for a while, they kind of dissolve into habit. Or dissolve into habits we don’t think we need to practice anymore. Documenting our coding decisions is one of the reasons we can support so many customers with such a small team. It’s easy to overlook, but it works.
This is the second post in a series that formed the basis of my 2017 DevCon session on Increasing Code Quality While Staying Lean. Check out the first post for an introduction to the series. We’re looking at techniques that have made a big impact at SeedCode and we hope you’re inspired to incorporate some of these into your work.
Documenting Decisions – We’re Coding for Our Future Selves
We’re coding for our future selves—both in our products and in custom work. We end up coming back to our own code months later and sometimes it’s as opaque to us as if we’d never written it.
So when we make decisions, we want to document them so that our future selves (or our teammates) can more quickly pick up the thread when they return to our work.
This means you can restart projects more quickly, which in turn increases the delivery velocity: especially the velocity of delivering change requests and bug fixes.
[bctt tweet=”One definition of fragility: the original developer is the only one who can help this customer.” username=”seedcode”]
Here’s what we do:
- When we comment out or change code in a script or in a calculation, we include a note in the comment about why we did it.
- If work is related to a Manuscript case, we include the case number in the comments: it’s amazing to be looking at an If() statement you don’t think should be there and see this telling you exactly why it’s there… “If filter is not empty and field DOES NOT match this source: Case 30325”. Now you can go read that case and see the real-world situation that required the If() statement.
- When we’re building a new feature and we decide between competing alternatives we write about that in the case or in the product docs. (For an example, see “Why Make This a Switch?” toward the bottom of the article here).
- Sometimes we start docs for features that haven’t shipped yet so we have a place to record the details of implementation as we’re creating them. It’s much easier to jot down these details as we’re building than to try and reconstruct them later.
- In FileMaker, any script that’s changed gets the Manuscript case number related to that change added to the header comments in the script. For products, we also include the build number we’re working on. This means that if we want to see all the scripts changed in a particular build, we can just use The Tool to search for the build number across all our scripts. (We used the FBz prefix when Manuscript was called “FogBugz”.)
- And all commits to our repo (we use Kiln and GitHub) should include the case numbers related to that work. When we do that, our commits flow back into Manuscript, linking the commit to the customer. When we’re reading back through cases and wondering if we really solved / shipped this, the case numbers help us know for certain if and when we shipped a fix/feature.
[bctt tweet=”We write code once, but we support it forever.” username=”seedcode”]
Well, sometimes we write it more than once 😉
But all of these strategies are about creating a path from the customer’s cases (or feature specs) to the code that addresses them—a path that our future selves can follow. Creating a path means making links between things, not just comments. So paste in URLs and case numbers along with your comments.
Having a path reduces restart time and increases role portability. Meaning your organization (not just your code) is less fragile: less susceptible to schedule changes, minor emergencies, or one of your developers just having a low energy day.
I am trying to adhere to most of the points you’re making but am wondering about the version control part you mention: How do you handle that in a FileMaker-world? Is there any decent support for git out there or do you manually edit/copy the scripts you’re working on into a text-file-based folder structure? Or is this more of a “team git” where you soley track your changes and add the parts you’ve edited?
I dream of a more dev-friendly FileMaker workflow with git-support, that would be awesome!
> I dream of a more dev-friendly FileMaker workflow with git-support, that would be awesome!
Me too! =)
We don’t t anything acrobatic like check DDRs into version control or copy scripts’ XML into their own files. We just check in the .fmp12 binaries themselves. This means we can’t merge code but we can get the other benefits of version control: the team always has access to all versions of the app, and by using case #s in our commits we know which cases were addressed in which versions. Even without code merge, the commit history for a FileMaker repo is like a high-level development blog: one that’s kept up to date for you. =)
Thanks very much for this series. Such an important topic, and I enjoy reading your thoughts on this.
Wondering if you might share a word or two about the choice of using “1 = 1” in line 21 of the example script in the first image. Any special rationale for preferring this to using True or False reserved words?
Thank you again & kind regards.
Thanks for then kind words, Steve. Nothing too serious about the 1=1 switch: I’ve just felt it was tough for beginners to know if it was “True” or True, The equals version just seemed easier for new folks. If ( true ) seemed like code; if ( 1 = 1 ) seemed like logic and somehow simpler. Writing that out now it seems kind of silly, but if it’s even a little more readable that probably maters. =)
The more I read the 1=1 style, the more I like it. I can’t for sure say why, but, at the end of the day I guess it must read just as well (or better) for me than True/False.
Thank you again.