It is needless to say how powerful is Specification by Example for requirements exploration and for Acceptance Test Driven Development and simply for communicating the intent from Product Manager to Product Owners (POs) and from POs to teams and backwards… (see my earlier post: Specification by Example: Simple Questions to Understand a User Story, and more generally, a good book by Gojko Adzic on this subject: Bridging the Communication Gap). It is extremely powerful technique because it keeps everybody focused. We know infinitely many examples when abstract requirements/statements simply don’t capture teams’ attention and inconsistencies go unnoticed, ambiguities remain undetected and new ideas (if any) are being built on the shaky assumptions.
But Specification by Example also works efficiently when addressing the design challenges. This set of problems are well familiar to architects, and even more so to software developers who quite often have to deal with system design that does not adequately reflect the expected system behavior and capabilities, and so further system maintenance turns out to be constant hacking. This often happens because the initial idea behind the design is based on too abstract thinking and assumptions. Based on experience creating complex systems and maintaining them over time, suggestion can be made:
Grow system architecture gradually, conduct regular architecture workshops, use Specification by Example to explore design options.
Let’s consider an example.
We build a bookmarking service and want to introduce a new feature: fuzzy match for tags. Agile team needs to understand what an impact this has (and what should they do overall) on system architecture.
We start our design workshop with from the highest level – new requirements and product owner comes up with the simplest successful scenario:
“Given that I search my bookmarks for ‘games’, when I have a bookmark tagged as ‘games’ – it should pop up in the top of the search (scenario 1); when I have a bookmark tagged as ‘gaming’, it should be in the second order of relevancy if their exists an exact match, otherwise it goes first (scenario 2). ”
Now, let’s see how it maps on to the level of system components.
Scenario 1 is quite clear so far – it does not involve any changes to system design, at least nothing visible yet. Scenario 2 though starts attracting our attention. Indeed, this is a new behavior. People start talking thru their thoughts...
Developer: “Scenario 2 actually means that our search layer passes ‘gaming’ to the search processor and the latter somehow matches it to ‘games’ and then just performs a search for ‘games’ and returns back the results”.
Architect: “Well, I’m not sure. What if we have both tags (‘games’ and ‘gaming’) in our DB and then search by each of these keywords respectively? ”
Tester: “I think that the search results should be just the same. This should be symmetric searches”.
Architect: “Exactly!.. See what I’m saying?.. there has to be the invariant result set dependent only on tags and not on the search terms, whether this is ‘games’ or ‘gaming’”.
Developer: “Oh, I see what you mean. This means actually, that between search layer and search processing component needs to be some ‘normalization’ that would find a common denominator for those tags? Like a simplest word form or something like that?”
Product Owner: “…you mean that the system will actually perform a search on ‘game’?! Is that right?”
Tester: “Guys, I certainly like your excitement about this ‘simplest form’ thing but that way we miss one important requirement: exact match (say, ‘games’) will never appear in the top if that’s the exact match”.
Architect: “Good point. Means we should be passing both the simplified form and the initial form and make a correction for the search results…”
Developer: “Do we even need to pass the initial form? What if we just pass the remaining suffix?”
Architect: “Makes sense. Another point: now when saving tags we have to save both ‘game’ and ‘ing’ for tag ‘gaming’ and store it that way, otherwise the search processor will not be able to make the match”.
Product Owner: “Guys, but I just thought that this is not it – fuzzy search is wider than that: it also covers matching of ‘games’ and ‘agmes’, for example…”
Tester: “Huh, how about matching ‘games’ with ‘agming’?”
Developer: “Let’s not try to put it all into this sprint. I see what you mean. It seems like we can already start thinking about checking words against dictionaries etc. But let’s just get fuzzy search without typos for now”.
Developer (to Architect): “Can we now have some secrecy at the whiteboard with respect to searching by dual terms: ‘gam(e)’ + ‘ing’ because I still have some questions?..”
Architect: “Sure thing. ” (to Tester): “could you please come up with 3-4 more concrete examples that would be totally different from this ‘game-games-gaming’ subset?”
And finally, there can be no efficient design workshop without a whiteboard…