Published on

Conversation-Driven Design

Authors

How to send a package?

Let's imagine you have a strong need to send a package with some valuable goods to a friend of yours that is located in another city. You either order a delivery man to come to your place and pick it up or you go to the parcel shipment place.

Let's add some interesting conditions to this scenario. An assumption is that there's no other delivery companies in neighborhood and you are somehow forced to pick this particular one.

Additionally, their modern looking sexy SPA web app is facing some issues (maybe they are handling gazillion customers at the time and their k8s cluster struggles? Who knows?!). You must fill in the details manually (😨).

Due to those reasons you decide to select the second option. You enter that facility and the first thought is to find an individual that can help you.

Almost immediately you are approached by an employee and the conversation starts innocently:

- Hi! How can I help you? - the employee asks.

- Hello! I would like to deliver this package - you raise your hands, holding a parcel, a bit higher - I already filled in the form. - you show your handwriting - Can you check if it's fine?

- Yes, let me take a look.

~ The employee checks the form and the delivery letter. ~

- Hmm, seems like you mistakenly swapped address cell and phone cell. Also postal code isn't filled in correctly.

~ You frown your eyebrows a bit, but continue the dialogue. ~

- What's wrong with the postal code? - you asks politely.

- Oh, sorry for not being explicit! You forgot the "-" in between the numbers*.

-------------------

* in Poland postal codes are in the format of XY-ABC

You got your delivery form corrected thanks to the validation you received from the employee. In couple of minutes you finalized a request to deliver your package.

Packages? What is it all about?

Why the heck I bother you with such a dull story that you could (and probably did) experience in your lifetime?

Let's end writing our lovely courier story and use the theme of sending parcel further on.

Imagine you are designing a similar customer facing capability - validating a delivery form.

It doesn't seem complicated, because it's "just" reading some form values, (maybe) sending them to the server and actually getting a response, isn't it?

Wait. What language was used in the conversation with the imaginary employee of the delivery facility?

Of course, nothing alike "server", "form values", "sending", etc. None of us would dare to ask those questions when speaking to the human being, trying to resopnd to the request of delivering a package, right?

Probably (I hope so!) you know where my thoughts are flowing.

Model Out Loud

In the Blue Book - the Blue Bible of DDD - Eric started the subsection "Modeling Out Loud" with the following words:

The detachment of speech from other forms of communication is a particuarly great loss because we humans have a genius for spoken language.

This is a great introduction to the concept of ubiquitous language.

But this subsection pinpoints interesting property of human abilities to comperhend the complexity of a given topic.

He then continues:

One of the best ways to refine a model is to explore with speech, trying out loud various constructs from possible model variations.

This might seem as a counter-intuitive advice, because we, the professionals, are using drawings and eye-based tools to work on our models. Highly visual information reception.

One picture is worth 1024 words, isn't it?

It might be true, but there's something with the auditory traits of modeling.

In the modern world most people know that we, as a human race, use storytelling to convey important values, inspire other people and sell the ideas while standing in the front of other individuals.

As the first primates used grunts and snarls to tell a story of strange berries that put uncle Barry to death, we do similar activites, but in various scenarios and with different scale.

That's also pointed out by the Author of the Blue Book:

In fact, our brains seem to be somewhat specialized for dealing with complexity in spoken language.

Human - Auditory Validator Included

It all "feels" that if something sounds bad or unnatural - we sense it. We don't need to be our native language teacher to catch inconsistencies in the used language.

I am not a language scientist, neither a researcher, but the common sense tells me that the evolution of the speech didn't happen during single night and there are a lot of trial and errors to make our auditory skills on the level we have it now.

Why not utilizing it?

The conclusion of the subsection, done by Eric, is:

Play with the model as you talk about the system. Describe scenarios out loud using the elements and interactions of the model, combining concepts in ways allowed by the model. Find easier ways to say what you need to say. (...)

Saying it out loud. Expressing the use cases, scenarios and interactions almost as if we would tell the story.

But wait, what is the goal of speaking?

Talking as a tool?

