Composing features
A few years ago I took the challenge to be outside for 1000 hours in a single year. At the start, I logged outdoor time in an EDN-based DSL on my computer, but since being outside often meant being away from my computer, I captured outdoor time on my phone, then transferred it to the computer when I was back at my desk. That was minor but annoying enough that I made a simple mobile app. I've done a little mobile development, but not a lot, but I'm familiar with Clojure, so I used ClojureDart and learned enough Flutter to make an app that was good enough to get me through a year of logging. When I decided to build a personal statistics platform and listed ways I could have used such a thing in the past (the jobs to be done design practice), tracking time outside was one of the jobs I would have used such a tool for. The tool didn't need any new features, just the same data entry and basic visualization as other jobs, but again logging time I spent outdoors inspired a new feature, one that was small but which composed existing features in a way that's been useful for other types of entries too.
In Two Ravens, a basic entry for tracking time outside looks like this:
The timestamps here show as form inputs when editing the card, but when the card is saved, those timestamps are omitted from the summary and only shown to the left of the entry card:
The simplest visualization is a number that shows the sum total duration of all the entries labeled "outside":
That worked alright, but it was bothersome every time I added an entry to switch from the log to the view to see the new total. A better workflow was to embed the outdoor view directly in the entry's summary.
Fortunately, entries already supported fields for YAML data, so I decided that the app should recognize a special field named _summary that would contain a configuration of how to render the summary card, including what views to embed. The syntax could be as simple as:
views: [outside]
Which produces a summary like this:
That was an unanticipated but beautifully simple combination of three existing features: YAML fields, views, and entry summaries.
I hadn't planned for entries to contain data visualizations, but using the app day-to-day revealed the importance of it, and the features I had already built into the app composed nicely to make this new capability easy to add.
As a software engineer, composing functionality in code is second nature, but capabilities can also be composed as a product owner. The trick is to choose abstractions with the right boundary interfaces, ones that allow combinations that create satisfying new features.
Do you have any stories of features that composed in powerful ways? If so, email me! As I learn more about being a product owner, I'd love to hear about your experience.