David Khourshid

Stop Drawing Pointless Arrows: Taming Complexity with Diagrams

Conference talk at YOW! Australia 2024. 45:37 long, 4.3K views on YouTube. Topics: visual modeling, actor model, statecharts, state machines.

Watch on YouTube (GOTO Conferences)

What is this talk about?

This presentation was recorded at YOW! Australia 2024. #GOTOcon #YOW (From the video description.)

“In learning about state machines and statecharts, I learned about terms like executable diagrams and visual formalisms.”

“You know if you try to explain microservices you might you know just go to a whiteboard and start drawing things like this and you'll quickly understand that everything is a graph at varying levels of complexity.”

From the opening of the talk.

Key takeaways

  1. You know if you try to explain microservices you might you know just go to a whiteboard and start drawing things like this and you'll quickly understand that everything is a graph at varying levels of complexity. 8:00
  2. You might think, hey, I can use sequence diagrams to represent just how this service communicates with that one, even if it's not strictly an actor model. 17:00
  3. You could see instead of having to draw multiple arrows from each of these states, we can just group them in one parent state and really simplify our state diagrams. 26:00
  4. You might be thinking like, I thought diagrams were supposed to reduce complexity. 33:00
  5. One of them is constructing the user interface with statecharts which really goes beyond statecharts and explains how these visual diagrams are useful in thinking about your software architecture. 44:00

Quoted from the transcript.

Full transcript

From YouTube auto-captions. Technical terms were normalized; some errors remain. 7,363 words.

0:00 Introduction

All right. How many of you if my slides ever show up? How many of you got lost this morning just trying to find this place? All right. I'm going to guess it's a lot of you because I can't see any of you. But would a diagram have helped? Like, hey, go here. Enter here. Probably, right? That's exactly what this talk is about. Stop drawing pointless arrows. We're going to be teaming complexity with diagrams and waking up my laptop so it actually shows the right screen. So my name is David Cororsche. I'm at @DavidKPiano pretty much everywhere. Piano is not my last name. My last name is Corsed and you know like was mentioned I am a piano performer. I studied piano in university. And let's see what else about myself. A couple weeks ago I actually just got married. So, and my wife is actually here in the audience, and we I mentioned this because we wanted to do something special for our wedding.

We wanted to have a first dance where instead of just having a DJ play the song, we wanted our friends to actually perform it live. And this was actually at first a little bit complicated to get all together. You could imagine if you know some of you are musicians just getting a group together and just having the same idea of what to play it could be difficult. Thankfully there's something called music notation that really helps just groups of musicians organize and just be on literally the same page. And I decided to whip up Musecore and actually notate all of the music for the group to play our first dance. And it sounded really nice. And this is the actual music over here. And yeah, this diagram really helped us. Just I'll get on the same page. And you might be thinking, wait, is this a diagram? And the answer is yes. And I'll explain that in a minute. So I went to university for piano and then I decided that you know I was playing around with HTML, CSS, a little bit of JavaScript, PHP, things like that and I got a job at the university and I learned that being behind a computer keyboard actually paid a little bit more than being behind a musical keyboard.

So I decided to go with that career path. But one of the things that always frustrated me and I'm sure many of you who are musicians here were also frustrated with is just this code you cannot read this the like even if I try to zoom in don't worry about it like it's just code is linear right you read it like you would read a book left to right top to bottom and file by file but the problem is that programs are not really actually structured this Hey, programs are really more structured in a series of connections where it's like we have these modules which are connected to this and this thing communicates with that.

Play from 0:00

3:00 In learning about state machines and statecharts…

So if you sort of envision it, you just have these lines pointing to just different things. But code is very much linear. And so that was one of the biggest things that bothered me where with music we have notation that can actually describe all different types of genres. and with code. It's like the there was no like visual formalism, at least not one that I discovered when I was a junior developer that really helped with that. And so that's how I got into diagrams. So, first of all, what exactly is a diagram? What constitutes a diagram? There's actually only two simple criteria. One is it's visual. So, it's a visual representation of something. And the second is it's helpful. Take this subway map or railway whatever you call it metro people have different names for these it's helpful and it's visual music notation also helpful in visual so this talk is going to be sort of two different things first of all why diagrams are useful and actually how to make your diagrams even more useful because we all have probably made diagrams before but we all have probably made the same mistakes making these diagrams so I was researching diagrams as a junior developer just really wanting that visual aspect.