We evolved to interact, to talk to each other. Talking to other human beings is therapeutic - we need to talk to other people for so many various reasons - to express, to moan, to share, to validate our point of view, etc.

As the Author of the Blue Book emphasized - saying things out loud might be really powerful technique.

But then - saying to whom? To yourself? Or telling out loud so that your peers can hear that?

Let's get back to our domain of sending parcels. It's somehow natural to think of technical terms about validation of delivery form.

What would happen if we imagine that we are actually talking to a person who does such validation, if there was no internet? You know, a conversation as in the good, old days when there was no Messenger, Signal and WhatsApp.

Conversation - a model for modeling

Thinking of your software constructs as they would be individuals you can talk to might bring interesting properties. And what I love the most: interesting questions. Pretending your are talking to such imaginary person:

  • What questions would you ask?
  • What information this person needs to answer your question?
  • What language would that person use?
  • What concepts would be juggled over during such conversation?
  • What questions would be rejected by that person?
  • Which requests would be denied due to lack of related responsiblity?
  • If that person doesn't use desired terms, should you teach this person with those words?

And, thanks to human development, we are quite good at conversing. It means we might use our abilities to design proper interactions, sense how a natural dialogue might look like.

Use case #1: talking to an sensitive information validation expert.

Let's take another use case.

Recently I had a chance to work with a little capability for validating some sensitive information. Let's say they were stored in some file.

Technically speaking, there was a method accepting a list of keys (their values are targets for validation) and the path to the file. Surprisingly, the return type was bool.

Imagine that this software construct is a validation expert. How such conversation would look like?

- Hi! I have this file - I showed it - and here are lists of keys. Could you do me a favor and validate underlying values?

- Wrong.

~ Awkward moment. ~

- Haha, nice joke! But really, could you take a look on those keys and tell me whether related values are valid?

- Wrong.

I feel that we wouldn't talk any further...

Then, how would an ideal dialogue look like?

- Hi! I have this file - I showed it - and here are lists of keys. Could you do me a favor and validate underlying values?

- Sorry, but values under keys A and B are in the wrong format. The desired format is XYZ.

* Immediately fixing the format issues. *

- Could you check it again?

- Yes, that looks ok.

Such conversation would lead us into a proper solution: taking into account we can use F# types, such "software validating expert" could return Result<(), ValidationErrorMessages>.

Or maybe we should teach it the right language - SensitiveDetailsValidationResult?

Use case #2: talking to an e-mail

I hear you: "Hey, how the hell I am supposed to talk to AN EMAIL?!"

Yes, that might be tough experience, especially that e-mails are not that talkative these days.

In various implementations, a concept of an e-mail is represented as string. Why to overcomplicate things, right?

Let's go further and apply our metaphor of conversing with an expert - this time with "e-mail" expert, the tamer of the chars:

- Hi! I became an owner of the collection of such characters - I present the characters to this guy - could you tell me if this is valid e-mail?

- Sorry, I can tell you if it's empty or null. Maybe you want to know if they are all digits?

* I breath loudly *

- As far as I recall, email should contain an "@" char, etc. You should know that - you are an expert!

- Do you want to find a substring?

For sure this conversation won't have happy ending and we would find some other person that would become profficient in working with string "e-mail" expert - maybe EmailUtils or EmailManager?

How would you model such conversation, where the expert knows the language of the email validation domain?

Use case #3: talking to a dialogue presentation expert

When I started working on this blogpost, I was wondering how to present a dialogue card.

Nothing fancy, really. Just to make sure that it is visually distinguishable from the "regular text". I started embedding the first dialogue from How to send a package? in the following form:

<div class="italic bg-slate-600 rounded-xl p-2">
    <p>- Hi! How can I help you? - the employee asks.</p>
    <p>- Hello! I would like to deliver this package - you raise your hands, holding a parcel, a bit higher - I already filled in the form. - you show your handwriting - Can you check if it's fine?</p>
    <p>- Yes, let me take a look.</p>
    <p> ~ The employee checks the form and the delivery letter. ~ </p>
    <p>- Hmm, seems like you mistakenly swapped address cell and phone cell. Also postal code isn't filled in correctly. </p>
    <p> ~ You frown your eyebrows a bit, but continue the dialogue. ~ </p>
    <p>- What's wrong with the postal code? - you asks politely. </p>
    <p>- Oh, sorry for not being explicit! You forgot the "-" in between the numbers*.</p>
    <div>-------------------</div>
    <p class="text-xs">* in Poland postal codes are in the format of XY-ABC</p>
