This blog post discusses the relationship between specification and design. Specifically, I will discuss how to leverage function signatures as a specification for modeling business rules and application responsibilities. In addition, this post will start the saga for explaining how a specification can be represented through types and exposed as a library for interpreters to implement.
What exactly is a specification and why is it useful? Committees usually describe how something should work by providing a specification.
A specification may be defined as the following:
A detailed description of the design and materials used to make something.
Translated, a specification could be thought of as a specific design that’s abstract enough for interpretation.
A specification is useful because it gives developers a set of rules to follow to achieve a desired outcome. One could also view a specification as a tool that restricts developers from building the wrong thing.
In regards to software, I’ve observed “specifications” represented as flowcharts, mockups, user stories, and even essays. In an ideal world, these artifacts would be referenced to build some form of a compilable specification that’s usually in the form of an automated test suite. Sadly though, the majority of codebases aren’t backed by automated test suites. Translated, the majority of codebases don’t convey their intended specification.
Specification as Tests
Earlier, I discussed the notion of compiliable documentation in the form of automated tests. Automated tests (done right) are extremely valuable and can serve as up-to-date documentation regarding the features of a system. Every test should at minimum convey the setup, test, and verification for a given feature. These steps alone serve as a form of specification.
Test Driven Development is a strategy that some developers use to ensure that their code complies with a specification. Thus, having automated tests is one step closer to a codebase conveying its specification. However, even though a suite of tests could drive the design of a feature, there’s still an obvious division between the tests and the codebase that the business actually relies on. Translated, we continue to have codebases without any enforced compliance to a specification.
Specification as a Library
The last section discussed how tests could be leveraged for steering code in a direction that aligns to a particular specification. However, tests do not enforce compliance. So how can code be enforced to comply with a specification?
If only there were a way to make a specification a dependency for business logic.