I started with flowcharts which seemed pretty simple but were a bit limiting in describing just the complex nature of our applications. So then I eventually learned about state machines and then I discovered statecharts and all of these just sort of stemmed from flowcharts and I became obsessed with just these ways of representing our application logic at any level of complexity and I just really wanted to just to have any kind of developer work with their team on visually expressing their application logic because the truth is our software gets more and more complex like we're always going to be adding features, removing features, fixing bugs, making changes, all these things that just make our software super complex.

And in reality, we need visual languages to do three things. First of all, we need to understand what the heck our applications are actually doing. We need to be able to communicate all of these processes and flows with our entire team, even if they're non-technical, so that they're on the same page. And we also need to analyze like actually look at the diagram and spot deficiencies or places where we could optimize or even logical bugs and things like that. So diagrams are very useful for understanding software at scale. Now I got really interested in this interplay between diagrams and code and how they sort of related to each other. And so in learning about state machines and statecharts, I learned about terms like executable diagrams and visual formalisms. So just to give you an idea, a visual formalism according to Davidid Herell who created statecharts are a diagrammic and intuitive yet mathematically rigorous language.

Play from 3:00

6:00 The first one of course is entity relationship diagrams which as…

So it's a visual way of describing a program that can be converted directly to code. And that seemed really, really, really magical to me. Now, I'm not going to assume your ages in the audience, but I know some of you might be reading this and thinking, "OMG, is he going to be talking about UML?" And the answer is no. I sort of started development after the whole UML thing. I mean, UML is still popular in some areas of tech, but it wasn't really popular, you know, with the startups I worked with. No one ever said you must create a class diagram and you must generate this code and here's code that you don't touch. We we never used UML to its strictest form. And I think that UML has some good ideas, but really it's just way too rigid and prescriptive for what you're trying to do. So really we're going to be talking about UML the good parts like just not full UML because I think that diagrams can come in basically many different forms when it relates to your software and these forms are more useful depending on what exactly you're trying to do.

So for example there's diagrams which are purely visual. These might be something you write on a whiteboard. And then there's diagrams where you can actually have a text representation that generates the diagram. So you could think about mermaid plant UML things like that. And you could actually put this in source control and actually see the changes. So text to diagram very useful. And then there's code to diagram where you could take code and actually generate diagrams from it. This gets closer to UML but in some cases this is also very useful for visualizing your system. And then there's this magical birectional code to diagram which this might not be applicable for you know all use cases and it does take a lot of work to get right but in an ideal world if this works it is truly magical. And how exactly does this work? like how can we even possibly make code to diagram or text to diagram to code etc.

The truth is that everything at least in our applications is a graph. So you know if you try to explain microservices you might you know just go to a whiteboard and start drawing things like this and you'll quickly understand that everything is a graph at varying levels of complexity. By the way this is a hilarious video. So if you haven't seen it yet, please check it out on YouTube. So what's a graph? We have nodes and edges. So nodes are things. Edges connects the things. And this is actually extremely versatile. Our nodes represent entities which could be components, people, roles such as like organization charts, components in your system, states in the state machine, etc. And then we have edges which describe relationships between all these entities. So these could be state transitions or how data flows from one entity to another or things like constraints, distances if you're making a map or cause effect like this causes that.

The three levels of abstraction that I'm going to demonstrate with diagrams really cover pretty much the entire the entire way that applications are structured. So at the smallest level where you could even barely see it, we have data and then we have actors which really take that data and transform it based on messages it receives. And then we have systems which describe how these actors interact with each other. So this is my UML the good parts slide. These are the three diagrams which I think are the most important in my opinion to learn and to use with software regardless of if you're using them in a strict way or a less formal way. Just having these three represent all of these three areas of abstraction. So the first one of course is entity relationship diagrams which as the name mentions talks about the relationship between entities that you might have in your system.

So for example this might be a cafe system where you have customers and orders and things like that and they're all related to each other. So if we zoom in you could see that we are describing relationships between customer order employee menu items inventory all of that and also how they relates to each other. Now these can be loosely structured diagrams where you're just doing it on a whiteboard or they could be generated which I'm going to show you a few examples of in a minute. One of the confusing things I found about entity diagrams was these little things these crows feet over here. And also this slide really exemplifies just how simple you can make your entity relationship diagrams. So the two lines mean one and only one even though there's two. I don't really get the connection, but that's why I honestly just like plain text instead of these weird symbols. And then this means zero or more because a customer can make a customer can have zero or more orders and an order belongs to one and only one customer who made the order.