</div>

In the first seconds, it felt "correct", but as I was using "a conversation as a modelilng tool", I asked myself "how would a conversation with such presentation expert look like?"

- Hi! I want to display a dialogue with some specific background traits where each line needs to be placed in the sequence. Could you help me with this?

- Sure! I take a div for dialogue and p elements for lines - this would work like a charm.

- But you know how to display a chat, right?

- Haha, no worries kid! I am an expert in displaying chats!

At least he would solve the riddle, right?

I stopped there and thought of another model: how would "real" dialogue presentation expert talk to me?

- Hi! I want to display a dialogue with some specific background traits where each line needs to be placed in the sequence. Could you give me a helphand?

- Sure! Just take a Dialogue and put a bunch of Dialogue.Lines inside of it. It should do the work.

- What about the side notices?

- Specify them when you start your Dialogue.

What might be a potential result of such conversation?

<Dialogue notices={[
    "* in Poland postal codes are in the format of XY-ABC"
]}>
    <Dialogue.Line>- Hi! How can I help you? - the employee asks.</Dialogue.Line>
    <Dialogue.Line>- Hello! I would like to deliver this package - you raise your hands, holding a parcel, a bit higher - I already filled in the form. - you show your handwriting - Can you check if it's fine?</Dialogue.Line>
    <Dialogue.Line>- Yes, let me take a look.</Dialogue.Line>
    <Dialogue.Line> ~ The employee checks the form and the delivery letter. ~ </Dialogue.Line>
    <Dialogue.Line>- Hmm, seems like you mistakenly swapped address cell and phone cell. Also postal code isn't filled in correctly. </Dialogue.Line>
    <Dialogue.Line> ~ You frown your eyebrows a bit, but continue the dialogue. ~ </Dialogue.Line>
    <Dialogue.Line>- What's wrong with the postal code? - you asks politely. </Dialogue.Line>
    <Dialogue.Line>- Oh, sorry for not being explicit! You forgot the "-" in between the numbers*.</Dialogue.Line>
</Dialogue>

Leaving technical terms aside

Moving away from technical language and approaching conversation-like design might have interesting benefits, since we really know how to interact with other people.

What if we go a bit further with out metaphor - and introduce another imaginary person to our conversation?

We would be able to talk to them both at the same time and it might be that they, e.g. would argue that something is only within the area of responsiblity of the first interlocutor?

This metaphor isn't limited to local software constructs like classes, functions or types - could we go even further and model conversation between services?

Pretending that services are people doing various operations, how would their discussion look like?

Let's play with this metaphor more and use more concepts from "conversation" domain!

As we model our software constructs with people talking to each other, here are next questions we could think of:

  • What would mean that "person A sends an email to person B"?
  • What would mean that "person C calls person D directly"?
  • What would mean that "person D didn't pick up the phone?"

The metaphor

One might say that such approach is silly, overstretched and exaggerated - "who has time for that?"

It is probably like with other models - intially they seem dubious and unusable. As Mr. Box stated:

All models are wrong (imperfect - my understanding). But some of them are useful.

Metaphors (which are in fact mental models), we are using for various aspects of our lives, really matter. They bring different sets of concepts, primitives, terms and meanings. We are faced with manifold of abstractions that are related to metaphors we are choosing.

Once, I read that the metaphors separate winners from losers. I doubt that someone could be a winner when it comes to designing a system/a class/a function/a module/etc.

Nevertheless, having another mental model in your pocket, while you are designing the interaction with your software constructs, might bring new perspectives on how they look like and work.

I think it might get even more interesting when we would "summon" a group of such imaginary people and call them a "company" - how would they interact to achieve bigger goal like some of their domain capabilities?