In the previous link, I started my saga to explain an approach for encoding a specification into a system itself. In this post, I will introduce the design phase for such an application.
We need the specification for the software that we’re going to build. Hence, with the specification, we can identify individual domains for the application. Personally, I view domains as subsystems. A subsystem should behave as its own isolated system, thus being ignorant to peer subsystems as well as the higher-level system that encompasses it.
Now let’s imagine that we’ve just received word that the application that’s to be built needs the following:
- User can register an account
- Once registered, a user can login and logout
- Once logged in, a user can create their profile
- A user can set their content
- A user can subscribe to content from other users
- A user can view their followers
- A user can view the people that they follow
- A user can unsubscribe from other users
- A user can feature specific content of theirs
- A user can feature specific topics that they provide content on
Let’s divide and conquer this influx of requirements by organizing the above requirements into isolated subsystems.
Some of the requirements for the application involved user-session. Hence, a user should be able to login and logout of the application. What would be a good domain name to reflect those type of operations? Let’s create a domain called “Session” as in user-session.
I lightly touched on how I view a domain as a subsystem. Moving forward though, I will use the term domain in the place of subsystem. If we examine our Session domain that we recently extracted from our list of requirements, we should notice a requirement that’s kind of related to our Session domain but is definitely a distinguished operation that should not be thrown under the umbrella that we call a user-session. Hence, before a user can login to a session, they must first have a registered account. Also note that registering an account requires much of the same data that’s required for logging into an account. Hence, both a login and a registration require a user’s credentials. Do we extract yet another domain that has just one behavior and requires the same data (i.e. credentials) that our session domain also requires?
The following would be our Registration domain using the questioned approach:
- Register account
This new domain would be extremely small and as a result, appears out of place because it’s indirectly related to our Session domain. Hence, both Registration and Session domains share much of the same language. Specifically, they both rely on user credentials and they both share responsibility for accessing the system. Therefore, perhaps we should define a new domain that encompasses system access responsibilities. Specifically, we can define a domain that merges a user’s registration with a user’s session. Let’s refactor the Session domain and Registration domain into single domain named the Access domain.
- Register account
The other domains of the system could be exposed as the following:
- Set image
- Set topics
- Edit account information (i.e. name, email, etc.)
- Set content
- Set featured topics
- Set featured content
- Follow user
- Unsubscribe from user
- View followers
- View subscriptions
So far we received a specification and as a result, established a proposal for business domains. This is a good first step for designing our system. Hence, we should identify business-level responsibilities and then identify the specific business domains that should handle those responsibilities. In addition, a maintainer should visually be able to quickly identify the domain of the system that requires updates based on an established hierarchy of libraries and files. I will later share how that can be accomplished. But first, how can we implement a domain’s responsibility and at the same time encode specification compliance as a foundation for our app’s implementation to rest on?
The saga continues…