So these diagrams are extremely useful for talking about the relationship of data in your application. Now there's a lot of useful tools that I've used. One of them is SQL DBM which allows you to visually create these diagrams and actually transform that to SQL code. And I just I love the aesthetic and how visual it is. And I also love how you could just take this and show it to someone non-technical to describe how the data is related and all the different kinds of entities that are in your application. Then there's Superbase, which I don't I'm not sponsored by Superbase or anything. I just love using it. It's for Postgress databases. You could take your existing Postgress database and actually generate a visualization of your entire database. They also recently released database.build which takes it to the next level where you could actually create applications just by talking to AI and it will do two things. It will generate this entity relationship diagram and it will also create the SQL code for you.

So you could use it directly in your app, which makes sense. They want to make money. So it's like, hey, we built this for you.

Play from 6:00

13:00 The interaction between them are the messages passed from actor to…

Click here to deploy it to Superbase and pay us like $25 a month or something. All right, but all this talk and this is, you know, for example, a coffee ordering app. I was jetlagged for the last week and I really needed coffee. So, I if I were to just, you know, walk up to any of the great cafes around here and just stand around, the barista wouldn't really know what to do. They'd be like, you know, can I can I help you? What would you like? So, in our daily interactions, we're doing message passing, which sort of alludes to what I'm going to talk about next. But the barista might ask me what I would like. I would say, I would like a flat whites, please. They would give me a flat white after paying, of course, and say, here you go. and then I would say thank you.

And so this is message passing between two actors. And it actually sort of looks like a sequence diagram, which is the one of my you know next favorite kinds of diagrams to use in software development. So with sequence diagrams, we have an actor and we have a lifeline which is depicted by this solid white line or dotted. And so the interaction between them are the messages passed from actor to actor. And you can have more than one actor. So for example, if I ask for a coffee and I ask the cashier, the cashier will tell the barista like, "Hey, we have a new order. This person wants a flat white." And then the cashier will ask me for money. I couldn't find the emoji for Australian dollars, so we have a little bit of a mix there. And then I would give them money. and they would give me a receipt and after some time the barista would give the cashier coffee in this scenario and the cashier would deliver it to me and this represents a complete flow of the interaction between these three actors for the goal of me getting caffeinated and defeating jet lag which I've almost done.

I woke up at 4:00 a.m. this morning so I'm getting there. So this has really taught me a lot about the actor model. So this is how sequence diagrams relates to code where we can actually envision our systems no matter how complex they are as sort of an actor model you know way of you know just these things interacting with each other. So in the actor model we have actors and messages and all computation is performed inside of a single actor. So basically an actor all it does is receive data and then it does something with that data. It might have its own internal state and it might change its behavior depending on the message that it received. Now actors can only communicate through messages and I really like this part of the actor model because there's this isolation in state which makes it really easy to reason about just all the actors in your system.

There's no implicit states or global state or anything like that. Everything comes from the actor's internal state and the messages it receives. And so the only way to share data is to send immutable messages to each other, which is really nice. And in response to a message, an actor can do one of three things or even all three. it can change its state or behavior, which means when I receive a message, I might do things to the data in my internal state, but I might also change how I'm going to react to the next message. What it could also do is send messages to other actors, of course, because actors need to talk to other actors. Every system has more than one actor. Every you know, non-trivial system. And it can also spawn new actors. So you might be thinking like a service can spawn instances of other services which themselves can spawn other services too. There's many implementations of the actor model. But even if you're not using a language such as Erling or a library such as Orleans or XState to you know to represent your system strictly as actors.

You can really envision these parts talking to each other. So you might think, hey, I can use sequence diagrams to represent just how this service communicates with that one, even if it's not strictly an actor model. But I think that the actor model is a really useful way of thinking. Now for actually making sequence diagrams, I really love using swimlings.io because drawing sequence diagrams is a little bit tough. you have to draw the lifelines and the arrows between them. It's a very nice visual representation, but swim lanes allows you to create it just in text using a very intuitive DSL or syntax. And also I created a library called Stately AI/ inspect which allows you to do something different. It's not creating sequence diagrams. Instead, it's inspecting different components of your app wherever you hook it up and actually visualizing the message passing between each of the components in real time. Not sure if this video is playing.

