Let us talk about time for a second, okay? We deal with in just about every application we write, but we treat it quite dismissively. But let me give an example first. We need to build a notification system, the system is based on timed notifications that should be displayed in a web page.
Thinking about it, I came up with the following design:
And this query:
SELECT TOP 3 Id, PublishAt, Title, Content FROM Notifications WHERE PublishAt > GETDATE() ORDER BY PublishAt DESC
That seems to satisfy the requirements, it is simple and it works. Done.
Not quite, this system design suffer from a pretty important problem, the time transitions are implicit. But why is that important?
Because the state transition from waiting-to-be-published and published is a meaningful transition in our domain. As a simple example, I can’t post a notification to Twitter when a notification is published, simply because I have absolutely no idea when that is going to happen. In many real applications, silent state transitions are going to lead to a lot of hacks. Likely something like adding WasPublished flag that we can check and then do some action if we get a notification that wasn’t published yet.
A much better plan is to model things so that time is an explicit state transition, instead of just checking for PublishAt, we will check the IsPublished flag, and we have a background process that will check for the PublishAt and the current date and explicitly set the IsPublished flag. That is also the place where we will place logic relating to the state transition. It also means that we aren’t depending on a side affect (someone viewing the page to cause the publication process) to make something important happen in our application.
You might have noticed a theme here, I like making things explicit, it means that it is easier to handle them.