Let's see, another question is, does immobility lead to fragility? Well, immobility is a symptom of interconnectedness, and fragility is also a symptom of interconnectedness. So, yes, probably, although I think it's indirect. I mean, without carefully thinking on design, developers may try to reuse a lot of components and failing in the coupling trap, falling into the coupling trap without mentioning that it can probably not respect SRP. Yes, yes, yes. We will get into the single responsibility principle in just a moment. And the last question here is, can we think about dependency inversion from the start? And if we do, does that lead to big design up front? Dependency inversion is something that you apply in the midst of the act of design and coding. Big design up front is when you spend a lot of time planning the code without implementing any code. And that's almost always a problem. It's very risky to do lots of code planning without actually coding, because there's nothing that proves that the design is correct. There's nothing that proves that the planning is correct. And what happens to most developers is that they go off and do lots of code planning without actually coding. They do a lot of design. And then when they start to write the code, they realize that the design doesn't look anything like that at all, because the code will lead them in another direction. So we don't want to do too much design up front. So we don't want to do too much design up front. a bunch of designs on the whiteboard for an hour or two. And we'll come up with some ideas that maybe are OK. We don't know for sure, but maybe they are. And then we will code them for a few days and see if they work out. And if they do, great. And if they don't, we'll go back to the whiteboard and fiddle around a little bit more and maybe we'll come up with better ideas. The act of coding and the act of design are part of this continuum. You have to do them simultaneously. The design part comes a little bit up front, but there's an awful lot of design thought while you are writing the code. And with that, let us move on to the single responsibility principle. The first of the solid principles. The single responsibility principle says this. And by the way, the single responsibility principle may be the worst named of the principles. And it's the worst named because the name implies something that isn't what the principle is trying to say. So many, many people will read the title of the principle without reading the definition of the principle, and they will take the wrong definition away. The single responsibility principle says that a class or a module, any kind of software entity, class, module, doesn't matter, should have one and only one reason to change. Now notice, that does not say that the module should have a single responsibility. No, one and only one reason to change. Why did we use the word responsibility? Well, I'll explain that in just a moment. But before I explain that, what causes software to change? And the answer to that is users. Users cause the software to change. They make requests. They ask for changes. So if the single responsibility principle says that a class should have one and only one reason to change, that means that there should be one and only one person requesting that change. Now, it's not fair to say that it's one and only one person, because really there's a group of people who need the system to behave in a certain way, and the group of people ask for the change. So I like to use the word actor instead of person. An actor could be one person, could be many people, but it is people who are requesting changes. So to restate the principle, the single responsibility principle says that every class and every module should be responsible to one and only one actor, where that actor could be a group of people who request certain kinds of changes. Now, to make this clear, let's look at an example. Here I have an employee class, a module that deals with employees. And apparently this is part of some kind of payroll program because it's got a calculate pay function in it. The employee class has a calculate pay function in it. It also has two other functions. It's got the save function, which probably saves the employee data on a database or something. And it also has this print report function, which from our point of view, returns a string about the employee and that string will be integrated into a larger report about many employees. So the report generator will go through all of the employees and it will call print report and print report will return a string that the report generator will integrate into the actual report. Employee class has these lovely three methods. And if you were to open up any book on object-oriented design, it would give you something that looks like this. And it would bless this and say, yes, this is good because the employee class has these three methods, but it violates the single responsibility principle. And let me explain how. Who is likely to ask for changes to the calculate pay function? Well, the answer to that is that the accountants are likely to ask for those changes. Nobody else. It's the it's the people in the finance group, the answer to that is that the accountants are likely to ask for those changes. Nobody else. It's the people in the finance group, the accountants who do all the calculations and who figure out how people ought to be paid. So if the rules for calculating pay change, it will be the accountants who start that process. And all of the accountants report up to the CFO, the chief financial officer. So in some sense, the calculate pay function is responsible to the chief financial officer. Look at the print report function. Who reads those reports? Well, the auditors read those reports. Who do the auditors work for? Well, they work for human resources. And the human resources is a function of the operations department, which reports to the chief operating officer, the COO, officer, the COO, the chief operations officer. And therefore, in some sense, that print report function is responsible to the chief operations officer. And now look at that save method. Who's going to ask for changes to the save method? Well, the DBAs are. The database administrators are. They're the ones who are going to ask for schema changes and table changes. They're the ones who will be affecting the way the employee is saved on the database. And of course, all of those database administrators report to the chief technical officer, theto and therefore in some sense the save function is responsible to the chief technology officer now let us say that you are a programmer who worked on the calculate pay function. And as you wrote the calculate pay function, you did what all programmers do. You you wrote little tiny functions, and more and more little tiny functions that all collaborated in to making calculate pay. And you got it all working, maybe you even wrote tests and you walked away. And let's say there's someone else who wrote the print report function and they did the same thing kind of thing they wrote the print report function and that consisted of many little functions that collaborated to make print report work but as they were writing the print report function they noticed that there was a function already existing down deep in the function hierarchy that did exactly what they needed. It was there because of calculate pay, but why not use it in print report? So they call it, of course. And now, course. And now, months later, somebody in the operations group, one of the auditors, comes to you and says, hey, we need our report changed a little bit. We need you to move some columns around. And this one column has too many decimal places. Can you please trim the decimal places and round it and you do so you go into the code and you trace the code down and oh look here's this little function and we can round it and trim it right there not realizing that that function is also being called by calculate pay and And so you make the change. You test the report. The report works exactly the way the auditors want, but you did not realize that you have broken calculate pay. So the next time the paychecks are run, guess who's knocking on your door? The CFO. He's a little upset with you because you have now printed paychecks that are wrong. That is why we follow the single responsibility principle. We do not want that kind of fragility. That is the source of fragility, right? You make a change in one part of the system and it breaks an unrelated part. We do not want functions that have different responsibilities to exist in the same modules. Now, what can we do about that? Well, there's a whole bunch of things you can do about that. You can create a, let me show you a different picture, probably be better. You can create a facade. A facade is where the employee class has all of the functions in it still, but it doesn't implement any of them. Instead, it delegates them out to little service classes. So you would have a service class for calculating pay and another service class for saving to the database and another service class for printing the report and so on. You could fan it out that way. Or you could do it a different way. You could do it this way. You could have the employee class that still has the calculate pay function in it but you could take the save function and put it in a completely different class that uses the employee class and you could take the print report function and put that in a completely different class that uses the employee class and any of those techniques will separate the functions so that you don't have functions in a class that are responsible to more than one actor. That is the single responsibility principle.