Oh yeah, there we go. It's just taking a while. So, yeah, in this case, we're modeling a coffee dispenser or hot chocolate. Forget which one it is. And you can see that messages are actually being passed back and forth and visualized in real time which I think is pretty nice. There's also appmmat.io where this works for many languages not just JavaScript or TypeScript. I think it works for Java, Python, etc. where it actually inspects your network connections as your app is running and it visualizes them in real time.

Play from 13:00

19:00 I also wanted Wi-Fi on my cell phone, but of course…

So this is another very cool tool that I recommend you use just because visualizing these diagrams just brings a whole new level to how your application is working. So you don't have to write console logs and make the diagram in your mind. Instead you could see it visualized in real time. All right, story time. So there's there's lots of cruises in Australia and I live in Florida where you know we also have lots of cruises. And how many of you have actually been on a cruise, just on vacation? Okay, so a lot of you. It's sort of a thing in Florida. Everyone who lives in Florida basically goes on a cruise. So I'm thinking maybe it's the same in Australia. Someone told me that Australians love to travel. So totally makes sense whether you're flying somewhere, taking a cruise, but Wi-Fi is really, really expensive. So, I remember that I was working, but I also was going on a family cruise, and I'm like, I needed Wi-Fi. So, I it cost something like $80 a day or something ridiculous like that.

And the Wi-Fi system was itself pretty simple where I would make a request and first it would check, did this person already register for Wi-Fi? If they didn't register, then I was granted Wi-Fi access for the day. $80 later, I was able to access Wi-Fi. Now, I also wanted Wi-Fi on my cell phone, but of course, I registered with my computer. And so, with my cell phone, when I tried to make a request, it it sent a message from the clients to the service. Was it registered? And the answer was yes, it was. So, I didn't have Wi-Fi access. It said, "sorry, you're only allowed one device per day." So, speaking of right. So, what I actually did, and this was just you know, six or so years ago, but I knew of sequence diagrams back then, and I quickly sketched one out on the back of a paper, and I'm like, "Okay, you know what? How does this system work?" Okay, so we have something that's checking whether I'm registered or not, but I want Wi-Fi in both devices, and I don't want to pay for two devices.

So, what do you think I did real quick? I made another request while the other one was checking. So, basically, I did both my laptop and my cell phone at the same time. And because of the sequence of events, I was able to cause a race condition and get Wi-Fi access for both the devices. Saved myself $80 doing that. All right. So now my favorite what I think is and I'm biased, but what I think is one of the most useful parts of UML, which is state machines. Some people call them state diagrams.

Play from 19:00

22:00 If you were try to try to do this without parallel…

I know them as state machines. But machine is a very intimidating term even though conceptually they could be pretty simple. For example, we might model that a dog can be asleep and then on the event that it wakes up it's awake and then when it falls asleep it's asleep and you can't be in more than one state at a time unless you were jetlagged like me. But yeah, machine just sounds very complicated, but there's really only three core parts that you have to keep in mind, which are states, which again you can only be in one at a time. Events, which help you transition between the states. And so those are the transitions or the arrows between the states. So state machines have a few important parts. We have the finite states. Like I mentioned, you can only be in one at a time. So in this example state machine we are in the idle state and when the load event happens we're loading and then when we resolve we're in the success state but we could go back to loading by reloading and so this is an this is an important part because it shows that state machines and these flows are not necessarily linear and that's something that diagrams are really good at explaining is that things can loop back things might branch off things might have substeps so that's why I really like state diagrams for explaining processes.

Then of course we have the events and transitions which cause the transition between one state and another state. State machines also have final states which denotes the end of a process. But when I was making more and more complex applications this actually wasn't enough. So I discovered statecharts which were invented by Davidid Herell back in 1987 and eventually became part of UML and I sort of discarded the UML definition and went with the regular Davidid Herell paper from 1987 and this was actually in the paper. This is a citizen quartz multi- alarm watch. So one of those cool 1980s watches where you could set alarms, set the display mode and everything. And this is the schematic or the diagram for how it worked which I thought was really cool to see. Statecharts enable a lot of other things in state machines and they make them really expressive. So one of them is transition actions where you can actually say when this transition happens there is a side effect.

