Transcript from the "Managing State Complexity" Lesson
>> The most challenging thing about programming, and it took me a long time to realize this when it comes to programming. Our jobs are, I would say, our primary or least our predominant function as a programmer is to manage complexity within our code, and so, here's a quote from a paper called out of the tar pit, and you can Google it.
[00:00:29] It's completely free. And for me, this should be written in stone. When I read this I just realized like this has crystallized my worldview about programming. The biggest problem in the development and maintenance of large scale software systems is complexity large systems are hard to understand. And you could say okay, I get it complexity, but what is complexity and so when they clarified this it's all the same to me it clicked.
[00:01:07] And I said this is the foundational tension that is engineers that we are constantly trying to manage and so the major contributor t o complexity is handling of state. I could not agree more. That if you fail to handle state properly, it's going to mess up your ability to move or communicate across your application which is flow of control or flow control.
[00:01:40] And, if you fail to manage state properly, you're going to exponentially increase your code volume. And so, just what I would say would be, the Iron triangle of programming is handling of state, code volume and flow of control. And so as a programmer, everything that I do is to this end, how do I effectively manage state?
[00:02:10] How do I manage communication, which is flow of control and how do I do it In the least amount of code possible. And so Iron triangle and other state code volume flow control and the problem is that your current position In purgatory will depend on your ability to manage complexity.
[00:02:47] And so just stop for a second and think about a time that you've ever checked in code. And really we're not 100% sure that it wasn't going to break anything. So anybody on the Zoom or whatever, just show of hands, have you ever just did that YOLO commit because you were up against the gun or it was a timeline or you just like.
[00:03:20] I don't think anything could go wrong, but I'm gonna do it YOLO and so, if you've ever done that YOLO commit, you realize that you're slowly stepping in to purgatory. And then It just begins to get worse or if you've ever just airdropped into a brownfield project, you inherited it, somebody just gave it to you.
[00:03:44] And you're staring at this code and you're like, I have no idea what is happening here, I am in hell. I've done it, I think everybody probably would say, we've been there. And so, complexity has a direct relation to the level of purgatory that you will find yourself in.
[00:04:07] And so when we look at state management that We have some code here, and it seems to be okay. But there's a way in which you could write this, and we'll talk about this later. That if you change something outside of the method That you are calling. And so this is when we're gonna talk about micro complexity.
[00:04:36] That it could change the result that you get from calling a method. So when you call a method with the same parameters every single time, and you get a different result based on some external state How can you possibly test that?. More importantly is how can you possibly know what you're going to get at any given time?.
[00:05:05] And so, a real life example that I like to use around this is that the reason why, This could be problematic and we'll see exactly why in just a little bit is that the output of this method is dependent on some external state, which then creates unpredictable results.
[00:05:25] And so, shared mutable state is incredibly incredibly Dangerous in so much that a really simple example is that occasionally I like to buy stuff on Amazon and my wife also likes to buy stuff on Amazon and I can be on one computer and I just need to buy a book.
[00:05:45] So I add the book to the cart. I go to the cart, instead of the book being in the cart, it's the book plus like six other things. The reason being is that because my wife is on my account, and there's a shared state across that shopping cart, all of a sudden now there are What I'm seeing in my shopping cart is unpredictable.
[00:06:10] It's not what I expected because some third party, aka my wife, don't tell her I called her that, but has added that to the cart. And now I need to figure out what to do with it. What is the intention behind this thing in the cart, and I have to figure out what that's doing.
[00:06:27] Now imagine in your code. If all sudden something shows up, that you weren't expecting, and now you have to know like what was the reasoning behind this? And so the ability to parse that out becomes very, very difficult. Funny story, I found a bunch of toys in the cart.
[00:06:47] I thought my wife had put them there and it was for a very specific reason. And I just bought them all and come to find out it was my nine year old window shopping. And he basically [LAUGH] Ended up getting like six toys because I thought it was from my wife and it was from my nine year old and so this creates an predictability, control flow.
[00:07:12] How are we communicating state in events in the context of our application from the component level, how are components communicating with each other to a massive distributed level? Now imagine you're just zooming out. And now you have this large scale system. How do you communicate across not only an application but a bunch of connected applications in maintain consistency across those and so this is where control flow becomes very, very important.
[00:07:57] And we have code volume that in an attempt to manage state. Unfortunately, what you do if you don't do this properly, is you start to write a bunch of code Over and over and over that you don't need. So, for instance here within these blocks, what would happen if I needed to delete an element from the courses array somewhere else?
[00:08:31] Well, I wouldn't be able to do that. Or more, so I wouldn't be able to do that. But I would have to duplicate the code in the Delete block. And so when you fail to manage your state in your control flow properly, you'll find that you have to not only write additional code to manage your state, but your ability to reuse code Is greatly diminished, which leads to code duplication, or code volume.
[00:09:00] And one more note on shared mutable state, this is a slightly contrived example but I've done this, I'm guilty of it. That before I started using redux or ngrx that it was very common for me to have a component that shared a property or pulled data from a shared service.
[00:09:25] And now what you have is an items component and a widgets component that has the ability to modify the ledger total. So In here, you have this add method. And in each portion of this, you're able to do something. So, fairly simple I just opponent can add to the ledger widgets component can add to the ledger.
[00:09:54] Now the problem is. What happens when the items component says, look, we can never ever have the ledger go over ten, and then the widgets component is kind of the crazy kooky cousin of the bunch and it's work tournament ramp up to 11 We're going to set ledger all the way up to 11.
[00:10:20] And then it causes itemsComponent to break. Well, a simple example but this happens in a lot of different ways. So how would the widgetsComponent. Know that hey I'm not allowed to se this to 11, well also now it has to know about the requirements of the items component.
[00:10:48] And also because you have shared it will stay all of a sudden now all of the business requirements, the business logic in the context of every one of these components that shares the state is now coupled. And this is where it's scale. So imagine just two components if I change this over here, something bad could happen over here.
[00:11:19] That is two simple components. I look at this and I'm thinking this would be really easy for this to go really, really bad. Now imagine an application with like 50 or 60 of these components. Mentally, we simply do not have the mental faculties or the tools or the bandwidth being humans were designed to thin slice that think about this complexity its scale.
[00:11:46] And so this is where I want to set the stage. As we start to delve into how to write good enterprise grade applications, what are we doing? What are we trying to manage? And we're trying to manage complexity, which is State management, flow control and code volume. And so with that, before we get into writing some code, I want to stop and ask, are there any questions about what I've said up to this point?
>> What complexity do you see? Because, I mean, I have been using shared classes in Angular environments since long. And I mean I know I mean certainly at many times the Shared Services used to you It, I mean, it used to take a lot of time to manage the Shared Services at many places and and we used to get a lot of bugs in that.
[00:12:55] So what kind of actual complexity we are talking about here. So I have, highlighted the boxes like Ledger and then, in the items component and into the widgets component.
>> So the question is specifically, what complexity am I talking about? And the answer is that I'm talking about, I think, first of all, like mental complexity, your ability to mentally parse what's happening.
[00:13:26] And then, from there, the underlying pieces that make it hard to do so. At this point, I'm talking about complexity in a very kind of abstract sense. In the sense that, we know that, when we're programming, when you know what you're doing it's not necessarily hard, But it's complex and it can be complex.
[00:13:52] And so especially for new programmers, that the ability to make sense and navigate what's happening, it's cuz of complexity. And so, in my opinion, that complexity comes from again, our inability to manage state, flow control and manage code volume. And so this is what we're gonna talk about for really the entire day is how to do this at a micro level, a mezzo level and a macro level.