- Published on
Time, angle and depth: dimensions in software design
- Authors
- Name
- Damian Płaza
- @raimeyuu
This blogpost is based on the plot that happened in one of the previous posts: Context Segregation Principle.
I greatly encourage reading it in the first place.
I hugely recommend reading Balancing Coupling by Vlad Khononov - there are another set of dimensions (and more!) that can be used while designing systems.
It's all different?
Imagine a person named Samwho is the sales person of a company selling floor panels.
After the events happening earlier, Samreported to his Bossthat struggled with communication towards his "colleagues": Igorthe installer and Williamthe warehouse worker.
So Bossdecided to organize a joint meeting to discuss the situation.
"Communication is important in our company.", said Boss.
All arrived at HQ to participate.
Bossagain was speechless.
Speaking without understanding
All the representatives of each company function missed the point of another one - including Boss's point brought in front of Sam's face.
Each of them was an expert in his area - selling, storing and installing.
Bosshimself was expert in closing big deals, building relationships and making sure that the company is profitable.
Each capability is required to make the whole company work - you can't install panels if no one actually bought them.
You can't sell them if you don't have them in stock.
"Is there a way to see the whole picture?", Bossasked himself.
Bosstook a deep breath and tried to calm down himself and the situation.
Bossgot an enlightenment.
As each of the participants was expert in his or her area, dealing with a very specific fraction of reality, in a particular moment of time.
Even if all "saw" a floor panel, while communicating with each other, they were talking about different aspects of it!
Each of those aspects was important but not always in the same moments of time.
So each expert used some aspects of a floor panel, when the time has come.
Typically, when one function handed the work off to another one.
Bossinvited all parties to have dinner tonight.
Calming everyone down and making sure they understand each other, not as a company functions, but as human beings, should make everything smoother and better.
Also, Bossdecided that each of them should spend at least one week in another area, to understand what is the context that others are dealing with.
Abstractions
"An abstraction" is quite loaded and biased term in software world (hence it is a part of The ambiguity of series).
How often we deal with abstractions, dear Reader?
Is it just "what we craft" in the code?
"What are you talking about? What abstractions have to do with floor panels?!", one might ask.
As we saw in this tiny tale, all the characters were talking, but were they understanding each other?
In earlier tale, Context Segregation Principle, we explored the idea of decomposing "reality" into a set of contexts.
This can be depicted by that diagram:

Even though we, human beings, communicate with each other using words (like "a floor panel"), we rarely mean the same thing as we think of a specific aspect of this thing, rather than "this thing" as the absolute.
Taking away the details
So we are "taking away the details" of this "absolute thing" in order to simplify our operations while dealing with the reality, which is full of inifinite details.
Abstractions - when?
Why are we "taking away the details"?
We do so to simplify our reasoning about something, now.
I mean, not "now now", but in the given moment of time.
Or "when it's needed".
Ok, so then let's follow up with another question: when are we "taking away the details"?
We do so when details do not matter, of course (kinda surprising answer, isn't it dear Reader?).
One could say that we are looking at something from a specific angle (or perspective) as it is what matters in this particular context, in that particular moment.
We capture the essence of a specific aspect of something in order to reason about it a certain way and possibly use this knowledge while further designing a system/a process/interactions.
Let's bring back the diagram from before:

As we experienced the tiny tale, dear Reader, "in order to make the customer happy" all the "company functions" needed to play their role in a sequence of steps.
A sequence of steps implicitly brings the dimension of time.
Can you tell what is missing in this picture, dear Reader?
We only see contexts in a static manner, without getting the information how and when do they interact.
Imagine that we are taking a big, illusionary and "abstract" (pun intended) scissors and we cut (1) it right on one of the boundaries. Then, we "unfold" (2) the "wheel" made of all abstract ideas:

I hope you are able to do this exercise and visualization in your mind, dear Reader.
If not, here's a result of doing so:

Nothing really changed as we see abstractions (or perspectives, interchangeably) not in "a motion".
Let's add the time dimension:

And now this is when the magic happens.
Temporal modeling?
Thanks to adding "time dimension", we have the possibility to represent the interactions between various "perspectives" on the same "thing".
So this opens a possibility for us to see "things in motion" - how abstract ideas interact with each other, when various contexts are involved.

It might look familiar to you, dear Reader.
"Bravo, you just invented a sequence diagram!", one might say.
Or Event Storming, or BPMN diagram, or whatever we can call it.
What we just saw, resembles more "handoff diagram" introduced in Workflow Modeling (at least that's where I read it for the first time).
Thanks to "time" we can see (almost) complete picture - when and what are the interaction patterns between various segregated contexts.
Taking perspective and time dimensions we can make "the absolute concepts" (like User
, FloorPanel
, GroupChat
, Product
) ceasing to exist (at least mentally).
This little diagram we brought to life isn't as detailed as many Event Storming and BPMN diagrams out in the wild - but it gives us the possibility to see the patterns and then start discussions.
It's one of the levels - we can go deeper and inspect important facts happening, check if there are any important rules that need to be satisfied, and so on.
If something is looking superficial or trivial - change the perspective or change the level.
What about depth?
Yes, depth.
In Modeling Maturity Levels we explored the idea of "depth" in modeling - which gave us powerful tool to reason about how can we model one particular aspect of something.
But don't get fooled, dear Reader.
We might uncover new perspectives (=abstractions) as we are transitioning between levels, e.g. while browsing Behaving level, we might discover that there's another perspective that appears in a particular moment of time (which means - interaction).
If we represent "a floor panel" as a class, we might uncover that a method Install
can't happen if it wasn't delivered first:
public class FloorPanel
{
public void Install() {
if (!Delivered)
{
throw new InvalidOperationException("Can't install a floor panel that wasn't delivered yet.");
}
// installation logic...
}
}
Hence we might split a single abstraction into two - InstallationMaterial
and InventoryItem
, correlated by a single identifier.
InventoryItem
won't ever have Install
behavior, but InstallationMaterial
will.
Such contextual segregation might make our sight so sharp that we will see that InventoryItem
Becomes InstallationMaterial
when it's delivered.
Suddenly we start modeling concepts on the "highest" possible level - Becoming level. (but of course there is The cost of modeling effect).
And here we are getting a sequence of steps - a process.
So one could state that each dimension reinforces our designing and modeling as we are getting the feedback from this process.
In order to get those diagnostic signals while modeling, we need to Slow down.
Other dimensions?
Turns out that there are other dimensions that one can (and I believe should!) use while reasoning about systems, processes and modeling.
I am talking about ones presented in Balancing Coupling by Vlad Khononov.
To tease you a little bit dear Reader (hence hoping this will encourage you to buy and read the book), I will reveal one interesting tool (and useful in terms of changing the mental model) that Vlad introduces in his profound book.
Vlad brings to us the following "equation":
PAIN = f(Strength, Volatility, Distance)
PAIN = Strength x Volatility x Distance
This formula describes "the pain" (or "the cost incurred") one might experience while introducing a change in the system, hence maintaining the system.
Each "part" represents some aspect of the system:
- Strength represents knowledge shared among two "concepts"
- Volatility represents how often two, coupled "concepts" change
- Distance represents how far apart those two "concepts" are in the system (file-wise, department-wise, etc.)
"Ok, why the hell you brought even more abstract terminology, Damian?", one might ask.
I was just wondering - how might "PAIN dimensions" relate to time, angle and depth dimensions?
At the time of writing, I feel that dimensions summed up in this blog post appear firstly in the continuum, as we need to have abstract concepts to work on, and then verify "the pain" related to changing them.
Time, angle and depth might help us with training our brain and eyes to "see more" while reasoning about "the business reality" - segregate contexts, look through various levels, observing how all those concepts and contexts interact over time.
Simultaneously, we can simulate changes (e.g. of the requirements) that will challenge summoned concepts' integration strength, volatility and distance.
Such simulations might help us verifying what maintenance pain/costs we might experience.
Is it useful?
"Ok, but how can I use it while coding?", you might be wondering dear Reader.
Imagine that we are dealing with a web application and in order to ensure that the session is established, we need to have a user logged in which will be represented by obtaining an access token.
So we might be dealing with a given structure in application state:
type AppState = {
user: User | null;
accessToken: string | null;
// ...and more!
}
So every time we want to do anything with the token, we must check if it is non-null.
if(state.accessToken) {
// do something that requires the token to be present
}
But wait, we know that after certain time the token will be present so why the heck we need to check that the access token is there?
Maybe we are missing a perspective here that transformes itself into another one, e.g. UnauthorizedAppState
and AppState
?
Eventually, we might discover that we are dealing with state machines and model essential aspects of such interaction accordingly ("a fraction of reality").
Of course, it is a toy example, but I hope you get the point, dear Reader.
In my humble opinion we are capable of using those dimensions (time, angle and depth) while working with the code as long as we are able to "receive the diagnostic signal" sent by the software constructs we are working on.
Feedback and openness to it is the key here.
Based on such reasoning, one could state that time, angle and depth are ways to decompose the reality into a set of cohesive concepts and "PAIN dimensions" are there to validate if decomposition "holds" after "we shake the model".
Time, angle and depth
It is so fascinating that many people across the world, in different times and places, came up with similar ideas - especially when it comes to using time in modeling.
It might constitute "a proof" that we are dealing with something universal, something fundamental that precedes everything we do and "see" (subjectively).
Some methods and approaches vary in the syntax, the nomenclature and the details, but the essence is the same - we must look for abstractions on various levels, constantly including the domain of time in order to design boundaries and assign responsibilities.
We must do so as that is the way we can deal with inevitable complexity of the reality we live in.
Next time, dear Reader, when you will be dealing with a problem, either in the code or while having a whiteboard session, remember about dimensions of software design.
Look at "things" from various perspectives and through various levels.
Check how they interact and possibly change over time.
Simulate changes and observe the cost (or pain) it incurrs.
Suggest at least three models so that you don't be afraid of The cost of modeling as you will be able to balance coupling.
And remember - if you are facing an absolute-looking concept (like User, GroupChat, etc.), treat it as an alert, a signal to start asking questions, e.g.
When does this "thing" appear?
What workflow are we talking about?