So now all of a sudden you have a declarative representation of the side effects that happen in your application because applications aren't just states. applications are also the side effects that happen. An application without side effects is not useful at all. There's also simplifications like state actions where we can say whenever we enter the state we're going to fetch data whenever we exit we're going to log telemetry. These can be equivalent to transition actions but it's just a much simpler way of representing them. Then there's also guarded transitions. So just like a flowchart we can say only transition here if this condition is true. So only load if we're actually online otherwise we go to the offline state wait for online and then you know we can continue again when we're online. Then there's compound states which simplify statecharts even further by being able to express subprocesses. So for example, when we're loading and the loaded event happens, now we're in the ready states, but we also transition to the initial state over here, which is playing.

So you can imagine this is a music player. And regardless of whether we're playing or paused, when you press next on the music player, it's going to first look at the child states and see is there a next transition? No, there's not. So let's look at the parent. Is there a next transition on ready? Yes, there is. So, we're going to transition to the loading state. So, you could see instead of having to draw multiple arrows from each of these states, we can just group them in one parent state and really simplify our state diagrams. There's also history states which are which are another interesting aspect of statecharts. For example, if we're loading a song and the song's loaded, then we will initially transition to the playing state. But let's say that we press next. and whether we're playing or paused, it's going to load the song, but we want to remember whether we were playing or paused. So, that's exactly what history states are for. They they let you transition to the most recent child state that we were in.

So, if we were paused and we load and we the loaded event happens, we're going to go back to paused just because that's where we were at. There's also parallel states and parallel states allow you to further simplify statecharts and state machines by saying these two things happen concurrently. So we have the player which is representing whether we're playing or paused and we have the volume control which represents whether we're muted or unmuted. So if you were try to try to do this without parallel states, you would have to represent these as a combination of states such as playing muted, playing unmuted, paused, muted, paused, unmuted. And you could see how it could get even more complex when you have even more different concurrent states that you need to represent. So that's why parallel states exist. One of the things that I really appreciate about state machines is how they map directly to requirements.

So for example, logged out, logged in, logged in. This is a very simple state diagram explaining an authentication process, but it maps to your you know, girkin, cucumber, whatever you want to call it. Given a user is logged in when the user logs in with valid credentials, then the user should be logged in.

Play from 22:00

28:00 State machines are in game development a lot and with with…

And so all of this can be mapped to a diagram. So really you could think of any application that you create as just a series of these given when vends that each describe part of a path of a bigger state machine. So you could write hundreds and hundreds of different Girkin statements or you could just draw a state diagram and derive those that behavioral logic right from the diagram. And of course you could just hide the level of abstraction. So you could only just depending on who your audience is for example for developers you might want to show more information for non-developers this might be sufficient state machines like I mentioned also allow you to declaratively represent effects such as if we're in the toggle state we want to play a video and if we're in the or sorry if the toggle action happens we play a video and if we toggle from the full screen we want pause the video.

So that can be declaratively represented here instead of what we normally think of as just random things that happen in our codebase that are very hard to track. So side effect management just becomes very declarative with state machines. And so one other great thing about state machines is that since they're executable, you can actually simulate them and see them in real time. If this video plays. There we go. So you can see that we can actually visualize what happens when certain events are triggered and you could see which state you're in what transitions to what and it gives a very visual way of showing the rest of your team basically how your application logic works and it makes it very simple for them without staring at code to give feedback on this should work this way or maybe we can change this or even just understanding all the features in your application.

So some other things I really like about state machines is it makes it simple to identify logical flaws in your application just by looking at the diagram. Now let's say that your code compiles there's no type errors, no linting errors, everything just compiles perfectly. That doesn't mean that your software is necessarily correct. Can you see anything wrong with this diagram? Well, we might be missing a few states. For example, if we have this payment form, we might be missing the option to go back or if we're on the payment state, we might want to give the ability to cancel. And this is something that both developers and non-developers can catch just by looking at the diagram. We can also like I said ex just explain different user stories just as parts of the diagram. But we can go further than that and actually just trace entire flows. So because our state diagrams or state machines are a graph, we can apply things such as shortest path to say what is the shortest path from the initial state to the final state in our application and just really represent this as the happy path that a user would take in the application.

Or we could add more context to it and say like oh what is the shortest path where we actually have to enter a shipping address and then it would find that shortest path that meets the criteria. So you can imagine that this is useful not only for determining happy paths and flows but also for testing. And so this is an area called modelbased testing which is really useful. State machines are in game development a lot and with with state machines you can also represent them in code too. And so that's why I created XState which is a JavaScript/TypeScript open-source library for creating these state machines in this JSON-like format that allows you to visualize them as a state machine. And we're not using switch statements because we actually want to take those JSON objects and analyze them so that we could visualize them too. So it starts with create machine and then you pass this JSON object which has an initial state and then a mapping of states such as wandering a maze or chasing Pac-Man and then different transitions.

So, for example, when we're in the wandering maze state on lose Pac-Man, then we go to chasing Pac-Man. And so, all of this represents the behavior of, for example, one of the ghosts in the game. And you can either run these in real time or they I actually introduce some new functions which allow you to just get whatever the next state and the side effects are going to be based on the events that you provided. So given we're in the initial state of wandering a maze when the lose event or lose Pac-Man event happens now we're in chase Pac-Man and so you can use that in your applications it's framework agnostic use it in the front end back end and it just allows you to have your application logic in one place where you could also visualize it at the same time.

Play from 28:00

33:00 You've probably seen these diagrams before where it's like, hey…

Now, some of you might have worked with state machines and statecharts before, and you might be thinking, you know what, I get the benefits, but I've created some pretty gnarly diagrams before. You know, and they were even confusing for developers. And you might be thinking like, I thought diagrams were supposed to reduce complexity. The truth is diagrams actually reveal complexity. And with this, it's actually sort of a feature, not a not a bug, where diagrams just show you all of the parts interacting with each other. But that doesn't mean that diagrams necessarily have to be complex. Take this famous one from Slack. I'm sure some of you have seen this before, right? Where this is the Slack flowchart for determining whether to show a notification or not. So first of all, Slack is very complicated. I'm still learning it and I've used it for many years. But imagine this in code. Imagine that you didn't have this. The code is much probably much more gnarly than this simple float or simple in comparison flowchart.

All right. So, how do we make good diagrams then that don't confuse people? Well, we start with intention. What is the reason why we're creating this diagram? Like I said before, diagrams are meant to be visual and helpful. So, we want to help people. And so, you have to think, am I doing this to explain how the intricate technical processes work in this application or just to give an overview of like mapping these user stories to these specific flows? And then that really depends on the audience. So your diagrams for developers might actually look very different than your diagrams for designers or project managers or other stakeholders where they might be more simple or show things at a different level of abstraction. And so that's why given the intention and audience, you also have to determine the scope of your diagram. What do you want to include? What do you want to admit?

And so in general, intention answers why are you making the diagram? Audience determines who you're making the diagram for and scope determines what is going to be included in this diagram. So when you're making a diagram, I want you to actually do just before you start putting pen to paper or start making the diagram, just fill out this mad Lib where you say this diagram is for which audience and it is to help whatever the purpose is and it will cover these things but it will not cover these specific things. This simple statements can accompany any diagram you create and it's going to make it very clear to whoever is reading your diagram what the diagram is about and if it will help them. So like I said earlier making diagrams is really easy. We probably all have done it before. But making good diagrams takes a lot of practice. And trust me, I've been making state machines for over 10 years now. and just drawing these diagrams, thousands and thousands of these diagrams.

And there's and I've also seen a lot of diagrams. I worked at Microsoft, so they were all over the place in more than one way. But yeah, making good diagrams takes practice. And I feel like there's a lot of obvious and non-obvious mistakes that we make in making diagrams. So the first one, unlabeled objects. You've probably seen diagrams with like these random symbols everywhere or these colored boxes or something and they're just pointing to each other. And this might make sense in whoever made the diagram. But really it's very confusing. It does not take much effort to just add some text describing what these objects are. And in a similar vein, pointless arrows. Now all arrows technically have a point but what I mean by pointless arrows and this trust me look at the diagrams after this talk that you yourself have created or received and you will see so many pointless arrows where it doesn't mean anything.

It's just pointing from one thing to another thing. The meaning might be implied. But really it doesn't take much effort to just add a label to your arrow to describe what exactly it's for. There can also be too much detail in the diagrams. And again, this can be solved by answering those three questions. What's the intention? Who's the audience? And what is the scope of the diagram? This is an example of even using our software at state.new where the statechart was just too big and it was showing just way too much. This is a generated diagram of Netflix's microservices and you can see it's way too much info. It's not really helpful at all. Sort of looks like corona virus. And then we have too little detail. And you've probably seen these diagrams before where it's like, hey, it's simple. This talks to this magic happens and voila. In fact, this is happening today with all of our LLM agentic applications where we think, okay, here's a prompt and we some magic happens and then the AI spits out a result even though in reality there are so many steps happening in between and it's worth knowing what those steps are.

So again, depending on the intention, audience, and the scope, you might want to show a little bit more detail depending on who you're working with. H I've also seen this recently mixing diagrams where for example we might be explaining a process where we're in a coffee shop the bur is idle we make an order the order is received and then through some magic this order goes to some database so that we have a list of these orders later and that might make sense but these two arrows mean two completely different things now one of them is a state transition and the other one is data flow so it might actually be better to explain these as two different types of diagrams where we go from idle to order received and we send the order to a database and then we could use a sequence diagram to show the interaction between the client and the database.

Another one is diagrams that are hard to follow. And this one really takes practice because this is a simple example but with larger diagrams it's becomes a lot more difficult to make it look nice. So here we have arrows crossing everywhere. We have states all over the place. We don't even know where to start. And honestly if you could just answer the question where does this diagram start? That is the first step to making your diagrams a lot easier to follow. So in this example, we could actually rearrange this like this. So there's two big things happening here. The first one is we're arranging our boxes, our things in reading order. And so the first one because we read from left to right, at least here in other cultures, it's right to left. Same rules apply. But we will start with the first state because it's at the upper left. And then we will go to second and then we follow clockwise.

So we could go to third and to fourth. Or you could just follow reading order in a zigzag way or if your screen space allows, all of it can be in one line. The second thing is that our arrows are no longer intersecting. Now, this might be impossible to do, but really your goal is to minimize the number of intersections of your arrows. So, you want to clean up the graph by having good alignment, reading order with your boxes, and also minimizing the intersection between the arrows. There's also symbol and color overuse. And so with this, all right, here's an example diagram that I saw just found randomly online. Now, this makes sense. At least the labels are arrowed. Sorry, the arrows are labeled. I'm getting confused myself, but you could look at each of the boxes. There's so many colors and each of the boxes have lots of symbols on them where it's just very hard to determine what do those symbols even mean and are they even useful in the graph.

Here's one from Microsoft and this is actually recently made just explaining the Azure OpenAI service boundary. So, how Azure and OpenAI work together. And there's a lot of crazy things happening in here. Some of the labels are arrowed, some of the arrows are labeled. Some of them are not. We have some things in boxes, some things not in boxes. We have one box with an orange border, a dashed orange border, which we don't know why that's special. What does that mean? And then we have this cluster f over here like with I like that could be simplified. It just makes things more complicated when they're crossing. So there's I don't have much time left but I do want to explain that there's a lot of tools that you can use. Some of them are the usual suspects like draw.io. You probably use things like Lucid chart and Miro and things like that.

I really like using TL draw just because it's a very versatile and simple whiteboard.

Play from 33:00

43:00 Really just making diagrams physically really helps a lot

There's textbased tools such as PlantUML and Mermaid chart. And then there's tools that do both like Stately. And I also really love Whimsical too because it allows you to express many different types of diagrams. But I am going to reveal to you my favorite tool, the tool that I think is the best diagramming tool. And the answer is pen and paper. And the reason there's a famous study from 2014 by Mueller and Oenheimer, not the atomic bomb Oenheimer, he's dead but a more recent Oppenheimer. And in this study, it was actually shown that writing your notes really activates three parts of the brain. the motor cortex, the somato sensory cortex which is that tactile feedback part and the visual cortex which is the visual representation you see once you make those movements that because you're activating more of the brain in doing that physical activity you actually retain more information and get more understanding of what you're doing. So really just making diagrams physically really helps a lot.

And so Figma is a great tool for collaboration too. So again two things that could really help improve the way you make diagrams making it physically and also collaborating with your team. So again I really like using Fig Jam for this. But in general tools should never constrain the thinking process. So you shouldn't be limited to what your tool can do. And there's two really good books that have influenced how I think about diagrams. One of them is constructing the user interface with statecharts which really goes beyond statecharts and explains how these visual diagrams are useful in thinking about your software architecture. And the second one is stock diagrams help which I actually brought in this trip. Very visual book very easy read in something that I recommend to all teams. It doesn't cost too much unlike this book. It cost 725. Don't buy it. It's only like this because it's out of print.

Maybe you could find it elsewhere online, but you know, it's a really good book. But yeah, in general, a picture is worth a thousand words, and a diagram, at least to me, is worth a thousand lines of code. And if I want you to take anything away from this talk, label your errors. Thank you very much. [Applause]

Play from 43:00

Related talks