Core Software Design Principles
Subramaniam, Venkat
Creating code is easy, creating good code takes a lot of time, effort, discipline, and commitment. The code we create are truly the manifestations of our designs. Creating a lightweight design can help make the code more extensible and reusable. In this presentation we will take an example oriented approach to look at some core design principles that can help us create better design and more maintainable code.
 All right. Let's get started. Welcome to the session on course of the design principles. My name is Venkat Subramanya. We're going to talk about a few design principles here and how it has an impact on it. I want to talk a little bit about where that has helped me in the past. So I'll talk about some of those as well. And I'll try to keep this as possible without getting too much into code. I'll probably give you kind of one example just to illustrate a few points, maybe a few others as we go through. Best time to ask a question or make a comment is when you have it. So please don't wait till the end. Anytime is a great time. If you do want to participate, ask a question. Just say a question so you draw my attention and I'll be more than happy to listen to you. So let's get started. We're going to talk about some core design principles. And I have to say that these principles have helped me enormously over the past several years. In fact, I have to say that these principles that helped me a lot more than design patterns themselves. One of the gripes I have about design patterns is when people look at a pattern, if they only look at a pattern to use it, then it may not be the right pattern after all to use. But if they think about what's the force behind using a pattern, if they look beyond that and look at design principles, it often leads to a better reason to use a certain pattern or even a practice. So I value the design principles enormously compared to anything else. Where do we really see them? I feel that the design principles are very effective when we use them in a tactical design mode. I often use this in test-driven development. There are two things I do. One is when we are doing test-driven development, we can say, well, we want to design this, what principle may we apply here? Certain times we look at principles to apply, certain times we look at principles not to violate. The other benefit I've had with this is, in teams where I work closely with them, we often use these principles as a vocabulary. For example, we would be looking at a piece of code on our design and somebody would say, yeah, but we cannot do that because if you do, we will be violating the OCP or violating the dry principle. So we use these kinds of terms to communicate between each other. So this is a nice vocabulary to build for communicating a certain intent as well. But why should we really use them? The reason I would use them is the principles are a set of practices or things that help us to create better quality software. And I found them to be fairly effective if applied in the right way to the right degree. But of course, like anything else, we could also overuse something. And when we try to use a principle when it doesn't make any sense, it could lead to unnecessary complexity. So we have to be very careful about them. And like I said, I've really seen this to be very effective in test-driven development, tactical design and things like that. In evolutionary design as well, I've seen this to be very effective. So I'm going to talk about some principles that I consider as a very set of core principles. You probably have heard the term solid principle. Well, solid principles are part of this, but I don't really like the word solid as much because I don't want to say those are the principles I want to focus on. There are a few principles that are outside of solid that seem to help as well. So put them in a sequence where I find the most merit or value in them. So let's get started with one principle here to begin with, which is called the dry principle. So the dry principle stands for don't repeat yourself. So the idea behind the dry principle, this was originally written in the book called The Pragmatic Programmers. And this is a publishing company now, but they originally started by writing this fantastic book called The Pragmatic Programmers. And Dave Thomas and Andy Hunt wrote this book. And in that book, they talk about the dry principle. And so what is the dry principle really state? And dry principle says every knowledge in a system must have a single authoritative representation. So the idea really is representation. So the idea really is that every knowledge in the system must have a single authoritative, in fact, they even add and one more word here unambiguous. So the idea really is we want to create, when we create an application, we have to ask where is this piece of knowledge really kept? And duplicating this knowledge in multiple places is really a disservice we do for ourselves. Let's think of a few examples of this. A years ago, I was building an application and we had a problem with the system. We couldn't implement a certain logic in a certain place in the system. So what we did was, what I did was that I decided to, I was overly eager to solve this. So in several parts of the UI, I had implemented a logic to perform a certain checking. A few weeks went by and the problem was solved in a different area. And now I had to remove the code I put in for this particular logic. Well, unfortunately, there were several places where I have to remove it, more work to remove, and you forget in some places, and then it takes time to go back and fix it. So I learned my lesson the hard way doing this. So when it comes to dry principle, we want to ensure that we have the knowledge in one single place. Let's think about this with a little example here. I'm going to just throw one example at you. And we could use different languages and tools for this, but my idea is to illustrate the benefit of this concept. I'm looking at a little framework here called Grails, which is written on Groovy and Java and Spring and all those good stuff, but you can do this in multiple different tools and framework. The idea is to get a sense of what this is. The point is we need to be able to do this in our own application if they can do it here. So I've got a team with a name and a contact email, as you can see here. So I want to quickly try out an example. So I'm going to say here in this case, I'm going to create a new team. So this is a new, as you can see, and I'm going to say team one is the name of the team. And I'm going to say team one at example.com is the email address. So notice this is a create, and I'm going to go ahead and create it. So likewise, I'm going to create another team. I could say team two at example.com here. And once I create team two, I could say team two here, and you can see that the teams are being created. And I can look at a list of teams. We could also do an edit of a team. So for example, I could click on edit, and I can change the information of the edit page, like in the create page. So it looks like there are two different pages, one for create, one for edit. Well, that's great so far. I'm going to kill this application. And the data is in memory. So when I restart it, it will go away. But that's really the intention of what I wanted to show you here. So what I want to do is I want to enforce a rule. And the rule I want to enforce is that no two teams can have exactly the same name. Well, how do I enforce that rule? I got to enforce this rule in the create page. Because when you're creating a team, you want to make sure that team name for the new team is not the same as any other team out there. You also have to make sure this doesn't happen in the edit page. Because if you're changing the name of an existing team, you don't want to give a name of another team that already exists. So if I naively do this, this would end up duplicating the effort in two different places. Drive principle is not about duplication of code. It is actually about duplication of effort. The reason I say this will become clear in the next example as we will see it in a minute. So what I want to do here is I'm in the model here. And I'm going to say name and I'm going to say unique is true. That's all I've said here that the name is unique. So having done this, I go back to the application. I restart it. Like I said, I'm having in-memory data. It's going to blow it away. So I'm going to go ahead and create a new team right now. And in this case, I'm going to go ahead and ask him to, I'm waiting for the server to start up still. So I'm going to ask him to create a new team for us to use in this case. So when I do, I'm going to go to the create page for us to take a look at what this shows. So I go to the create page. And on the create page, I'm going to say team one over here. And I'm going to say that the contact is team one also. So click on create right now. So that worked. Now we're going to new team again. This time I created team one one more time. And I'm going to say team one also click on create. And it tells me I cannot do this. So it tells me that the property has to be unique and you cannot do this. So I'm going to change it to team two right now. And I'm going to change this one to team two, click on create, it finished it. Now I go to that list of teams, I go back to team two. Notice this is the edit page, not the create page. But in the edit page, I change it back to team one, and I click on update, it catches me and says you cannot do this. The point really is, it is a simple activity, but that single authoritative knowledge was captured here in this domain object. And I don't have to go about modifying this in multiple places in one place I can express it. Well, we could argue, are we really looking at duplication of code right now? Well, not really, it is duplication of effort as well. Like what? Let's go to the contact email for a minute. If I go back to the application, I can remove everything from here in the email, and I can click on update. And in this case, of course, it was able to take the change to the email, which is really wrong. So let's give it a try one more time and see how this is going to shape up. Now notice what I'm going to do. I'm going back to exactly the same place. I'm going to say contact email. And I say that this email format is true. I want to emphasize that the email actually is in the right format. So all we did in this case is we added this one line. But let's think about it. Would you want verification on the front end? Or do you want validation on the back end? Which one would you like? Both I heard greedy people, right? Absolutely both. Why do we want it both? Because a front end validation is quicker. There are other benefits for front end validation. We want it on the front end. But you cannot live with the front end alone because the back end has to validate it too. Why? Because you could be sending data through other means than going through the browser. You want to make sure the validation happens on the server side. You say, wait a second. Usually the technology for client side is different from technology in the server side. So I got to write the code maybe in C sharp or Java or Groovy or whatever. I got to write that code on the server side. And of course I may have to write JavaScript on the client side. So that is really two different sets of code, isn't it? Well, not really. That is where the violation of the drive principle comes in. It is a different code because it's different language. But it is for the same reason. So it is a duplication of effort. Same way, you don't want to duplicate that effort for other means as well. How can we do that? So when I go back to the application now, I'm going to, I blew away the data again. But this time I go back to creating a new team now. And when I create the new team, notice what happens now. I say team one over here. And I'm going to say team one without anything. And right off the bat, you can see the error pop up. It tells me I cannot create the team right now. If you insist, it tells you please include, it's even polite as you can see, please include an ad symbol. And when you want to create this, and it gives that error as you can see right there. Now, clearly we see this is a client side validation in place. And there is also a service head validation also written for this. In other words, once again, looking at this single authoritative representation, the tool was able to create client side and server side details to take care of this. So that is an example of the drive principle. So what is the benefit of following the drive principle? It becomes easier to maintain the code. It reduces the cost of development. It makes it easier to modify and evolve the code. So I honor the drive principle a lot. Now, when you think of a drive principle, it reminds me of an experience. I was at a client side and one of the programmers said, oh, we tend to fix the same bugs every two months. I said, that's nasty. Does somebody actually put back the bugs back in the code? He said, no, the code is duplicated in so many places. We keep figuring out, discovering these places and we fix the bugs. I said, well, when you fix a bug, you do take a little bit of time to refactor the code, right? He thought for a minute and said, that would be a good idea, right? So I mean, what good is it if we don't fix that and refactor the code? That's going to spill through everywhere. So it is our responsibility to actively refactor the code and enforce the drive principle. So if there's one thing we can look at avoiding, it is about avoiding the duplication, not just duplication of code, but a duplication of effort as well. So when you look at code, ask yourselves, does this really honor the drive principle? Does this really take care of not violating this principle? That is something to think about. The second principle I quite heavily use is the Yagney principle. Sometimes people get very angry when I use the Yagney because they say, of course you need it. So I change it a little bit. It stands for you aren't going to need it. So it is a principle that says we really don't need it. But I change it a little bit just to kind of make a little bit of ease. I say you aren't going to need it yet. And that seems to ring a better bell to people than you aren't going to need it. They get very apprehensive. Well, oftentimes what I find people do is when they are designing a piece of code, they put in a lot of different features. They put error checking. They put extensibility in place. They look at data types and how extensible can it be? Oh, this has got to be a generic type. Whatever it is they think of, they put all of those in place. But my question often is, do you really need it? If we don't really need it, we need to postpone it until we know a little bit better. But oftentimes we hear people say, I'm not exactly sure what the functionality is, but I can still write the code. So it takes a bit of a discipline to say, we don't know what exactly this is, or we don't know if something is really needed. So we are going to postpone adding this to a later time. And the Yagney principle is a good principle to follow for that reason. Now, you aren't going to need it yet is a much better in my opinion because it says that it's not that you will never need it, but the fact that you may not need it right now helps you to postpone the decision until you know better about this. And then you can decide to use it or not. So it's not that you are condemned from using that, but let's postpone until we know better. And if we later on we find out we actually need it, we can absolutely implement it. Otherwise, we don't have to use it. One of the real problems here is this. Let's say for a minute, we've been implementing code, and let's say you implemented a piece of code. And two days later, I come over and say, we don't need that code, you're going to be pretty angry because you took the time to write it, and you're going to say, you better use it because I wrote it, right? But the code we did not write is the easiest code to throw away because, hey, I didn't really write it. Thanks for saying it. I can go do something else more meaningful right now. So that's a principle I really like using. So we don't really have to force ourselves to use this code. We can postpone it. The next principle I want to talk about is probably one of the most important principles, but it comes in different names. It's a single responsibility principle. A single responsibility principle says that every piece of code needs to have a single one purpose, one reason. This is also often called as cohesion. So cohesion is a property where things belonging together are together and things that are not belonging together are separate. Now let's think about cohesion. What does it really mean? Well, in real life, we can think about cohesion in several ways. I'll give you one example. When I was a child, I was the brat that really liked to come home from school, throw things and then run out to the street and play. That was a lot of fun. And I had a wonderful parents who tried to teach me values and they said, hey Venkat, when you come back home, you don't throw stuff and run away. You got to put things in place. Well, I used to have this cupboard and I would throw things into the cupboard and run away. It was fun when I had to do it, but any time I needed something from it was terrible because I would open it. If I pull a blue sock, the next sock I find will not be blue in color because it's obviously hidden somewhere else in it. So it was more effort to take things out. It was much easier to throw things in. It was a mess and my parents tried really hard. They kept telling me, don't do this. You got to keep things separate. You got to put your colored sock, all the light colors in one place, light colors, another one in this place and they tried to teach me all of this and that never worked. And you may look at me and say, well, it looks like you already turned out to be better. How did that happen? Well, I got married. A lot of things changed when that happens. So what my parents couldn't do my lovelies can do. So that's beauty of that is things are more organized and now my books are in the study. My clothes are in a different room and there is harmony and everything. You know where exactly things are. In fact, it's such wonderful that a couple of months ago, I was somewhere else in the world and I really wanted a reference from a book which is a very old book. I couldn't find the reference online and so much so that I could actually call my wife and say, would you do me a favor, go down to the bookshelf, the third book from the top row. I wanted to pull that out and look at this particular index and read it for me. So that kind of discipline eventually evolves and that is an example of cohesion. Like things are together and dislike things are apart and that really helps to find things easy and maintain them. We can do this a lot in the code. For example, classes. Don't put multiple classes in one file, for example. That's a rule we can follow. And when you write classes, you want the classes to be narrow and focused. One thing done one. What if your class is doing input-output-related operations plus database operations and dealing with some calculation, what's going to happen? If that is one class you have, let's say this is your class you have written and if this class does every single operation, well, the problem is that class is going to be very, very unstable. In other words, every single thing that changes in the system potentially could affect this one class you wrote because it does everything. On the other hand, you split this into smaller classes. You have one class that deals with input-output, another class that deals with calculation, a third class that deals with database, a fourth class that may deal with maybe a particular calculation. Now the chances are you may decide to change the calculation, you change one class, or even better, you can provide an alternate implementation of the calculation class and the other classes can vary with the factory or something to use one or the other. So the reason for a class to change becomes a lot less when every class focuses on a single principle and does one thing and one thing well. So we can look at single responsibly principle at the class level. But we can also look at single responsibly principle at the method level also. Let's think about this for a minute. A long method. So let's think about long methods. Who here thinks long methods are a good idea? Not a single person, right? Now why do we think long methods are not a good idea? Let's think about some of the reasons why long methods are a bad idea. So can you throw some reasons at me? Why long methods are bad? It's really hard to read, right? Hard to read, thank you. What else? Hard to test. What a wonderful way to think about it, right? How do you test this method? So readability. You look at this method, I remember one experience, a client called me up and said, hey, do a code review for us and help us with some problems we are having. So I started doing code review. And I started with this method. I read about 25 lines of method code. And after 25 lines, my thought was how much more do I have to read? So I started scrolling down. Then I started paging down. And then eventually I said that doesn't work. And I used the tool to find out the curly braces and find the difference in the number of lines of code, right? And that said there are 750 lines of code in that one function. Immediately I'm like where's the nearest coffee machine? I need some caffeine, right? It is frustrating when you see that code. Why? Because you are like, whoa, that's a lot of lines of code to read, to comprehend this one idea, how worse it can turn very quickly. And also imagine how do you test that method? How do you go through combination of the methods and the branches in the code? The permutation and combination through it is going to be so many that you cannot possibly write enough tests on that method to satisfy all the branches or it becomes extremely complex to be able to do it. So that is another problem with it. What else do we have? What was that? Oh yeah, wonderful. Hard to reuse. How do you reuse a monster? What you need is those 10 lines right in the middle. Well, but you cannot reuse the 10 lines because it's within the method. So what do you do? You take the 10 lines away from it and what do you do with it? You stick it into another long method, right? So as a result, it leads to duplication of code as well. So it's combination of both. It's hard to reuse and in turn it leads to duplication as well. Anything else we can think of? A little louder, please? Oh, hard to debug. So hard to debug. Well, that's actually not a problem, right? That's why you hire the interns, right? So you say go get it and the interns of course log through and they say this is what you guys do for a living. That makes it really hard. So hard to debug. What else? Is that it? Hard to maintain. Hard to modify. What else do we have? Anything more? Hard to what? Hard to remove. Yeah, hard to remove. Fails single response to be principle has what do you call it? Tight coupling often, right? More coupling in code. If a code is that big, chances are, miscellaneous company, right, is going to ask for other dependencies. So that's going to be really coupled and that makes it hard to remove as well and other problems that will come with it. So there are so many problems with long methods. But let me ask you this question. We already asked you this question, right? Who here thinks long methods are good and nobody raised the hand? My question is different. Who here has seen long methods? Look at that, right? Almost everybody in the room is raising the hand. This is called cognitive dissonance. We all know it is bad, but yet we see it. Does anybody know? You all know it is bad, but then why do we have long methods? Well, the sad story is this. Nobody in this room wants to write long methods because you all know it's bad. But the folks who believe it's good are at work right now, making those methods longer as we speak, right? That is the problem we have to deal with. So what do we do about long methods? So if there's one thing, just one thing we can teach people, if one thing we can do, and that is to tell people, please don't write long methods, there'll be so much improvement in our design. If we can do just one thing, don't write long methods. And why do we write long methods? I really don't know the answer for that. Why do we write it? That's like a very bad practice. Now, if we don't write long methods, what happens? The code becomes cohesive, a single responsibility. It becomes easier to understand, easier to maintain, and there are so many benefits in doing it. But the question is this, how long is long? So let's try to put a number on this. How long is long? Somebody said 25 lines of code. And immediately Ruby programmers said, what 25? We never write 25 lines of code. Seven lines it is. Well, the closure guide said seven lines, we don't write anything for seven lines, only three lines. There is no way to win this battle of number of lines of code. Well, here's another measure we could use. How long is long? I would say if you can see the entire, entire method in one window, right? But don't try to lower that font size. So you want to see the entire method in your window, okay, that may be a good measure. But there is a better way to think about it than either one of those. So what is a short method? A short method is not a method with fewer lines of code. That is a wrong way to look at it. Let's think about this a little differently. Remember that gentlemen or the programmer or person that we talked about at your work, and what does this person do? The person writes long methods every day. And you believe wrong methods are bad. You told this person several times the person doesn't want to listen to you. So I got a last-ditch effort to convince this person. So go to, go back to work on Monday. Don't say a word. Just sit down and start coding. This, this colleague of yours who writes long methods comes over to you and says, hey, how was your weekend? You could say your weekend was great by saying when, you know, something like went to the park on Saturday, you can say, and then you can say went to the movies on Sunday, right? So you could, you could say something like this, but don't do that. Instead, you say, oh, my weekend. Well, I'll tell you at 10 o'clock, I got into the car, turned it on, you know, back the car up stood at the stoplight for about seven seconds, turned right, went for another two kilometers. And then I turned left. Oh, there was a bird on the street as I was going through. And then I went two more, you know, feet, and then I had to turn right for more kilometers. Just keep going like this. After about 10 minutes or so, your colleague is in a panic mode and says, stop. Have you gone mad? You say, no, I'm not gone mad. I thought I will tell you how my weekend was like the way you write code, right? So the point is, we don't talk to people like that. How do we talk to people? We talk to people in these high level of concepts. I went to the park on Saturday and went to the movies on Sunday. Now your colleague may be interested in movies and may say, really, what movie did you go to? Notice your colleague did not ask you about the park. Or another colleague who we're talking to may be interested in a park and say, tell me what park did you go to? And maybe you say what park you went to and the colleague now says, really, is that park over here? Is it family friendly? I want to know more about it. So notice what's happening in the communication. We mention things in one level of abstraction at a time. So that is something very important to think about when writing methods. This principle is called the slap principle. Where the slap principle, no, don't do this, you call a colleague. The slap principle stands for single level of abstraction principle. So in other words, what should we do when we write methods? The method is short if the method is focusing on a single level of abstraction. So in other words, when you look at a method, a method should nicely compose itself and tell us what the method is really doing. So another name for this pattern is called the compose. So it's called a compose method pattern. And the idea really is the method nicely composes things at a single level of abstraction. And that is called a compose method pattern. So the idea of a compose method pattern is to compose things at a single level of abstraction. And then if you want more detail about that particular level of abstraction, you dive into that method and look at the details. So then what happens is the code becomes very easy to read and understand what's going on. Now also this becomes easy for maintenance and debugging later on as well. When you are trying to get into a code, if you have 750 lines of code in front of you versus if you have about four lines of code where those lines of code are in these levels different of abstraction, there are some clear benefits here. The first benefit is if you had 750 lines of code, chances are that it's all jumbled up and the logic goes back and forth. You do a little bit of this, a little bit of something else, a little bit of something else, it becomes hard to understand and maintain. But if you have those four lines of code at one level of abstraction, everything to do with one abstraction will be inside that method. Everything related to the second abstraction will be inside that method. So that's more cohesive and focused on single responsibility as well. And then when it comes to debugging the code or understanding it or maintaining it, we take these high level concepts in our mind and say, oh, you are doing XYZ access over here, got it. If I really want to dig in and look at more details about it, I can step into it, but I don't need to know that detail right now. I can skim over to the next one. So as human beings, we retain these chunks of concepts in our mind and not these little turns and twists that we make all the time. So that's a better way to write code. So if there's one thing we can try to do in our field, that should be really removing long methods and writing things that are focused on a single level of abstraction as much as we can. So that is something to think about how we can achieve this. The next principle I want to talk about here is a principle that is really hot for me because I don't tend to think about it that much, but I think it's a very important principle. And the times I've applied this, it's come as a surprise to me that I didn't quite pay attention to it. So this is called the tell don't ask principle. The tell don't ask principle says that you want to tell a piece of code to do stuff rather than asking the piece of code for some information and then going back and doing it. We see this principle being violated in so many places in programming and we just don't think about it that way. Let me start with a very simple example for a minute. Let's say we have a collection of books. So I have books on my hand and let's say for a very simple thing, I want to go through my library of books and I want to print information about each of these books. So how would I write the code in a more familiar style of coding? I would say far int i equal to zero i less than books.size or count whatever you want to use i plus plus and then I would write some code for processing that. Now we have done this so many times we don't stop to think about it, but if you really think about it, this is a nice example of the violation of tell don't ask principle. What are we doing in the first case? We are going to this book and saying hey books give me your count and it simply says you want my count I don't know why but here you go I've got 250 books and now you say all right I start counting from zero to one to two to three until the value is less than 250. You are taking the effort to count through and then what are you going to do? One more time you're going to come down here and say books and then ask for element at that location so every step of the way you're asking for low level details from it and then you are making action. But how do we really do stuff in the real world? Imagine a lot of times how do you communicate with somebody? If somebody comes to you and says hey what are you doing tomorrow your response usually is what do you want? Generally that's what you ask them because you want to know the intention because if somebody you want to really help you may say you know what it doesn't matter what I'm doing I will come and spend the time with you. If somebody you don't want to you will create a new engagement for tomorrow so it depends on that so your context really matters. Let's think about how you would do this differently. Now I'm going to say books. For each and I'm going to specify what to do for each of the elements. Now look at the code on line number nine compared to the loop we saw a minute ago. This is an example of tell don't ask. You are telling the books collection, hey books collection for each of your elements do whatever right? So whatever is your intention whatever you want to do for each of the books but you are being very direct about this and saying hey book for each of the elements please do this. I don't want to be in the business of asking you how many you have and stuff like that. Similarly by writing the code in a more for declarative style you can promote the tell don't ask principle even further rather than the way that we've been programming where we keep asking little different information. Similarly when we design our classes rather than providing methods that are query methods and then providing methods that are methods that go affect the state of the object we should try to turn them into more methods that actually directly perform the task and give back a result. This will make benefit of two things. Become really averse of this methods that query and a method that take an action because you got to do two steps to talk to the object. Instead if you have one method that can take a bigger chunk of action to do there are two benefits you get. The first benefit is it's less work for you. You simply say do this and you forget about every other detail and the object can do it. The second benefit is it really makes it easier to evolve the code. If the action the object has to do changes tomorrow that changes in one place instead of oh we change the action over here everywhere you use the code you got to change the action consistently as well you don't have to endure that kind of pain it becomes more polymorphic rather than querying. In other words anytime you query and ask for detail and take action you are really failing to use polymorphism anytime you tell the object to do things you are using more polymorphism because an implementation of that tell method can do something little differently if it makes sense which is really hard to achieve if you're going to do things on your own side so this is a lot more beneficial so this is something to stop and think about can we really benefit from tell don't ask. Like I said I'm having trouble with this principle a lot because it is very powerful but I got to think through the code a little bit to say oh wait a minute I'm actually violating that principle here let me rearrange the code refactor it and a lot of times when I refactor the code it really becomes a lot better to understand and maintain as well. The next three principles I'm going to talk about are one of my most favorite principles the next one is called the open closed principle the open closed principle it says that a software module must be open for extension but closed from modification let me write that down it says that Burton Meyer created this principle and open open a closed principle now this sounds a little weird it says a software module so a software module must be open for extension but closed for modification so what does that mean hey how could it be open for extension and closed for modification in other words you want a software module to be able to do something more than what it did before but without having to actually change it so to understand this particular principle let's try to take a little example and work through it and see how we can actually benefit from this I'm going to close this out we don't need this anymore so I'm going to talk about this principle and I'm going to create a little example to play with it but but let's say how we're going to actually do this so I'm going to create a little example here and play with it let's see how we're going to actually be able to do that so I'm going to bring up just an example here to see how we can actually do it I'm going to start a little tool here so give me a second so I'm bringing up the wonderful command prompt I'm going to start a little code let me go to where the code is reciting on my machine and once I get there I will do a little code in C sharp here to give you an example of what this actually may mean so let's get going with a little example let's say we have where can I create it yeah this is a good place to create it so let's say we have a little a class that I want to entertain how this could become really problematic so let's go to a code and and play with it so let's say I want to create an extensible code but let me start with something simple and make it a bit extensible I'm going to increase the font in just a second here so let's get to a class I want to work with let's say I'm going to put all the classes here in one file just so I don't have to be dealing with multiple files here so so bear with me for a second but we'll get through this real quick so I have a little code that I want to make sure it's running great so I want to start with a class let's say a class called car and the car doesn't have a whole lot yet but I'm going to put a few things into it very quickly so let's say I want to create a car object so car car one equals new car but what are the things I want the car to have I'm going to say the year is 2014 I want to say what year it is I want to give it a new engine as a parameter so I'm going to give it a new engine as well I will give you this example halfway and I won't give you the full example but I will prod you to go look at few other things after this so I'm going to create a constructor here so it's going to be let's say int the year and engine I'm going to create let's say the engine so I'm going to provide these two guys over here as a parameter and let's say year is a property we'll say this is going to be the year and I'm going to say engine is a property and it's going to be the engine as well well that's great but for this to work I need those two types right the engine of course we need to create but let's also do public let's say override and I'm going to say string and two string and what do I want to do in the two string well I want to simply return let's say over here a string dot format and I'm going to simply return let's say the year first of all so I'm going to say the year and I also want to display the engine itself so let's go ahead and say year and engine so year is a property and then engine is a property too well so far so good right nothing really spectacular so far what about the engine and the year so we'll say over here a public year I'm going to say a get and a set available to it and I'm also going to say in this case we also have an engine which is going to also have a get and a set so that's good so far now for this to work we need of course a class engine our engine is not going to have a whole lot right now I'm going to leave it empty just for a few minutes so now that we have all the things we need for this to work let's go ahead and output our car one just to get a feel for what it contains oh wait a minute it contains a problem in line number 20 I want to do a format over here this is going to be what did I do wrong here oh return of course return I've got a conflict with compilers these days I program in quite a few languages that don't require a return and the compiler says you're missing a return and I argue with the compiler I'm not missing it really so it's really becomes a problem so yes I need to put a return you will notice me skip that quite a bit and of course it's still complaining on line number oh format is uppercase fs in it so that's a format of course that it wants so yep that's an engine that's 2014 now let's look at this code for a second it looks like a benign piece of code it seems to work just fine and let's make a copy of this so what I want to do here is I want to say car car two equals new car and I'm going to say over here car one so I'm making a car copy using a copy of a car I already have well if you look at this code example it looks like all I want to do is I make a copy now will that's code work let's go ahead and try that real quick and you would notice that it complains to me there is no copy constructor well C sharp doesn't provide a copy constructor automatically well why didn't they provide it well because they provide didn't provide it because people have been burned by c++ providing a copy constructor and that was evil and they said we know exactly how to fix the problem no copy constructor for you right so that is one way to fix the problem that's called running away from the problem so they did that now I'm going to write a copy constructor so what am I going to do in my copy constructor I'm going to say car other and in this case of course I'm going to say ear equals other dot ear and what if I say engine equals other dot engine do you think that's a good idea no because I would be the shallow copy and two cars would end up shedding the engine that's a disaster that's called a collision right so what do you want to do you want to say this is going to be new engine and then of course when you do an engine here you will have to have the same method in the engine as well it's going to complain about that so we got to go back to the engine class and now I'm going to say public engine which doesn't do anything and of course I've got to also provide public engine which takes the other engine and that doesn't do anything either but the compiler is going to be happy with that so we have done with this and again it looks like a simple solution so far but let's say we go a little further with this and we're going to extend it now so what I'm going to do quietly is I'm going to come and create a class called turbo engine and in the turbo engine inherits from engine so I create a constructor for the turbo engine I also create here a constructor for the turbo engine which is the copy constructor so I say other and over here what am I going to do I'm going to say that I'm going to have a base so this is going to be base and then I'm going to send nothing well actually I'm going to send the other to it so we created a turbo engine my question to you is is it legal to change this code to send a turbo engine rather than send an engine what do you think thumbs up yes or no is it legal will the compiler be happy absolutely right the compiler is not going to tell you anything it's going to be happy but when you run the code what happens you feel you're being cheated isn't it because the first car has a turbo engine the second car has a regular engine it did not make a right copy well how do we fix it well I got a way to fix it I'm going to go back to the car constructor copy constructor I'm going to say if other dot engine is a turbo engine I'm going to go ahead and create this as an engine equals new turbo engine and if it is not I'm going to say else I'm going to say this is going to be an engine and ask it to create this engine one way or the other so in this particular case let's see line number 29 is not happy with something well of course in this case you have to cast this to turbo engine because you know the other car is a turbo engine and you got to do a bit of a casting right so what do you think good or bad I see thumbs down you guys need to understand you gotta look at the positive side this is good because this gives you job security right of course we don't want the job eventually right yeah I agree with you this sucks so what's wrong with this it fails the open closed principle how does it fail the open closed principle because every time you add a new type of engine you gotta come and fix this code you gotta use eventually this will convert to a switch statement right and then you're going to switch for types and do it well this is evil but have you ever seen a code where somebody uses a is to find out what kind of widget it is or something and make a decision have you ever seen that it kind of sneaks that into the code isn't it and then it's sitting there fine until two months later oh you know what we got to go back and change that code a little bit further and then you write a little bit of code and that works and for three months later you got a little bit of code that's called scotch tape driven development right you put a little tape on it it sticks for a while well that becomes expensive why because everywhere you have to deal with the type you got to keep changing that code in different places that's a violation of open closed principle the is that you see here is called the runtime type identification and for a very long time language like c++ resisted introducing this for the same fear that the code won't be extensible if we do it but language like c-shop kind of generously provided it but we have to have the wisdom of not using it in 95% of cases so what do we do to fix it well one way to fix this problem is you would say well let's make it polymorphic and the way to make it polymorphic is you would simply say here engine equals other dot engine dot something like clone and you can ask it to be cloned for you so you could use a clone to do this and what would this do it'll perform the cloning but because the method clone is polymorphic you will if this was an engine you will get a copy of an engine if this was a turbo engine you will get a copy of turbo engine because clone can do it well this only opens the door just a little bit because you will soon end with one other problem this code will seem like it's working and you would use clone but the problem is this you would say what is good about clone well clone is a special method implemented in c-sharp you can use clone and it can make a copy of the object wonderfully but unfortunately though if you go back to this code and if you make one of the properties read only properties that you cannot modify but you want that property to be unique for example let's say I create an id int id and I want to make this property as read only so if I make a property as read only property what's going to happen well it turns out read only properties can be modified in the point of definition they can also be modified in the constructor but can you modify the read only properties in the clone method not really right so clones are not permitted to modify read only properties so what's going to happen you're going to get a compilation error very quickly because a clone cannot set this property which is read only and you're going to sit there and scratch your head don't it clone doesn't work either so a combination of clone and copy constructor would actually be needed to solve this problem the problem is not with the clone the problem is the way clone is implemented in c-sharp and in java because they all kind of went through the same path and fell off the cliff so the point really is what you do is you write your own clone method but in your clone method you call your copy constructor and you make your copy constructor a protected method so people don't directly call it so the eventual solution to this problem is you will call a clone a clone will turn on and call the copy constructor let that create the object setting the read only fields and then the clone can return the object to you and that would be the eventual solution for it but in a sense what we need to do is we need to think about the extensibility of the class and again like I mentioned earlier you want to think about this not when you design first but when you evolve the code so the minute you introduce a turbo engine that's when you want to solve this problem not until then you don't want to do premature solutions for these problems so open close principle open closed principle is a very useful principle to think about oftentimes when I work with programmers I would be doing code reviews for them or we would be sitting and doing design together and we would suggest oh how about doing this and eventually we would say oh that's a violation of open close principle we saw one example here in the copy method but open close principle violation happens in several other places sometimes we don't think about it but imagine you are dealing with the content of a file you're reading and you are doing some processing based on the content of the file and you are making a decision if this is the content do this if this is the content you do this that could be a violation of open close principle also because if that rule changes tomorrow you got to come and change that code and you got to ask yourself is there a way to extract this out so we don't have to continue to modify the code with a little bit of an effort and refactoring we can make the code extensible without failing the open close principle quite nicely the next principle I want to talk about here is called the Liskov substitution principle what does the Liskov substitution principle say the Liskov substitution principle says essentially if I have to nail it down to simple words Liskov's Liskov's substitution so substitution principle says that use inheritance only when you mean substitutability so what does that really mean it really says that inheritance is one of the most abused concepts in programming we use inheritance way too loosely than we should be so let's say we have a class so we have a class a and we also have a class let's say have a class called b so my question is should I inherit b from a so the way I look at this is inherit b from a only if anywhere an instance of instance of a can be used then so in other words inherit b from a only if anywhere an instance of a is used is used an instance of b can also be used so the substitutability is extremely important to think about can I use an instance of b anywhere an instance of a is used then the answer is use inheritance assuming b has been designed to comply with the behavior in that regard external behavior of b must be compatible right so compatible with external behavior of a this is a huge burden we take on our hands if we use inheritance if you are using inheritance for class reusability inheritance is a wrong tool so if your intention merely was was to use the implementation of a in the implementation of b then use delegation instead of inheritance so how do we see examples of this I'm going to give you one example of this which is pretty clear out there class vector now what does a class vector really do we can use a vector to add stuff remove stuff from anywhere right anywhere in the collection so that is what a vector can do for us now what if I create a class stack well what is a stack a stack is a basically a lifeful right last in first out that is the intention of a stack is to really provide a last in first out now imagine I come along and I tell you I got a bright idea I'm going to extend a stack from a vector what do you think of this idea good idea or bad idea bad idea why is it a bad idea let's think about this for a minute let's imagine for a second you are writing a piece of code that uses a vector and what does this code do it takes a vector deals with a vector as he's supposed to do with the vector he has a code that accepts a vector and he sends the vector to this particular gentleman's code and life seems to be fine so far well I come along I take a stack on my hand and I say hey you stack you are inheriting from a vector no worries because it's inherent from a vector I can use the stack anywhere a vector is being used and I send it to his function he takes the stack but he really doesn't care it's a stack he says hello vector come on in and what does he do he takes the vector and sends it to his code well his code says I got a vector on my hand and he inserts in the middle and removes from the middle and then I get back the stack on my hand and say hey stack how did it go and the stack says I feel violated right so it's been really poked and punctured in different places and he says don't send me back to him anymore right I don't like him right so the point really is this was a mistreating of an object violating its invariant and what is the invariant of the object that you should only do a life oh remove from the top and and add to the top itself and that clearly got violated in fact you would be surprised this is such a violation you would say you shouldn't do it but if you go back and look at google for or look for the stack class in the JDK java stack actually inherits from vector which is not a bright idea so this can be in different other places for example you can see evidence of this in different languages suppose I have a class let's say b uh let's call it as derived and the derived class inherits from let's say base class now in the derived class I'm going to say public something foo I'm going to add a function here called foo and I'm going to override this function so I'm going to say override like this now in C sharp java and other languages there are some rules if the base class function let's say let's go ahead and say this is a base class so I have this class base and the base class let's say has this method called foo which is public let's also say this has got a method let's say f which is oh let's call it as protected now in the case of java you can either make foo uh public or you can that's pretty much you can do right you cannot make it any more restrictive in the case of java you can take f the method f and you could actually say that method f is protected over here and of course in java you won't write override like this but nevertheless the point taken here and but if you want to you can make this public also but you cannot make make this private so java doesn't allow you to restrict it more than what the base allows in C sharp you cannot change it at all right public has to be public protected as we protected why why do they do this again for the same reason you don't want the derived class to restrict more than what the base class provides for the sake of substitutability that is very very important so the idea really is that it emphasizes some of these rules for you that falls into list of substitution principle that's where it comes from the last one i want to talk about is dependency inversion principle and i'm going to talk about this with the non-coding example i'll talk about my first experience my first visit to norway this was back in 2001 and i was excited to come to this lovely country but as you do when you come to a new place you kind of get to know about a few different things so i went to the hotel the first day i was my first visit brought to stavanger i was there in the hotel and i'm a very serious coffee drinker and i looked around there was no coffee machine in the room so i was a bit frustrated i went to the hotel staff and said there's no coffee machine in the room and they were kind enough to say okay you can borrow this coffee maker it can make bad coffee for you is it okay with you and i'm like i was happy well a few hours went by i was getting ready for bed and i looked around the room and i found something strange there was no clock in the room so i said what's the problem with these people they don't give you anything that is useful and i went back to the reservation or the front desk and said and and i went there and the lady said what is it now what do you want i said there's no clock in the room and she said yes we don't give you clocks and i said well this is going to be a problem and she said why is there a problem i said well if you don't give me a clock how do i wake up in the morning and remember this was 2001 before the days of cell phone and all those good stuff right and i and then she kind of looked a little bit confused and said i don't get it why would you need a clock to wake up and i thought for a minute and said well what else would you need and she said do you mean you need an alarm to wake up and i was getting angry because she's i thought she was getting technical on me and i said okay fine i need an alarm but in this case she was right but you never admit she's right so she said you need an alarm i said you know what you are right i've got a clock by my bedside it makes such a one you know lousy noise i cannot sleep for the rest of the day that's why i said a clock but you're right i need an alarm and she said well you don't need a clock then like no i don't need a clock i need an alarm well notice what happened here my coupling was wrong i was coupled coupled to a clock but i don't need a clock i really need an alarm i learned this lesson in norway so and then she said well there's an alarm in your room i said really this is exciting i didn't see it she said did you turn on the tv i said no i don't watch tv she said this week you will it's like okay so i went back to my room turned on the tv it said dear venkat subraman welcome to our hotel i'm like why i've been here for six hours i didn't realize that they even have my name on the tv and then i kind of looked at it it said you can set the alarm i'm a guy who believes in tdd what did i do i set the alarm for two minutes from now turn it off and wait for two minutes and two minutes later it goes on i was like hey this is wonderful this worked like an alarm i should watch tv from time to time and i put it again right you want to make sure it really works two minutes later and guess what it turned on but that was a bit strange because it turned on back only to cnn i would switch channels i would turn it off it would turn on to cnn anyway i kind of thought that was funny and i left it i'm a guy who wakes pretty early in the morning so i set up the clock to about four in the morning and i went to bed it was a very peaceful sleep i don't get jet lags by the way because i traveled so much so i was sleeping through the night and now i'm in a dark room honestly i don't know where i am right and suddenly at four in the morning i hear this loud noise in the room i jump out of my bed because there's somebody in my room i forgot about this alarm i said and i'm in panic mode i look around the tv is on and the volume keeps increasing i'm like where's the remote right lower the volume and look at the tv and i saw the most scariest thing there was this guy in suspenders with this dark glass and said hello this is larry king life can you imagine waking up to larry king live in the morning i had to go to therapy when i went back to back home right anyway now that i was awake and scared by larry king i started thinking what a great idea now i asked for a clock she said i don't have it but i could use a tv what does the tv do it supports an alarm interface i'm of course i'm i'm pretty smart i said you know what i'm not going to deal with larry king for the entire week so end of that by the end of the week i had a program written on my machine that would wake up at four o'clock and blare the computer so a computer could be an alarm these days my smartphone could be an alarm right or when i was growing up i had the best alarm one can have my grandma i would tell my grandma grandma i've got an exam could you please wake me at four o'clock and she would promptly wake me up at two o'clock and say honey don't worry about it i'm awake i'll wake you but four so the point really is i can have different implementations of this and this is an example of dependency inversion principle if you coupled directly to an implementation like clock then it doesn't give you the flexibility but rather than depending on a clock you think about what part of clock i really care about and it turns out i didn't care about a clock i really wanted an alarm so i depend on the alarm and as a result i was able to get multiple different implementation this provides a better extensibility i've used dip probably as one of the most widely used principle i often look for violation of ocp but really use of dip if you have ever used mocking for example you use dip pretty extensively you really depend on an abstraction and then you can substitute with mock objects also very easily so this is one of my favorite principles that i've used quite extensively as well so to summarize we looked at a few principles design principles here i find these principles are extremely valuable even more valuable than design patterns but i find them very useful when i apply them in the tactical design during test event development is when i get the most leverage of these i really hope you found these useful thank you
 All right. Let's get started. Welcome to the session on course of the design principles.  My name is Venkat Subramanya. We're going to talk about a few design principles here  and how it has an impact on it. I want to talk a little bit about where that has helped  me in the past. So I'll talk about some of those as well. And I'll try to keep this as  possible without getting too much into code. I'll probably give you kind of one example  just to illustrate a few points, maybe a few others as we go through. Best time to ask  a question or make a comment is when you have it. So please don't wait till the end. Anytime  is a great time. If you do want to participate, ask a question. Just say a question so you  draw my attention and I'll be more than happy to listen to you. So let's get started. We're  going to talk about some core design principles. And I have to say that these principles have  helped me enormously over the past several years. In fact, I have to say that these principles  that helped me a lot more than design patterns themselves. One of the gripes I have about  design patterns is when people look at a pattern, if they only look at a pattern to use it,  then it may not be the right pattern after all to use. But if they think about what's  the force behind using a pattern, if they look beyond that and look at design principles,  it often leads to a better reason to use a certain pattern or even a practice. So I value  the design principles enormously compared to anything else. Where do we really see them?  I feel that the design principles are very effective when we use them in a tactical design  mode. I often use this in test-driven development. There are two things I do. One is when we  are doing test-driven development, we can say, well, we want to design this, what principle  may we apply here? Certain times we look at principles to apply, certain times we look  at principles not to violate. The other benefit I've had with this is, in teams where I work  closely with them, we often use these principles as a vocabulary. For example, we would be  looking at a piece of code on our design and somebody would say, yeah, but we cannot do  that because if you do, we will be violating the OCP or violating the dry principle. So  we use these kinds of terms to communicate between each other. So this is a nice vocabulary  to build for communicating a certain intent as well. But why should we really use them?  The reason I would use them is the principles are a set of practices or things that help  us to create better quality software. And I found them to be fairly effective if applied  in the right way to the right degree. But of course, like anything else, we could also  overuse something. And when we try to use a principle when it doesn't make any sense,  it could lead to unnecessary complexity. So we have to be very careful about them. And  like I said, I've really seen this to be very effective in test-driven development, tactical  design and things like that. In evolutionary design as well, I've seen this to be very  effective. So I'm going to talk about some principles that I consider as a very set of  core principles. You probably have heard the term solid principle. Well, solid principles  are part of this, but I don't really like the word solid as much because I don't want  to say those are the principles I want to focus on. There are a few principles that  are outside of solid that seem to help as well. So put them in a sequence where I find  the most merit or value in them. So let's get started with one principle here to begin with,  which is called the dry principle. So the dry principle stands for don't repeat yourself.  So the idea behind the dry principle, this was originally written in the book called  The Pragmatic Programmers. And this is a publishing company now, but they originally started by  writing this fantastic book called The Pragmatic Programmers. And Dave Thomas and Andy Hunt  wrote this book. And in that book, they talk about the dry principle. And so what is the dry  principle really state? And dry principle says every knowledge in a system must have a single  authoritative representation. So the idea really is representation. So the idea really is  that every knowledge in the system must have a single authoritative, in fact, they even add  and one more word here unambiguous. So the idea really is we want to create, when we create an  application, we have to ask where is this piece of knowledge really kept? And duplicating this  knowledge in multiple places is really a disservice we do for ourselves. Let's think of a  few examples of this. A years ago, I was building an application and we had a problem with the system.  We couldn't implement a certain logic in a certain place in the system. So what we did was, what I  did was that I decided to, I was overly eager to solve this. So in several parts of the UI,  I had implemented a logic to perform a certain checking. A few weeks went by and the problem  was solved in a different area. And now I had to remove the code I put in for this particular logic.  Well, unfortunately, there were several places where I have to remove it, more work to remove,  and you forget in some places, and then it takes time to go back and fix it. So I learned my lesson  the hard way doing this. So when it comes to dry principle, we want to ensure that we have the  knowledge in one single place. Let's think about this with a little example here. I'm going to  just throw one example at you. And we could use different languages and tools for this,  but my idea is to illustrate the benefit of this concept. I'm looking at a little framework here  called Grails, which is written on Groovy and Java and Spring and all those good stuff, but you  can do this in multiple different tools and framework. The idea is to get a sense of what this is.  The point is we need to be able to do this in our own application if they can do it here.  So I've got a team with a name and a contact email, as you can see here. So I want to quickly try out  an example. So I'm going to say here in this case, I'm going to create a new team. So this is a new,  as you can see, and I'm going to say team one is the name of the team. And I'm going to say team  one at example.com is the email address. So notice this is a create, and I'm going to go ahead and  create it. So likewise, I'm going to create another team. I could say team two at example.com here.  And once I create team two, I could say team two here, and you can see that the teams are being  created. And I can look at a list of teams. We could also do an edit of a team. So for example,  I could click on edit, and I can change the information of the edit page, like in the create  page. So it looks like there are two different pages, one for create, one for edit. Well, that's  great so far. I'm going to kill this application. And the data is in memory. So when I restart it,  it will go away. But that's really the intention of what I wanted to show you here. So what I want  to do is I want to enforce a rule. And the rule I want to enforce is that no two teams can have  exactly the same name. Well, how do I enforce that rule? I got to enforce this rule in the create  page. Because when you're creating a team, you want to make sure that team name for the new team  is not the same as any other team out there. You also have to make sure this doesn't happen in the  edit page. Because if you're changing the name of an existing team, you don't want to give a name  of another team that already exists. So if I naively do this, this would end up duplicating the  effort in two different places. Drive principle is not about duplication of code. It is actually  about duplication of effort. The reason I say this will become clear in the next example as we will  see it in a minute. So what I want to do here is I'm in the model here. And I'm going to say name  and I'm going to say unique is true. That's all I've said here that the name is unique. So having  done this, I go back to the application. I restart it. Like I said, I'm having in-memory data. It's  going to blow it away. So I'm going to go ahead and create a new team right now. And in this case,  I'm going to go ahead and ask him to, I'm waiting for the server to start up still. So I'm going to  ask him to create a new team for us to use in this case. So when I do, I'm going to go to the create  page for us to take a look at what this shows. So I go to the create page. And on the create page,  I'm going to say team one over here. And I'm going to say that the contact is team one also. So click  on create right now. So that worked. Now we're going to new team again. This time I created team  one one more time. And I'm going to say team one also click on create. And it tells me I cannot do  this. So it tells me that the property has to be unique and you cannot do this. So I'm going to  change it to team two right now. And I'm going to change this one to team two, click on create,  it finished it. Now I go to that list of teams, I go back to team two. Notice this is the edit page,  not the create page. But in the edit page, I change it back to team one, and I click on update,  it catches me and says you cannot do this. The point really is, it is a simple activity,  but that single authoritative knowledge was captured here in this domain object. And I don't  have to go about modifying this in multiple places in one place I can express it. Well,  we could argue, are we really looking at duplication of code right now? Well, not really,  it is duplication of effort as well. Like what? Let's go to the contact email for a minute. If I go  back to the application, I can remove everything from here in the email, and I can click on update.  And in this case, of course, it was able to take the change to the email, which is really wrong.  So let's give it a try one more time and see how this is going to shape up. Now notice what I'm  going to do. I'm going back to exactly the same place. I'm going to say contact email. And I say  that this email format is true. I want to emphasize that the email actually is in the right format.  So all we did in this case is we added this one line. But let's think about it. Would you want  verification on the front end? Or do you want validation on the back end? Which one would you  like? Both I heard greedy people, right? Absolutely both. Why do we want it both? Because a front  end validation is quicker. There are other benefits for front end validation. We want it on the  front end. But you cannot live with the front end alone because the back end has to validate it too.  Why? Because you could be sending data through other means than going through the browser. You  want to make sure the validation happens on the server side. You say, wait a second. Usually the  technology for client side is different from technology in the server side. So I got to write  the code maybe in C sharp or Java or Groovy or whatever. I got to write that code on the server  side. And of course I may have to write JavaScript on the client side. So that is really two different  sets of code, isn't it? Well, not really. That is where the violation of the drive principle comes in.  It is a different code because it's different language. But it is for the same reason. So it is  a duplication of effort. Same way, you don't want to duplicate that effort for other means as well.  How can we do that? So when I go back to the application now, I'm going to, I blew away the  data again. But this time I go back to creating a new team now. And when I create the new team,  notice what happens now. I say team one over here. And I'm going to say team one without anything.  And right off the bat, you can see the error pop up. It tells me I cannot create the team right  now. If you insist, it tells you please include, it's even polite as you can see, please include  an ad symbol. And when you want to create this, and it gives that error as you can see right there.  Now, clearly we see this is a client side validation in place. And there is also a service  head validation also written for this. In other words, once again, looking at this single  authoritative representation, the tool was able to create client side and server side details  to take care of this. So that is an example of the drive principle. So what is the benefit of  following the drive principle? It becomes easier to maintain the code. It reduces the cost of  development. It makes it easier to modify and evolve the code. So I honor the drive principle  a lot. Now, when you think of a drive principle, it reminds me of an experience. I was at a client  side and one of the programmers said, oh, we tend to fix the same bugs every two months. I said,  that's nasty. Does somebody actually put back the bugs back in the code? He said, no, the code is  duplicated in so many places. We keep figuring out, discovering these places and we fix the bugs.  I said, well, when you fix a bug, you do take a little bit of time to refactor the code, right?  He thought for a minute and said, that would be a good idea, right? So I mean, what good is it  if we don't fix that and refactor the code? That's going to spill through everywhere. So it is our  responsibility to actively refactor the code and enforce the drive principle. So if there's one  thing we can look at avoiding, it is about avoiding the duplication, not just duplication of code,  but a duplication of effort as well. So when you look at code, ask yourselves, does this really  honor the drive principle? Does this really take care of not violating this principle? That is  something to think about. The second principle I quite heavily use is the Yagney principle.  Sometimes people get very angry when I use the Yagney because they say, of course you need it.  So I change it a little bit. It stands for you aren't going to need it. So it is a principle  that says we really don't need it. But I change it a little bit just to kind of make a little bit  of ease. I say you aren't going to need it yet. And that seems to ring a better bell to people  than you aren't going to need it. They get very apprehensive. Well, oftentimes what I find people  do is when they are designing a piece of code, they put in a lot of different features. They put  error checking. They put extensibility in place. They look at data types and how extensible can it  be? Oh, this has got to be a generic type. Whatever it is they think of, they put all of those in  place. But my question often is, do you really need it? If we don't really need it, we need to  postpone it until we know a little bit better. But oftentimes we hear people say, I'm not exactly  sure what the functionality is, but I can still write the code. So it takes a bit of a discipline  to say, we don't know what exactly this is, or we don't know if something is really needed. So we  are going to postpone adding this to a later time. And the Yagney principle is a good principle to  follow for that reason. Now, you aren't going to need it yet is a much better in my opinion because  it says that it's not that you will never need it, but the fact that you may not need it right now  helps you to postpone the decision until you know better about this. And then you can decide to use  it or not. So it's not that you are condemned from using that, but let's postpone until we know better.  And if we later on we find out we actually need it, we can absolutely implement it.  Otherwise, we don't have to use it. One of the real problems here is this. Let's say for a minute,  we've been implementing code, and let's say you implemented a piece of code. And two days later,  I come over and say, we don't need that code, you're going to be pretty angry because you took  the time to write it, and you're going to say, you better use it because I wrote it, right? But the  code we did not write is the easiest code to throw away because, hey, I didn't really write it.  Thanks for saying it. I can go do something else more meaningful right now. So that's a principle  I really like using. So we don't really have to force ourselves to use this code. We can postpone  it. The next principle I want to talk about is probably one of the most important principles,  but it comes in different names. It's a single responsibility principle. A single responsibility  principle says that every piece of code needs to have a single one purpose, one reason. This is  also often called as cohesion. So cohesion is a property where things belonging together are  together and things that are not belonging together are separate. Now let's think about  cohesion. What does it really mean? Well, in real life, we can think about cohesion in several ways.  I'll give you one example. When I was a child, I was the brat that really liked to come home from  school, throw things and then run out to the street and play. That was a lot of fun. And I had a  wonderful parents who tried to teach me values and they said, hey Venkat, when you come back home,  you don't throw stuff and run away. You got to put things in place. Well, I used to have this  cupboard and I would throw things into the cupboard and run away. It was fun when I had to do it,  but any time I needed something from it was terrible because I would open it. If I pull a  blue sock, the next sock I find will not be blue in color because it's obviously hidden somewhere  else in it. So it was more effort to take things out. It was much easier to throw things in.  It was a mess and my parents tried really hard. They kept telling me, don't do this. You got to  keep things separate. You got to put your colored sock, all the light colors in one place, light  colors, another one in this place and they tried to teach me all of this and that never worked.  And you may look at me and say, well, it looks like you already turned out to be better. How did  that happen? Well, I got married. A lot of things changed when that happens. So what my parents  couldn't do my lovelies can do. So that's beauty of that is things are more organized and now my  books are in the study. My clothes are in a different room and there is harmony and everything.  You know where exactly things are. In fact, it's such wonderful that a couple of months ago,  I was somewhere else in the world and I really wanted a reference from a book which is a very  old book. I couldn't find the reference online and so much so that I could actually call my wife  and say, would you do me a favor, go down to the bookshelf, the third book from the top row. I  wanted to pull that out and look at this particular index and read it for me. So that kind of discipline  eventually evolves and that is an example of cohesion. Like things are together and dislike  things are apart and that really helps to find things easy and maintain them. We can do this a  lot in the code. For example, classes. Don't put multiple classes in one file, for example. That's  a rule we can follow. And when you write classes, you want the classes to be narrow and focused.  One thing done one. What if your class is doing input-output-related operations plus  database operations and dealing with some calculation, what's going to happen? If that is one class  you have, let's say this is your class you have written and if this class does every single operation,  well, the problem is that class is going to be very, very unstable. In other words, every single  thing that changes in the system potentially could affect this one class you wrote because it does  everything. On the other hand, you split this into smaller classes. You have one class that deals with  input-output, another class that deals with calculation, a third class that deals with  database, a fourth class that may deal with maybe a particular calculation. Now the chances are  you may decide to change the calculation, you change one class, or even better, you can provide an  alternate implementation of the calculation class and the other classes can vary with the factory  or something to use one or the other. So the reason for a class to change becomes a lot less  when every class focuses on a single principle and does one thing and one thing well. So we can look  at single responsibly principle at the class level. But we can also look at single responsibly  principle at the method level also. Let's think about this for a minute. A long method. So let's  think about long methods. Who here thinks long methods are a good idea? Not a single person,  right? Now why do we think long methods are not a good idea? Let's think about some of the reasons  why long methods are a bad idea. So can you throw some reasons at me? Why long methods are bad?  It's really hard to read, right? Hard to read, thank you. What else?  Hard to test. What a wonderful way to think about it, right? How do you test this method? So  readability. You look at this method, I remember one experience, a client called me up and said,  hey, do a code review for us and help us with some problems we are having. So I started doing  code review. And I started with this method. I read about 25 lines of method code. And after 25  lines, my thought was how much more do I have to read? So I started scrolling down. Then I started  paging down. And then eventually I said that doesn't work. And I used the tool to find out the curly  braces and find the difference in the number of lines of code, right? And that said there are  750 lines of code in that one function. Immediately I'm like where's the nearest coffee machine? I  need some caffeine, right? It is frustrating when you see that code. Why? Because you are like, whoa,  that's a lot of lines of code to read, to comprehend this one idea, how worse it can turn very quickly.  And also imagine how do you test that method? How do you go through combination of the methods and  the branches in the code? The permutation and combination through it is going to be so many  that you cannot possibly write enough tests on that method to satisfy all the branches or it  becomes extremely complex to be able to do it. So that is another problem with it. What else do we  have? What was that? Oh yeah, wonderful. Hard to reuse. How do you reuse a monster? What you need  is those 10 lines right in the middle. Well, but you cannot reuse the 10 lines because it's within  the method. So what do you do? You take the 10 lines away from it and what do you do with it?  You stick it into another long method, right? So as a result, it leads to duplication of code as well.  So it's combination of both. It's hard to reuse and in turn it leads to duplication as well. Anything  else we can think of? A little louder, please? Oh, hard to debug. So hard to debug. Well,  that's actually not a problem, right? That's why you hire the interns, right? So you say go get it  and the interns of course log through and they say this is what you guys do for a living. That  makes it really hard. So hard to debug. What else? Is that it? Hard to maintain.  Hard to modify. What else do we have? Anything more?  Hard to what? Hard to remove. Yeah, hard to remove. Fails single response to be principle  has what do you call it? Tight coupling often, right? More coupling in code. If a code is  that big, chances are, miscellaneous company, right, is going to ask for other dependencies.  So that's going to be really coupled and that makes it hard to remove as well and other problems  that will come with it. So there are so many problems with long methods. But let me ask you  this question. We already asked you this question, right? Who here thinks long methods are good and  nobody raised the hand? My question is different. Who here has seen long methods? Look at that,  right? Almost everybody in the room is raising the hand. This is called cognitive dissonance.  We all know it is bad, but yet we see it. Does anybody know? You all know it is bad,  but then why do we have long methods? Well, the sad story is this. Nobody in this room wants to  write long methods because you all know it's bad. But the folks who believe it's good are at work  right now, making those methods longer as we speak, right? That is the problem we have to deal with.  So what do we do about long methods? So if there's one thing, just one thing we can teach people,  if one thing we can do, and that is to tell people, please don't write long methods, there'll be so  much improvement in our design. If we can do just one thing, don't write long methods. And why do we  write long methods? I really don't know the answer for that. Why do we write it? That's like a very  bad practice. Now, if we don't write long methods, what happens? The code becomes cohesive, a single  responsibility. It becomes easier to understand, easier to maintain, and there are so many benefits  in doing it. But the question is this, how long is long? So let's try to put a number on this.  How long is long? Somebody said 25 lines of code. And immediately Ruby programmers said,  what 25? We never write 25 lines of code. Seven lines it is. Well, the closure guide said seven  lines, we don't write anything for seven lines, only three lines. There is no way to win this  battle of number of lines of code. Well, here's another measure we could use. How long is long?  I would say if you can see the entire, entire method in one window, right? But don't try to  lower that font size. So you want to see the entire method in your window, okay, that may be a good  measure. But there is a better way to think about it than either one of those. So what is a short  method? A short method is not a method with fewer lines of code. That is a wrong way to look at it.  Let's think about this a little differently. Remember that gentlemen or the programmer or  person that we talked about at your work, and what does this person do? The person writes  long methods every day. And you believe wrong methods are bad. You told this person several  times the person doesn't want to listen to you. So I got a last-ditch effort to convince this person.  So go to, go back to work on Monday. Don't say a word. Just sit down and start coding.  This, this colleague of yours who writes long methods comes over to you and says,  hey, how was your weekend? You could say your weekend was great by saying when, you know,  something like went to the park on Saturday, you can say, and then you can say went to the movies  on Sunday, right? So you could, you could say something like this, but don't do that. Instead,  you say, oh, my weekend. Well, I'll tell you at 10 o'clock, I got into the car, turned it on,  you know, back the car up stood at the stoplight for about seven seconds, turned right, went for  another two kilometers. And then I turned left. Oh, there was a bird on the street as I was going  through. And then I went two more, you know, feet, and then I had to turn right for more kilometers.  Just keep going like this. After about 10 minutes or so, your colleague is in a panic mode and says,  stop. Have you gone mad? You say, no, I'm not gone mad. I thought I will tell you how my weekend  was like the way you write code, right? So the point is, we don't talk to people like that. How  do we talk to people? We talk to people in these high level of concepts. I went to the park on  Saturday and went to the movies on Sunday. Now your colleague may be interested in movies and may  say, really, what movie did you go to? Notice your colleague did not ask you about the park.  Or another colleague who we're talking to may be interested in a park and say, tell me what park  did you go to? And maybe you say what park you went to and the colleague now says, really,  is that park over here? Is it family friendly? I want to know more about it. So notice what's  happening in the communication. We mention things in one level of abstraction at a time. So that  is something very important to think about when writing methods. This principle is called the  slap principle. Where the slap principle, no, don't do this, you call a colleague. The slap  principle stands for single level of abstraction principle. So in other words, what should we  do when we write methods? The method is short if the method is focusing on a single level of  abstraction. So in other words, when you look at a method, a method should nicely compose itself  and tell us what the method is really doing. So another name for this pattern is called the  compose. So it's called a compose method pattern. And the idea really is the method nicely composes  things at a single level of abstraction. And that is called a compose method pattern. So the idea  of a compose method pattern is to compose things at a single level of abstraction. And then if you  want more detail about that particular level of abstraction, you dive into that method and look  at the details. So then what happens is the code becomes very easy to read and understand what's  going on. Now also this becomes easy for maintenance and debugging later on as well. When you are  trying to get into a code, if you have 750 lines of code in front of you versus if you have about  four lines of code where those lines of code are in these levels different of abstraction,  there are some clear benefits here. The first benefit is if you had 750 lines of code, chances are  that it's all jumbled up and the logic goes back and forth. You do a little bit of this,  a little bit of something else, a little bit of something else, it becomes hard to understand  and maintain. But if you have those four lines of code at one level of abstraction,  everything to do with one abstraction will be inside that method. Everything related to the  second abstraction will be inside that method. So that's more cohesive and focused on single  responsibility as well. And then when it comes to debugging the code or understanding it or  maintaining it, we take these high level concepts in our mind and say, oh, you are doing XYZ access  over here, got it. If I really want to dig in and look at more details about it, I can step into it,  but I don't need to know that detail right now. I can skim over to the next one. So as human beings,  we retain these chunks of concepts in our mind and not these little turns and twists that we  make all the time. So that's a better way to write code. So if there's one thing we can try to do in  our field, that should be really removing long methods and writing things that are focused on  a single level of abstraction as much as we can. So that is something to think about how we can  achieve this. The next principle I want to talk about here is a principle that is really hot for  me because I don't tend to think about it that much, but I think it's a very important principle.  And the times I've applied this, it's come as a surprise to me that I didn't quite pay attention  to it. So this is called the tell don't ask principle. The tell don't ask principle says  that you want to tell a piece of code to do stuff rather than asking the piece of code for some  information and then going back and doing it. We see this principle being violated in so many  places in programming and we just don't think about it that way. Let me start with a very simple  example for a minute. Let's say we have a collection of books. So I have books on my hand and let's  say for a very simple thing, I want to go through my library of books and I want to print information  about each of these books. So how would I write the code in a more familiar style of coding?  I would say far int i equal to zero i less than books.size or count whatever you want to use  i plus plus and then I would write some code for processing that. Now we have done this so many  times we don't stop to think about it, but if you really think about it, this is a nice example of  the violation of tell don't ask principle. What are we doing in the first case? We are going to this  book and saying hey books give me your count and it simply says you want my count I don't know why  but here you go I've got 250 books and now you say all right I start counting from zero to one to  two to three until the value is less than 250. You are taking the effort to count through and then  what are you going to do? One more time you're going to come down here and say books and then ask for  element at that location so every step of the way you're asking for low level details from it  and then you are making action. But how do we really do stuff in the real world? Imagine a lot  of times how do you communicate with somebody? If somebody comes to you and says hey what are you  doing tomorrow your response usually is what do you want? Generally that's what you ask them  because you want to know the intention because if somebody you want to really help you may say  you know what it doesn't matter what I'm doing I will come and spend the time with you. If somebody  you don't want to you will create a new engagement for tomorrow so it depends on that so your context  really matters. Let's think about how you would do this differently. Now I'm going to say books.  For each and I'm going to specify what to do for each of the elements. Now look at the code  on line number nine compared to the loop we saw a minute ago. This is an example of tell don't ask.  You are telling the books collection, hey books collection for each of your elements do whatever  right? So whatever is your intention whatever you want to do for each of the books but you are  being very direct about this and saying hey book for each of the elements please do this. I don't  want to be in the business of asking you how many you have and stuff like that. Similarly by writing  the code in a more for declarative style you can promote the tell don't ask principle even further  rather than the way that we've been programming where we keep asking little different information.  Similarly when we design our classes rather than providing methods that are query methods and then  providing methods that are methods that go affect the state of the object we should try to turn them  into more methods that actually directly perform the task and give back a result. This will make  benefit of two things. Become really averse of this methods that query and a method that take  an action because you got to do two steps to talk to the object. Instead if you have one method that  can take a bigger chunk of action to do there are two benefits you get. The first benefit is it's  less work for you. You simply say do this and you forget about every other detail and the object  can do it. The second benefit is it really makes it easier to evolve the code. If the action the  object has to do changes tomorrow that changes in one place instead of oh we change the action over  here everywhere you use the code you got to change the action consistently as well you don't have to  endure that kind of pain it becomes more polymorphic rather than querying. In other words anytime you  query and ask for detail and take action you are really failing to use polymorphism anytime you  tell the object to do things you are using more polymorphism because an implementation of that  tell method can do something little differently if it makes sense which is really hard to achieve  if you're going to do things on your own side so this is a lot more beneficial so this is something  to stop and think about can we really benefit from tell don't ask. Like I said I'm having trouble  with this principle a lot because it is very powerful but I got to think through the code a  little bit to say oh wait a minute I'm actually violating that principle here let me rearrange  the code refactor it and a lot of times when I refactor the code it really becomes a lot better  to understand and maintain as well. The next three principles I'm going to talk about are one of my  most favorite principles the next one is called the open closed principle the open closed principle  it says that a software module must be open for extension but closed from modification let me write  that down it says that Burton Meyer created this principle and open open a closed principle now this  sounds a little weird it says a software module so a software module must be open for extension  but closed for modification so what does that mean hey how could it be open for extension  and closed for modification in other words you want a software module to be able to do something  more than what it did before but without having to actually change it so to understand this particular  principle let's try to take a little example and work through it and see how we can actually  benefit from this I'm going to close this out we don't need this anymore so I'm going to talk about  this principle and I'm going to create a little example to play with it but but let's say how  we're going to actually do this so I'm going to create a little example here and play with it  let's see how we're going to actually be able to do that so I'm going to bring up just an example  here to see how we can actually do it I'm going to start a little tool here so give me a second  so I'm bringing up the wonderful command prompt I'm going to start a little code let me go to  where the code is reciting on my machine and once I get there I will do a little code in C sharp  here to give you an example of what this actually may mean so let's get going with a little example  let's say we have where can I create it yeah this is a good place to create it so let's say we have  a little a class that I want to entertain how this could become really problematic so let's go to  a code and and play with it so let's say I want to create an extensible code but let me start with  something simple and make it a bit extensible I'm going to increase the font in just a second here  so let's get to a class I want to work with let's say I'm going to put all the classes here in one  file just so I don't have to be dealing with multiple files here so so bear with me for a second  but we'll get through this real quick so I have a little code that I want to make sure it's running  great so I want to start with a class let's say a class called car and the car doesn't have a whole  lot yet but I'm going to put a few things into it very quickly so let's say I want to create a car  object so car car one equals new car but what are the things I want the car to have I'm going to  say the year is 2014 I want to say what year it is I want to give it a new engine as a parameter  so I'm going to give it a new engine as well I will give you this example halfway and I won't give  you the full example but I will prod you to go look at few other things after this so I'm going to  create a constructor here so it's going to be let's say int the year and engine I'm going to create  let's say the engine so I'm going to provide these two guys over here as a parameter and let's say  year is a property we'll say this is going to be the year and I'm going to say engine is a property  and it's going to be the engine as well well that's great but for this to work I need those two  types right the engine of course we need to create but let's also do public let's say override and I'm  going to say string and two string and what do I want to do in the two string well I want to simply  return let's say over here a string dot format and I'm going to simply return let's say the year  first of all so I'm going to say the year and I also want to display the engine itself so let's  go ahead and say year and engine so year is a property and then engine is a property too well  so far so good right nothing really spectacular so far what about the engine and the year so we'll say  over here a public year I'm going to say a get and a set available to it and I'm also going to say  in this case we also have an engine which is going to also have a get and a set so that's good so far  now for this to work we need of course a class engine our engine is not going to have a whole lot  right now I'm going to leave it empty just for a few minutes so now that we have all the things we  need for this to work let's go ahead and output our car one just to get a feel for what it contains  oh wait a minute it contains a problem in line number 20 I want to do a format over here this is  going to be what did I do wrong here oh return of course return I've got a conflict with compilers  these days I program in quite a few languages that don't require a return and the compiler says  you're missing a return and I argue with the compiler I'm not missing it really so it's really  becomes a problem so yes I need to put a return you will notice me skip that quite a bit and of  course it's still complaining on line number oh format is uppercase fs in it so that's a format  of course that it wants so yep that's an engine that's 2014 now let's look at this code for a  second it looks like a benign piece of code it seems to work just fine and let's make a copy of this  so what I want to do here is I want to say car car two equals new car and I'm going to say over  here car one so I'm making a car copy using a copy of a car I already have well if you look at this  code example it looks like all I want to do is I make a copy now will that's code work let's go  ahead and try that real quick and you would notice that it complains to me there is no copy constructor  well C sharp doesn't provide a copy constructor automatically well why didn't they provide it  well because they provide didn't provide it because people have been burned by c++ providing a copy  constructor and that was evil and they said we know exactly how to fix the problem no copy  constructor for you right so that is one way to fix the problem that's called running away from the  problem so they did that now I'm going to write a copy constructor so what am I going to do in my  copy constructor I'm going to say car other and in this case of course I'm going to say ear equals  other dot ear and what if I say engine equals other dot engine do you think that's a good idea  no because I would be the shallow copy and two cars would end up shedding the engine  that's a disaster that's called a collision right so what do you want to do you want to say this is  going to be new engine and then of course when you do an engine here you will have to have the same  method in the engine as well it's going to complain about that so we got to go back to the engine  class and now I'm going to say public engine which doesn't do anything and of course I've got to  also provide public engine which takes the other engine and that doesn't do anything either but the  compiler is going to be happy with that so we have done with this and again it looks like a simple  solution so far but let's say we go a little further with this and we're going to extend it now  so what I'm going to do quietly is I'm going to come and create a class called turbo engine  and in the turbo engine inherits from engine so I create a constructor for the turbo engine I also  create here a constructor for the turbo engine which is the copy constructor so I say other and  over here what am I going to do I'm going to say that I'm going to have a base so this is going to  be base and then I'm going to send nothing well actually I'm going to send the other to it so  we created a turbo engine my question to you is is it legal to change this code to send a turbo  engine rather than send an engine what do you think thumbs up yes or no is it legal will the  compiler be happy absolutely right the compiler is not going to tell you anything it's going to be  happy but when you run the code what happens you feel you're being cheated isn't it because the first  car has a turbo engine the second car has a regular engine it did not make a right copy well how do we  fix it well I got a way to fix it I'm going to go back to the car constructor copy constructor  I'm going to say if other dot engine is a turbo engine I'm going to go ahead and create this as  an engine equals new turbo engine and if it is not I'm going to say else I'm going to say this is  going to be an engine and ask it to create this engine one way or the other so in this particular  case let's see line number 29 is not happy with something well of course in this case you have  to cast this to turbo engine because you know the other car is a turbo engine and you got to do a  bit of a casting right so what do you think good or bad I see thumbs down you guys need to understand  you gotta look at the positive side this is good because this gives you job security right of course  we don't want the job eventually right yeah I agree with you this sucks so what's wrong with this  it fails the open closed principle how does it fail the open closed principle because every time  you add a new type of engine you gotta come and fix this code you gotta use eventually this will  convert to a switch statement right and then you're going to switch for types and do it well  this is evil but have you ever seen a code where somebody uses a is to find out what kind of widget  it is or something and make a decision have you ever seen that it kind of sneaks that into the code  isn't it and then it's sitting there fine until two months later oh you know what we got to go back  and change that code a little bit further and then you write a little bit of code and that works and  for three months later you got a little bit of code that's called scotch tape driven development  right you put a little tape on it it sticks for a while well that becomes expensive why because  everywhere you have to deal with the type you got to keep changing that code in different places  that's a violation of open closed principle the is that you see here is called the runtime type  identification and for a very long time language like c++ resisted introducing this for the same  fear that the code won't be extensible if we do it but language like c-shop kind of generously  provided it but we have to have the wisdom of not using it in 95% of cases so what do we do to fix it  well one way to fix this problem is you would say well let's make it polymorphic and the way to  make it polymorphic is you would simply say here engine equals other dot engine dot something like  clone and you can ask it to be cloned for you so you could use a clone to do this and what would  this do it'll perform the cloning but because the method clone is polymorphic you will if this was  an engine you will get a copy of an engine if this was a turbo engine you will get a copy of turbo  engine because clone can do it well this only opens the door just a little bit because you will  soon end with one other problem this code will seem like it's working and you would use clone  but the problem is this you would say what is good about clone well clone is a special method  implemented in c-sharp you can use clone and it can make a copy of the object wonderfully  but unfortunately though if you go back to this code and if you make one of the properties read  only properties that you cannot modify but you want that property to be unique for example let's say  I create an id int id and I want to make this property as read only so if I make a property as  read only property what's going to happen well it turns out read only properties can be modified  in the point of definition they can also be modified in the constructor but can you modify  the read only properties in the clone method not really right so clones are not permitted to  modify read only properties so what's going to happen you're going to get a compilation error very  quickly because a clone cannot set this property which is read only and you're going to sit there  and scratch your head don't it clone doesn't work either so a combination of clone and copy constructor  would actually be needed to solve this problem the problem is not with the clone the problem is the  way clone is implemented in c-sharp and in java because they all kind of went through the same  path and fell off the cliff so the point really is what you do is you write your own clone method  but in your clone method you call your copy constructor and you make your copy constructor a  protected method so people don't directly call it so the eventual solution to this problem is  you will call a clone a clone will turn on and call the copy constructor let that create the  object setting the read only fields and then the clone can return the object to you and that would  be the eventual solution for it but in a sense what we need to do is we need to think about  the extensibility of the class and again like I mentioned earlier you want to think about this not  when you design first but when you evolve the code so the minute you introduce a turbo engine  that's when you want to solve this problem not until then you don't want to do premature solutions  for these problems so open close principle open closed principle is a very useful principle to  think about oftentimes when I work with programmers I would be doing code reviews for them or we would  be sitting and doing design together and we would suggest oh how about doing this and eventually  we would say oh that's a violation of open close principle we saw one example here in the copy  method but open close principle violation happens in several other places sometimes we don't think  about it but imagine you are dealing with the content of a file you're reading and you are  doing some processing based on the content of the file and you are making a decision if this is the  content do this if this is the content you do this that could be a violation of open close  principle also because if that rule changes tomorrow you got to come and change that code  and you got to ask yourself is there a way to extract this out so we don't have to  continue to modify the code with a little bit of an effort and refactoring we can make the code  extensible without failing the open close principle quite nicely the next principle I want to talk  about here is called the Liskov substitution principle what does the Liskov substitution  principle say the Liskov substitution principle says essentially if I have to nail it down to  simple words Liskov's Liskov's substitution so substitution principle says that use inheritance  only when you mean substitutability so what does that really mean it really says that inheritance  is one of the most abused concepts in programming we use inheritance way too loosely than we should  be so let's say we have a class so we have a class a and we also have a class let's say have a class  called b so my question is should I inherit b from a so the way I look at this is inherit b from a  only if anywhere an instance of instance of a can be used then so in other words inherit b from a  only if anywhere an instance of a is used is used an instance of b can also be used so the  substitutability is extremely important to think about can I use an instance of b anywhere an instance  of a is used then the answer is use inheritance assuming b has been designed to comply with the  behavior in that regard external behavior of b must be compatible right so compatible with external  behavior of a this is a huge burden we take on our hands if we use inheritance if you are using  inheritance for class reusability inheritance is a wrong tool so if your intention merely was  was to use the implementation of a in the implementation of b then use delegation instead  of inheritance so how do we see examples of this I'm going to give you one example of this which  is pretty clear out there class vector now what does a class vector really do we can use a vector  to add stuff remove stuff from anywhere right anywhere in the collection so that is what a  vector can do for us now what if I create a class stack well what is a stack a stack is a basically  a lifeful right last in first out that is the intention of a stack is to really provide a  last in first out now imagine I come along and I tell you I got a bright idea I'm going to extend  a stack from a vector what do you think of this idea good idea or bad idea bad idea why is it a  bad idea let's think about this for a minute let's imagine for a second you are writing a piece of  code that uses a vector and what does this code do it takes a vector deals with a vector as he's  supposed to do with the vector he has a code that accepts a vector and he sends the vector to this  particular gentleman's code and life seems to be fine so far well I come along I take a stack on  my hand and I say hey you stack you are inheriting from a vector no worries because it's inherent  from a vector I can use the stack anywhere a vector is being used and I send it to his function  he takes the stack but he really doesn't care it's a stack he says hello vector come on in  and what does he do he takes the vector and sends it to his code well his code says I got a vector  on my hand and he inserts in the middle and removes from the middle and then I get back the stack on  my hand and say hey stack how did it go and the stack says I feel violated right so it's been really  poked and punctured in different places and he says don't send me back to him anymore right I don't  like him right so the point really is this was a mistreating of an object violating its invariant  and what is the invariant of the object that you should only do a life oh remove from the top and  and add to the top itself and that clearly got violated in fact you would be surprised this is  such a violation you would say you shouldn't do it but if you go back and look at google for or look  for the stack class in the JDK java stack actually inherits from vector which is not a bright idea  so this can be in different other places for example you can see evidence of this in different  languages suppose I have a class let's say b uh let's call it as derived and the derived class  inherits from let's say base class now in the derived class I'm going to say public something  foo I'm going to add a function here called foo and I'm going to override this function so I'm going  to say override like this now in C sharp java and other languages there are some rules if the base  class function let's say let's go ahead and say this is a base class so I have this class base  and the base class let's say has this method called foo which is public let's also say this has got a  method let's say f which is oh let's call it as protected now in the case of java you can either  make foo uh public or you can that's pretty much you can do right you cannot make it any more  restrictive in the case of java you can take f the method f and you could actually say that method f  is protected over here and of course in java you won't write override like this but nevertheless the  point taken here and but if you want to you can make this public also but you cannot make make this  private so java doesn't allow you to restrict it more than what the base allows in C sharp you  cannot change it at all right public has to be public protected as we protected why why do they  do this again for the same reason you don't want the derived class to restrict more than what the  base class provides for the sake of substitutability that is very very important so the idea really  is that it emphasizes some of these rules for you that falls into list of substitution principle  that's where it comes from the last one i want to talk about is dependency inversion principle  and i'm going to talk about this with the non-coding example i'll talk about my first experience my  first visit to norway this was back in 2001 and i was excited to come to this lovely country but  as you do when you come to a new place you kind of get to know about a few different things so i  went to the hotel the first day i was my first visit brought to stavanger i was there in the hotel  and i'm a very serious coffee drinker and i looked around there was no coffee machine in the room  so i was a bit frustrated i went to the hotel staff and said there's no coffee machine in the room  and they were kind enough to say okay you can borrow this coffee maker it can make bad coffee for  you is it okay with you and i'm like i was happy well a few hours went by i was getting ready for  bed and i looked around the room and i found something strange there was no clock in the room  so i said what's the problem with these people they don't give you anything that is useful  and i went back to the reservation or the front desk and said and and i went there and the lady  said what is it now what do you want i said there's no clock in the room and she said yes we don't  give you clocks and i said well this is going to be a problem and she said why is there a problem i  said well if you don't give me a clock how do i wake up in the morning and remember this was 2001  before the days of cell phone and all those good stuff right and i and then she kind of looked a  little bit confused and said i don't get it why would you need a clock to wake up and i thought  for a minute and said well what else would you need and she said do you mean you need an alarm to  wake up and i was getting angry because she's i thought she was getting technical on me and i said  okay fine i need an alarm but in this case she was right but you never admit she's right so she  said you need an alarm i said you know what you are right i've got a clock by my bedside it makes  such a one you know lousy noise i cannot sleep for the rest of the day that's why i said a clock  but you're right i need an alarm and she said well you don't need a clock then like no i don't need  a clock i need an alarm well notice what happened here my coupling was wrong i was coupled coupled to  a clock but i don't need a clock i really need an alarm i learned this lesson in norway so and then  she said well there's an alarm in your room i said really this is exciting i didn't see it  she said did you turn on the tv i said no i don't watch tv she said this week you will  it's like okay so i went back to my room turned on the tv it said dear venkat subraman welcome to  our hotel i'm like why i've been here for six hours i didn't realize that they even have my name  on the tv and then i kind of looked at it it said you can set the alarm i'm a guy who believes in  tdd what did i do i set the alarm for two minutes from now turn it off and wait for two minutes  and two minutes later it goes on i was like hey this is wonderful this worked like an alarm i should  watch tv from time to time and i put it again right you want to make sure it really works two  minutes later and guess what it turned on but that was a bit strange because it turned on back  only to cnn i would switch channels i would turn it off it would turn on to cnn anyway i kind of  thought that was funny and i left it i'm a guy who wakes pretty early in the morning so i set up the  clock to about four in the morning and i went to bed it was a very peaceful sleep i don't get jet  lags by the way because i traveled so much so i was sleeping through the night and now i'm in a  dark room honestly i don't know where i am right and suddenly at four in the morning i hear this  loud noise in the room i jump out of my bed because there's somebody in my room i forgot about this  alarm i said and i'm in panic mode i look around the tv is on and the volume keeps increasing i'm  like where's the remote right lower the volume and look at the tv and i saw the most scariest thing  there was this guy in suspenders with this dark glass and said hello this is larry king life  can you imagine waking up to larry king live in the morning i had to go to therapy when i went  back to back home right anyway now that i was awake and scared by larry king i started thinking  what a great idea now i asked for a clock she said i don't have it but i could use a tv what does  the tv do it supports an alarm interface i'm of course i'm i'm pretty smart i said you know what  i'm not going to deal with larry king for the entire week so end of that by the end of the week i  had a program written on my machine that would wake up at four o'clock and blare the computer so a  computer could be an alarm these days my smartphone could be an alarm right or when i was growing up  i had the best alarm one can have my grandma i would tell my grandma grandma i've got an  exam could you please wake me at four o'clock and she would promptly wake me up at two o'clock and  say honey don't worry about it i'm awake i'll wake you but four so the point really is i can have  different implementations of this and this is an example of dependency inversion principle if you  coupled directly to an implementation like clock then it doesn't give you the flexibility but rather  than depending on a clock you think about what part of clock i really care about and it turns out  i didn't care about a clock i really wanted an alarm so i depend on the alarm and as a result  i was able to get multiple different implementation this provides a better extensibility i've used  dip probably as one of the most widely used principle i often look for violation of ocp  but really use of dip if you have ever used mocking for example you use dip pretty extensively  you really depend on an abstraction and then you can substitute with mock objects also very easily  so this is one of my favorite principles that i've used quite extensively as well  so to summarize we looked at a few principles design principles here i find these principles are  extremely valuable even more valuable than design patterns but i find them very useful  when i apply them in the tactical design during test event development is when i get the most  leverage of these i really hope you found these useful thank you
Venkat_Subramaniam_-_Core_Software_Design_Principles_0_5495.png Venkat_Subramaniam_-_Core_Software_Design_Principles_5496_5651.png Venkat_Subramaniam_-_Core_Software_Design_Principles_5652_5699.png Venkat_Subramaniam_-_Core_Software_Design_Principles_5700_5759.png Venkat_Subramaniam_-_Core_Software_Design_Principles_5760_6011.png Venkat_Subramaniam_-_Core_Software_Design_Principles_6012_6503.png Venkat_Subramaniam_-_Core_Software_Design_Principles_6504_8891.png Venkat_Subramaniam_-_Core_Software_Design_Principles_8892_9731.png Venkat_Subramaniam_-_Core_Software_Design_Principles_9732_9803.png Venkat_Subramaniam_-_Core_Software_Design_Principles_9804_10655.png Venkat_Subramaniam_-_Core_Software_Design_Principles_10656_11207.png Venkat_Subramaniam_-_Core_Software_Design_Principles_11208_11255.png Venkat_Subramaniam_-_Core_Software_Design_Principles_11256_12827.png Venkat_Subramaniam_-_Core_Software_Design_Principles_12828_13043.png Venkat_Subramaniam_-_Core_Software_Design_Principles_13044_13391.png Venkat_Subramaniam_-_Core_Software_Design_Principles_13392_14663.png Venkat_Subramaniam_-_Core_Software_Design_Principles_14664_15299.png Venkat_Subramaniam_-_Core_Software_Design_Principles_15300_15707.png Venkat_Subramaniam_-_Core_Software_Design_Principles_15708_15995.png Venkat_Subramaniam_-_Core_Software_Design_Principles_15996_16067.png Venkat_Subramaniam_-_Core_Software_Design_Principles_16068_17999.png Venkat_Subramaniam_-_Core_Software_Design_Principles_18000_18803.png Venkat_Subramaniam_-_Core_Software_Design_Principles_18804_19151.png Venkat_Subramaniam_-_Core_Software_Design_Principles_19152_19463.png Venkat_Subramaniam_-_Core_Software_Design_Principles_19464_27203.png Venkat_Subramaniam_-_Core_Software_Design_Principles_27204_30935.png Venkat_Subramaniam_-_Core_Software_Design_Principles_30936_39143.png Venkat_Subramaniam_-_Core_Software_Design_Principles_39144_40631.png Venkat_Subramaniam_-_Core_Software_Design_Principles_40632_43103.png Venkat_Subramaniam_-_Core_Software_Design_Principles_43104_43811.png Venkat_Subramaniam_-_Core_Software_Design_Principles_43812_43991.png Venkat_Subramaniam_-_Core_Software_Design_Principles_43992_46667.png Venkat_Subramaniam_-_Core_Software_Design_Principles_46668_48023.png Venkat_Subramaniam_-_Core_Software_Design_Principles_48024_48095.png Venkat_Subramaniam_-_Core_Software_Design_Principles_48096_48551.png Venkat_Subramaniam_-_Core_Software_Design_Principles_48552_54575.png Venkat_Subramaniam_-_Core_Software_Design_Principles_54576_55655.png Venkat_Subramaniam_-_Core_Software_Design_Principles_55656_55727.png Venkat_Subramaniam_-_Core_Software_Design_Principles_55728_55799.png Venkat_Subramaniam_-_Core_Software_Design_Principles_55800_56591.png Venkat_Subramaniam_-_Core_Software_Design_Principles_56592_56663.png Venkat_Subramaniam_-_Core_Software_Design_Principles_56664_56747.png Venkat_Subramaniam_-_Core_Software_Design_Principles_56748_56927.png Venkat_Subramaniam_-_Core_Software_Design_Principles_56928_57059.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57060_57119.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57120_57167.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57168_57239.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57240_57287.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57288_57359.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57360_57815.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57816_57923.png Venkat_Subramaniam_-_Core_Software_Design_Principles_57924_58115.png Venkat_Subramaniam_-_Core_Software_Design_Principles_58116_58175.png Venkat_Subramaniam_-_Core_Software_Design_Principles_58176_58235.png Venkat_Subramaniam_-_Core_Software_Design_Principles_58236_59111.png Venkat_Subramaniam_-_Core_Software_Design_Principles_59112_65639.png Venkat_Subramaniam_-_Core_Software_Design_Principles_65640_65951.png Venkat_Subramaniam_-_Core_Software_Design_Principles_65952_66239.png Venkat_Subramaniam_-_Core_Software_Design_Principles_66240_66671.png Venkat_Subramaniam_-_Core_Software_Design_Principles_66672_67199.png Venkat_Subramaniam_-_Core_Software_Design_Principles_67200_68471.png Venkat_Subramaniam_-_Core_Software_Design_Principles_68472_72743.png Venkat_Subramaniam_-_Core_Software_Design_Principles_72744_74831.png Venkat_Subramaniam_-_Core_Software_Design_Principles_74832_75263.png Venkat_Subramaniam_-_Core_Software_Design_Principles_75264_77003.png Venkat_Subramaniam_-_Core_Software_Design_Principles_77004_77063.png Venkat_Subramaniam_-_Core_Software_Design_Principles_77064_79511.png Venkat_Subramaniam_-_Core_Software_Design_Principles_79512_79859.png Venkat_Subramaniam_-_Core_Software_Design_Principles_79860_79991.png Venkat_Subramaniam_-_Core_Software_Design_Principles_79992_80039.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80040_80147.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80148_80255.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80256_80471.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80472_80531.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80532_80579.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80580_80723.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80724_80891.png Venkat_Subramaniam_-_Core_Software_Design_Principles_80892_81371.png Venkat_Subramaniam_-_Core_Software_Design_Principles_81372_84167.png Venkat_Subramaniam_-_Core_Software_Design_Principles_84168_84875.png Venkat_Subramaniam_-_Core_Software_Design_Principles_84876_86699.png Venkat_Subramaniam_-_Core_Software_Design_Principles_86700_86771.png Venkat_Subramaniam_-_Core_Software_Design_Principles_86772_86819.png Venkat_Subramaniam_-_Core_Software_Design_Principles_86820_94571.png Venkat_Subramaniam_-_Core_Software_Design_Principles_94572_95889.png
All right. Let's get started. Welcome to the session on course of the design principles. My name is Venkat Subramanya. We're going to talk about a few design principles here and how it has an impact on it. I want to talk a little bit about where that has helped me in the past. So I'll talk about some of those as well. And I'll try to keep this as possible without getting too much into code. I'll probably give you kind of one example just to illustrate a few points, maybe a few others as we go through. Best time to ask a question or make a comment is when you have it. So please don't wait till the end. Anytime is a great time. If you do want to participate, ask a question. Just say a question so you draw my attention and I'll be more than happy to listen to you. So let's get started. We're going to talk about some core design principles. And I have to say that these principles have helped me enormously over the past several years. In fact, I have to say that these principles that helped me a lot more than design patterns themselves. One of the gripes I have about design patterns is when people look at a pattern, if they only look at a pattern to use it, then it may not be the right pattern after all to use. But if they think about what's the force behind using a pattern, if they look beyond that and look at design principles, it often leads to a better reason to use a certain pattern or even a practice. So I value the design principles enormously compared to anything else. Where do we really see them? I feel that the design principles are very effective when we use them in a tactical design mode. I often use this in test-driven development. There are two things I do. One is when we are doing test-driven development, we can say, well, we want to design this, what principle may we apply here? Certain times we look at principles to apply, certain times we look at principles not to violate. The other benefit I've had with this is, in teams where I work closely with them, we often use these principles as a vocabulary. For example, we would be looking at a piece of code on our design and somebody would say, yeah, but we cannot do that because if you do, we will be violating the OCP or violating the dry principle. So we use these kinds of terms to communicate between each other. So this is a nice vocabulary to build for communicating a certain intent as well. But why should we really use them? The reason I would use them is the principles are a set of practices or things that help us to create better quality software. And I found them to be fairly effective if applied in the right way to the right degree. But of course, like anything else, we could also overuse something. And when we try to use a principle when it doesn't make any sense, it could lead to unnecessary complexity. So we have to be very careful about them. And like I said, I've really seen this to be very effective in test-driven development, tactical design and things like that. In evolutionary design as well, I've seen this to be very effective. So I'm going to talk about some principles that I consider as a very set of core principles. You probably have heard the term solid principle. Well, solid principles are part of this, but I don't really like the word solid as much because I don't want to say those are the principles I want to focus on. There are a few principles that are outside of solid that seem to help as well. So put them in a sequence where I find the most merit or value in them. So let's get started with one principle here to begin with, which is called the dry principle. So the dry principle stands for don't repeat yourself. So the idea behind the dry principle, this was originally written in the book called The Pragmatic Programmers. And this is a publishing company now, but they originally started by writing this fantastic book called The Pragmatic Programmers. And Dave Thomas and Andy Hunt wrote this book. And in that book, they talk about the dry principle. And so what is the dry principle really state? And dry principle says every knowledge in a system must have a single authoritative representation. So the idea really is representation. So the idea really is that every knowledge in the system must have a single authoritative, in fact, they even add and one more word here unambiguous. So the idea really is we want to create, when we create an application, we have to ask where is this piece of knowledge really kept? And duplicating this knowledge in multiple places is really a disservice we do for ourselves. Let's think of a few examples of this. A years ago, I was building an application and we had a problem with the system. We couldn't implement a certain logic in a certain place in the system. So what we did was, what I did was that I decided to, I was overly eager to solve this. So in several parts of the UI, I had implemented a logic to perform a certain checking. A few weeks went by and the problem was solved in a different area. And now I had to remove the code I put in for this particular logic. Well, unfortunately, there were several places where I have to remove it, more work to remove, and you forget in some places, and then it takes time to go back and fix it. So I learned my lesson the hard way doing this. So when it comes to dry principle, we want to ensure that we have the knowledge in one single place. Let's think about this with a little example here. I'm going to just throw one example at you. And we could use different languages and tools for this, but my idea is to illustrate the benefit of this concept. I'm looking at a little framework here called Grails, which is written on Groovy and Java and Spring and all those good stuff, but you can do this in multiple different tools and framework. The idea is to get a sense of what this is. The point is we need to be able to do this in our own application if they can do it here. So I've got a team with a name and a contact email, as you can see here. So I want to quickly try out an example. So I'm going to say here in this case, I'm going to create a new team. So this is a new, as you can see, and I'm going to say team one is the name of the team. And I'm going to say team one at example.com is the email address. So notice this is a create, and I'm going to go ahead and create it. So likewise, I'm going to create another team. I could say team two at example.com here. And once I create team two, I could say team two here, and you can see that the teams are being created. And I can look at a list of teams. We could also do an edit of a team. So for example, I could click on edit, and I can change the information of the edit page, like in the create page. So it looks like there are two different pages, one for create, one for edit. Well, that's great so far. I'm going to kill this application. And the data is in memory. So when I restart it, it will go away. But that's really the intention of what I wanted to show you here. So what I want to do is I want to enforce a rule. And the rule I want to enforce is that no two teams can have exactly the same name. Well, how do I enforce that rule? I got to enforce this rule in the create page. Because when you're creating a team, you want to make sure that team name for the new team is not the same as any other team out there. You also have to make sure this doesn't happen in the edit page. Because if you're changing the name of an existing team, you don't want to give a name of another team that already exists. So if I naively do this, this would end up duplicating the effort in two different places. Drive principle is not about duplication of code. It is actually about duplication of effort. The reason I say this will become clear in the next example as we will see it in a minute. So what I want to do here is I'm in the model here. And I'm going to say name and I'm going to say unique is true. That's all I've said here that the name is unique. So having done this, I go back to the application. I restart it. Like I said, I'm having in-memory data. It's going to blow it away. So I'm going to go ahead and create a new team right now. And in this case, I'm going to go ahead and ask him to, I'm waiting for the server to start up still. So I'm going to ask him to create a new team for us to use in this case. So when I do, I'm going to go to the create page for us to take a look at what this shows. So I go to the create page. And on the create page, I'm going to say team one over here. And I'm going to say that the contact is team one also. So click on create right now. So that worked. Now we're going to new team again. This time I created team one one more time. And I'm going to say team one also click on create. And it tells me I cannot do this. So it tells me that the property has to be unique and you cannot do this. So I'm going to change it to team two right now. And I'm going to change this one to team two, click on create, it finished it. Now I go to that list of teams, I go back to team two. Notice this is the edit page, not the create page. But in the edit page, I change it back to team one, and I click on update, it catches me and says you cannot do this. The point really is, it is a simple activity, but that single authoritative knowledge was captured here in this domain object. And I don't have to go about modifying this in multiple places in one place I can express it. Well, we could argue, are we really looking at duplication of code right now? Well, not really, it is duplication of effort as well. Like what? Let's go to the contact email for a minute. If I go back to the application, I can remove everything from here in the email, and I can click on update. And in this case, of course, it was able to take the change to the email, which is really wrong. So let's give it a try one more time and see how this is going to shape up. Now notice what I'm going to do. I'm going back to exactly the same place. I'm going to say contact email. And I say that this email format is true. I want to emphasize that the email actually is in the right format. So all we did in this case is we added this one line. But let's think about it. Would you want verification on the front end? Or do you want validation on the back end? Which one would you like? Both I heard greedy people, right? Absolutely both. Why do we want it both? Because a front end validation is quicker. There are other benefits for front end validation. We want it on the front end. But you cannot live with the front end alone because the back end has to validate it too. Why? Because you could be sending data through other means than going through the browser. You want to make sure the validation happens on the server side. You say, wait a second. Usually the technology for client side is different from technology in the server side. So I got to write the code maybe in C sharp or Java or Groovy or whatever. I got to write that code on the server side. And of course I may have to write JavaScript on the client side. So that is really two different sets of code, isn't it? Well, not really. That is where the violation of the drive principle comes in. It is a different code because it's different language. But it is for the same reason. So it is a duplication of effort. Same way, you don't want to duplicate that effort for other means as well. How can we do that? So when I go back to the application now, I'm going to, I blew away the data again. But this time I go back to creating a new team now. And when I create the new team, notice what happens now. I say team one over here. And I'm going to say team one without anything. And right off the bat, you can see the error pop up. It tells me I cannot create the team right now. If you insist, it tells you please include, it's even polite as you can see, please include an ad symbol. And when you want to create this, and it gives that error as you can see right there. Now, clearly we see this is a client side validation in place. And there is also a service head validation also written for this. In other words, once again, looking at this single authoritative representation, the tool was able to create client side and server side details to take care of this. So that is an example of the drive principle. So what is the benefit of following the drive principle? It becomes easier to maintain the code. It reduces the cost of development. It makes it easier to modify and evolve the code. So I honor the drive principle a lot. Now, when you think of a drive principle, it reminds me of an experience. I was at a client side and one of the programmers said, oh, we tend to fix the same bugs every two months. I said, that's nasty. Does somebody actually put back the bugs back in the code? He said, no, the code is duplicated in so many places. We keep figuring out, discovering these places and we fix the bugs. I said, well, when you fix a bug, you do take a little bit of time to refactor the code, right? He thought for a minute and said, that would be a good idea, right? So I mean, what good is it if we don't fix that and refactor the code? That's going to spill through everywhere. So it is our responsibility to actively refactor the code and enforce the drive principle. So if there's one thing we can look at avoiding, it is about avoiding the duplication, not just duplication of code, but a duplication of effort as well. So when you look at code, ask yourselves, does this really honor the drive principle? Does this really take care of not violating this principle? That is something to think about. The second principle I quite heavily use is the Yagney principle. Sometimes people get very angry when I use the Yagney because they say, of course you need it. So I change it a little bit. It stands for you aren't going to need it. So it is a principle that says we really don't need it. But I change it a little bit just to kind of make a little bit of ease. I say you aren't going to need it yet. And that seems to ring a better bell to people than you aren't going to need it. They get very apprehensive. Well, oftentimes what I find people do is when they are designing a piece of code, they put in a lot of different features. They put error checking. They put extensibility in place. They look at data types and how extensible can it be? Oh, this has got to be a generic type. Whatever it is they think of, they put all of those in place. But my question often is, do you really need it? If we don't really need it, we need to postpone it until we know a little bit better. But oftentimes we hear people say, I'm not exactly sure what the functionality is, but I can still write the code. So it takes a bit of a discipline to say, we don't know what exactly this is, or we don't know if something is really needed. So we are going to postpone adding this to a later time. And the Yagney principle is a good principle to follow for that reason. Now, you aren't going to need it yet is a much better in my opinion because it says that it's not that you will never need it, but the fact that you may not need it right now helps you to postpone the decision until you know better about this. And then you can decide to use it or not. So it's not that you are condemned from using that, but let's postpone until we know better. And if we later on we find out we actually need it, we can absolutely implement it. Otherwise, we don't have to use it. One of the real problems here is this. Let's say for a minute, we've been implementing code, and let's say you implemented a piece of code. And two days later, I come over and say, we don't need that code, you're going to be pretty angry because you took the time to write it, and you're going to say, you better use it because I wrote it, right? But the code we did not write is the easiest code to throw away because, hey, I didn't really write it. Thanks for saying it. I can go do something else more meaningful right now. So that's a principle I really like using. So we don't really have to force ourselves to use this code. We can postpone it. The next principle I want to talk about is probably one of the most important principles, but it comes in different names. It's a single responsibility principle. A single responsibility principle says that every piece of code needs to have a single one purpose, one reason. This is also often called as cohesion. So cohesion is a property where things belonging together are together and things that are not belonging together are separate. Now let's think about cohesion. What does it really mean? Well, in real life, we can think about cohesion in several ways. I'll give you one example. When I was a child, I was the brat that really liked to come home from school, throw things and then run out to the street and play. That was a lot of fun. And I had a wonderful parents who tried to teach me values and they said, hey Venkat, when you come back home, you don't throw stuff and run away. You got to put things in place. Well, I used to have this cupboard and I would throw things into the cupboard and run away. It was fun when I had to do it, but any time I needed something from it was terrible because I would open it. If I pull a blue sock, the next sock I find will not be blue in color because it's obviously hidden somewhere else in it. So it was more effort to take things out. It was much easier to throw things in. It was a mess and my parents tried really hard. They kept telling me, don't do this. You got to keep things separate. You got to put your colored sock, all the light colors in one place, light colors, another one in this place and they tried to teach me all of this and that never worked. And you may look at me and say, well, it looks like you already turned out to be better. How did that happen? Well, I got married. A lot of things changed when that happens. So what my parents couldn't do my lovelies can do. So that's beauty of that is things are more organized and now my books are in the study. My clothes are in a different room and there is harmony and everything. You know where exactly things are. In fact, it's such wonderful that a couple of months ago, I was somewhere else in the world and I really wanted a reference from a book which is a very old book. I couldn't find the reference online and so much so that I could actually call my wife and say, would you do me a favor, go down to the bookshelf, the third book from the top row. I wanted to pull that out and look at this particular index and read it for me. So that kind of discipline eventually evolves and that is an example of cohesion. Like things are together and dislike things are apart and that really helps to find things easy and maintain them. We can do this a lot in the code. For example, classes. Don't put multiple classes in one file, for example. That's a rule we can follow. And when you write classes, you want the classes to be narrow and focused. One thing done one. What if your class is doing input-output-related operations plus database operations and dealing with some calculation, what's going to happen? If that is one class you have, let's say this is your class you have written and if this class does every single operation, well, the problem is that class is going to be very, very unstable. In other words, every single thing that changes in the system potentially could affect this one class you wrote because it does everything. On the other hand, you split this into smaller classes. You have one class that deals with input-output, another class that deals with calculation, a third class that deals with database, a fourth class that may deal with maybe a particular calculation. Now the chances are you may decide to change the calculation, you change one class, or even better, you can provide an alternate implementation of the calculation class and the other classes can vary with the factory or something to use one or the other. So the reason for a class to change becomes a lot less when every class focuses on a single principle and does one thing and one thing well. So we can look at single responsibly principle at the class level. But we can also look at single responsibly principle at the method level also. Let's think about this for a minute. A long method. So let's think about long methods. Who here thinks long methods are a good idea? Not a single person, right? Now why do we think long methods are not a good idea? Let's think about some of the reasons why long methods are a bad idea. So can you throw some reasons at me? Why long methods are bad? It's really hard to read, right? Hard to read, thank you. What else? Hard to test. What a wonderful way to think about it, right? How do you test this method? So readability. You look at this method, I remember one experience, a client called me up and said, hey, do a code review for us and help us with some problems we are having. So I started doing code review. And I started with this method. I read about 25 lines of method code. And after 25 lines, my thought was how much more do I have to read? So I started scrolling down. Then I started paging down. And then eventually I said that doesn't work. And I used the tool to find out the curly braces and find the difference in the number of lines of code, right? And that said there are 750 lines of code in that one function. Immediately I'm like where's the nearest coffee machine? I need some caffeine, right? It is frustrating when you see that code. Why? Because you are like, whoa, that's a lot of lines of code to read, to comprehend this one idea, how worse it can turn very quickly. And also imagine how do you test that method? How do you go through combination of the methods and the branches in the code? The permutation and combination through it is going to be so many that you cannot possibly write enough tests on that method to satisfy all the branches or it becomes extremely complex to be able to do it. So that is another problem with it. What else do we have? What was that? Oh yeah, wonderful. Hard to reuse. How do you reuse a monster? What you need is those 10 lines right in the middle. Well, but you cannot reuse the 10 lines because it's within the method. So what do you do? You take the 10 lines away from it and what do you do with it? You stick it into another long method, right? So as a result, it leads to duplication of code as well. So it's combination of both. It's hard to reuse and in turn it leads to duplication as well. Anything else we can think of? A little louder, please? Oh, hard to debug. So hard to debug. Well, that's actually not a problem, right? That's why you hire the interns, right? So you say go get it and the interns of course log through and they say this is what you guys do for a living. That makes it really hard. So hard to debug. What else? Is that it? Hard to maintain. Hard to modify. What else do we have? Anything more? Hard to what? Hard to remove. Yeah, hard to remove. Fails single response to be principle has what do you call it? Tight coupling often, right? More coupling in code. If a code is that big, chances are, miscellaneous company, right, is going to ask for other dependencies. So that's going to be really coupled and that makes it hard to remove as well and other problems that will come with it. So there are so many problems with long methods. But let me ask you this question. We already asked you this question, right? Who here thinks long methods are good and nobody raised the hand? My question is different. Who here has seen long methods? Look at that, right? Almost everybody in the room is raising the hand. This is called cognitive dissonance. We all know it is bad, but yet we see it. Does anybody know? You all know it is bad, but then why do we have long methods? Well, the sad story is this. Nobody in this room wants to write long methods because you all know it's bad. But the folks who believe it's good are at work right now, making those methods longer as we speak, right? That is the problem we have to deal with. So what do we do about long methods? So if there's one thing, just one thing we can teach people, if one thing we can do, and that is to tell people, please don't write long methods, there'll be so much improvement in our design. If we can do just one thing, don't write long methods. And why do we write long methods? I really don't know the answer for that. Why do we write it? That's like a very bad practice. Now, if we don't write long methods, what happens? The code becomes cohesive, a single responsibility. It becomes easier to understand, easier to maintain, and there are so many benefits in doing it. But the question is this, how long is long? So let's try to put a number on this. How long is long? Somebody said 25 lines of code. And immediately Ruby programmers said, what 25? We never write 25 lines of code. Seven lines it is. Well, the closure guide said seven lines, we don't write anything for seven lines, only three lines. There is no way to win this battle of number of lines of code. Well, here's another measure we could use. How long is long? I would say if you can see the entire, entire method in one window, right? But don't try to lower that font size. So you want to see the entire method in your window, okay, that may be a good measure. But there is a better way to think about it than either one of those. So what is a short method? A short method is not a method with fewer lines of code. That is a wrong way to look at it. Let's think about this a little differently. Remember that gentlemen or the programmer or person that we talked about at your work, and what does this person do? The person writes long methods every day. And you believe wrong methods are bad. You told this person several times the person doesn't want to listen to you. So I got a last-ditch effort to convince this person. So go to, go back to work on Monday. Don't say a word. Just sit down and start coding. This, this colleague of yours who writes long methods comes over to you and says, hey, how was your weekend? You could say your weekend was great by saying when, you know, something like went to the park on Saturday, you can say, and then you can say went to the movies on Sunday, right? So you could, you could say something like this, but don't do that. Instead, you say, oh, my weekend. Well, I'll tell you at 10 o'clock, I got into the car, turned it on, you know, back the car up stood at the stoplight for about seven seconds, turned right, went for another two kilometers. And then I turned left. Oh, there was a bird on the street as I was going through. And then I went two more, you know, feet, and then I had to turn right for more kilometers. Just keep going like this. After about 10 minutes or so, your colleague is in a panic mode and says, stop. Have you gone mad? You say, no, I'm not gone mad. I thought I will tell you how my weekend was like the way you write code, right? So the point is, we don't talk to people like that. How do we talk to people? We talk to people in these high level of concepts. I went to the park on Saturday and went to the movies on Sunday. Now your colleague may be interested in movies and may say, really, what movie did you go to? Notice your colleague did not ask you about the park. Or another colleague who we're talking to may be interested in a park and say, tell me what park did you go to? And maybe you say what park you went to and the colleague now says, really, is that park over here? Is it family friendly? I want to know more about it. So notice what's happening in the communication. We mention things in one level of abstraction at a time. So that is something very important to think about when writing methods. This principle is called the slap principle. Where the slap principle, no, don't do this, you call a colleague. The slap principle stands for single level of abstraction principle. So in other words, what should we do when we write methods? The method is short if the method is focusing on a single level of abstraction. So in other words, when you look at a method, a method should nicely compose itself and tell us what the method is really doing. So another name for this pattern is called the compose. So it's called a compose method pattern. And the idea really is the method nicely composes things at a single level of abstraction. And that is called a compose method pattern. So the idea of a compose method pattern is to compose things at a single level of abstraction. And then if you want more detail about that particular level of abstraction, you dive into that method and look at the details. So then what happens is the code becomes very easy to read and understand what's going on. Now also this becomes easy for maintenance and debugging later on as well. When you are trying to get into a code, if you have 750 lines of code in front of you versus if you have about four lines of code where those lines of code are in these levels different of abstraction, there are some clear benefits here. The first benefit is if you had 750 lines of code, chances are that it's all jumbled up and the logic goes back and forth. You do a little bit of this, a little bit of something else, a little bit of something else, it becomes hard to understand and maintain. But if you have those four lines of code at one level of abstraction, everything to do with one abstraction will be inside that method. Everything related to the second abstraction will be inside that method. So that's more cohesive and focused on single responsibility as well. And then when it comes to debugging the code or understanding it or maintaining it, we take these high level concepts in our mind and say, oh, you are doing XYZ access over here, got it. If I really want to dig in and look at more details about it, I can step into it, but I don't need to know that detail right now. I can skim over to the next one. So as human beings, we retain these chunks of concepts in our mind and not these little turns and twists that we make all the time. So that's a better way to write code. So if there's one thing we can try to do in our field, that should be really removing long methods and writing things that are focused on a single level of abstraction as much as we can. So that is something to think about how we can achieve this. The next principle I want to talk about here is a principle that is really hot for me because I don't tend to think about it that much, but I think it's a very important principle. And the times I've applied this, it's come as a surprise to me that I didn't quite pay attention to it. So this is called the tell don't ask principle. The tell don't ask principle says that you want to tell a piece of code to do stuff rather than asking the piece of code for some information and then going back and doing it. We see this principle being violated in so many places in programming and we just don't think about it that way. Let me start with a very simple example for a minute. Let's say we have a collection of books. So I have books on my hand and let's say for a very simple thing, I want to go through my library of books and I want to print information about each of these books. So how would I write the code in a more familiar style of coding? I would say far int i equal to zero i less than books.size or count whatever you want to use i plus plus and then I would write some code for processing that. Now we have done this so many times we don't stop to think about it, but if you really think about it, this is a nice example of the violation of tell don't ask principle. What are we doing in the first case? We are going to this book and saying hey books give me your count and it simply says you want my count I don't know why but here you go I've got 250 books and now you say all right I start counting from zero to one to two to three until the value is less than 250. You are taking the effort to count through and then what are you going to do? One more time you're going to come down here and say books and then ask for element at that location so every step of the way you're asking for low level details from it and then you are making action. But how do we really do stuff in the real world? Imagine a lot of times how do you communicate with somebody? If somebody comes to you and says hey what are you doing tomorrow your response usually is what do you want? Generally that's what you ask them because you want to know the intention because if somebody you want to really help you may say you know what it doesn't matter what I'm doing I will come and spend the time with you. If somebody you don't want to you will create a new engagement for tomorrow so it depends on that so your context really matters. Let's think about how you would do this differently. Now I'm going to say books. For each and I'm going to specify what to do for each of the elements. Now look at the code on line number nine compared to the loop we saw a minute ago. This is an example of tell don't ask. You are telling the books collection, hey books collection for each of your elements do whatever right? So whatever is your intention whatever you want to do for each of the books but you are being very direct about this and saying hey book for each of the elements please do this. I don't want to be in the business of asking you how many you have and stuff like that. Similarly by writing the code in a more for declarative style you can promote the tell don't ask principle even further rather than the way that we've been programming where we keep asking little different information. Similarly when we design our classes rather than providing methods that are query methods and then providing methods that are methods that go affect the state of the object we should try to turn them into more methods that actually directly perform the task and give back a result. This will make benefit of two things. Become really averse of this methods that query and a method that take an action because you got to do two steps to talk to the object. Instead if you have one method that can take a bigger chunk of action to do there are two benefits you get. The first benefit is it's less work for you. You simply say do this and you forget about every other detail and the object can do it. The second benefit is it really makes it easier to evolve the code. If the action the object has to do changes tomorrow that changes in one place instead of oh we change the action over here everywhere you use the code you got to change the action consistently as well you don't have to endure that kind of pain it becomes more polymorphic rather than querying. In other words anytime you query and ask for detail and take action you are really failing to use polymorphism anytime you tell the object to do things you are using more polymorphism because an implementation of that tell method can do something little differently if it makes sense which is really hard to achieve if you're going to do things on your own side so this is a lot more beneficial so this is something to stop and think about can we really benefit from tell don't ask. Like I said I'm having trouble with this principle a lot because it is very powerful but I got to think through the code a little bit to say oh wait a minute I'm actually violating that principle here let me rearrange the code refactor it and a lot of times when I refactor the code it really becomes a lot better to understand and maintain as well. The next three principles I'm going to talk about are one of my most favorite principles the next one is called the open closed principle the open closed principle it says that a software module must be open for extension but closed from modification let me write that down it says that Burton Meyer created this principle and open open a closed principle now this sounds a little weird it says a software module so a software module must be open for extension but closed for modification so what does that mean hey how could it be open for extension and closed for modification in other words you want a software module to be able to do something more than what it did before but without having to actually change it so to understand this particular principle let's try to take a little example and work through it and see how we can actually benefit from this I'm going to close this out we don't need this anymore so I'm going to talk about this principle and I'm going to create a little example to play with it but but let's say how we're going to actually do this so I'm going to create a little example here and play with it let's see how we're going to actually be able to do that so I'm going to bring up just an example here to see how we can actually do it I'm going to start a little tool here so give me a second so I'm bringing up the wonderful command prompt I'm going to start a little code let me go to where the code is reciting on my machine and once I get there I will do a little code in C sharp here to give you an example of what this actually may mean so let's get going with a little example let's say we have where can I create it yeah this is a good place to create it so let's say we have a little a class that I want to entertain how this could become really problematic so let's go to a code and and play with it so let's say I want to create an extensible code but let me start with something simple and make it a bit extensible I'm going to increase the font in just a second here so let's get to a class I want to work with let's say I'm going to put all the classes here in one file just so I don't have to be dealing with multiple files here so so bear with me for a second but we'll get through this real quick so I have a little code that I want to make sure it's running great so I want to start with a class let's say a class called car and the car doesn't have a whole lot yet but I'm going to put a few things into it very quickly so let's say I want to create a car object so car car one equals new car but what are the things I want the car to have I'm going to say the year is 2014 I want to say what year it is I want to give it a new engine as a parameter so I'm going to give it a new engine as well I will give you this example halfway and I won't give you the full example but I will prod you to go look at few other things after this so I'm going to create a constructor here so it's going to be let's say int the year and engine I'm going to create let's say the engine so I'm going to provide these two guys over here as a parameter and let's say year is a property we'll say this is going to be the year and I'm going to say engine is a property and it's going to be the engine as well well that's great but for this to work I need those two types right the engine of course we need to create but let's also do public let's say override and I'm going to say string and two string and what do I want to do in the two string well I want to simply return let's say over here a string dot format and I'm going to simply return let's say the year first of all so I'm going to say the year and I also want to display the engine itself so let's go ahead and say year and engine so year is a property and then engine is a property too well so far so good right nothing really spectacular so far what about the engine and the year so we'll say over here a public year I'm going to say a get and a set available to it and I'm also going to say in this case we also have an engine which is going to also have a get and a set so that's good so far now for this to work we need of course a class engine our engine is not going to have a whole lot right now I'm going to leave it empty just for a few minutes so now that we have all the things we need for this to work let's go ahead and output our car one just to get a feel for what it contains oh wait a minute it contains a problem in line number 20 I want to do a format over here this is going to be what did I do wrong here oh return of course return I've got a conflict with compilers these days I program in quite a few languages that don't require a return and the compiler says you're missing a return and I argue with the compiler I'm not missing it really so it's really becomes a problem so yes I need to put a return you will notice me skip that quite a bit and of course it's still complaining on line number oh format is uppercase fs in it so that's a format of course that it wants so yep that's an engine that's 2014 now let's look at this code for a second it looks like a benign piece of code it seems to work just fine and let's make a copy of this so what I want to do here is I want to say car car two equals new car and I'm going to say over here car one so I'm making a car copy using a copy of a car I already have well if you look at this code example it looks like all I want to do is I make a copy now will that's code work let's go ahead and try that real quick and you would notice that it complains to me there is no copy constructor well C sharp doesn't provide a copy constructor automatically well why didn't they provide it well because they provide didn't provide it because people have been burned by c++ providing a copy constructor and that was evil and they said we know exactly how to fix the problem no copy constructor for you right so that is one way to fix the problem that's called running away from the problem so they did that now I'm going to write a copy constructor so what am I going to do in my copy constructor I'm going to say car other and in this case of course I'm going to say ear equals other dot ear and what if I say engine equals other dot engine do you think that's a good idea no because I would be the shallow copy and two cars would end up shedding the engine that's a disaster that's called a collision right so what do you want to do you want to say this is going to be new engine and then of course when you do an engine here you will have to have the same method in the engine as well it's going to complain about that so we got to go back to the engine class and now I'm going to say public engine which doesn't do anything and of course I've got to also provide public engine which takes the other engine and that doesn't do anything either but the compiler is going to be happy with that so we have done with this and again it looks like a simple solution so far but let's say we go a little further with this and we're going to extend it now so what I'm going to do quietly is I'm going to come and create a class called turbo engine and in the turbo engine inherits from engine so I create a constructor for the turbo engine I also create here a constructor for the turbo engine which is the copy constructor so I say other and over here what am I going to do I'm going to say that I'm going to have a base so this is going to be base and then I'm going to send nothing well actually I'm going to send the other to it so we created a turbo engine my question to you is is it legal to change this code to send a turbo engine rather than send an engine what do you think thumbs up yes or no is it legal will the compiler be happy absolutely right the compiler is not going to tell you anything it's going to be happy but when you run the code what happens you feel you're being cheated isn't it because the first car has a turbo engine the second car has a regular engine it did not make a right copy well how do we fix it well I got a way to fix it I'm going to go back to the car constructor copy constructor I'm going to say if other dot engine is a turbo engine I'm going to go ahead and create this as an engine equals new turbo engine and if it is not I'm going to say else I'm going to say this is going to be an engine and ask it to create this engine one way or the other so in this particular case let's see line number 29 is not happy with something well of course in this case you have to cast this to turbo engine because you know the other car is a turbo engine and you got to do a bit of a casting right so what do you think good or bad I see thumbs down you guys need to understand you gotta look at the positive side this is good because this gives you job security right of course we don't want the job eventually right yeah I agree with you this sucks so what's wrong with this it fails the open closed principle how does it fail the open closed principle because every time you add a new type of engine you gotta come and fix this code you gotta use eventually this will convert to a switch statement right and then you're going to switch for types and do it well this is evil but have you ever seen a code where somebody uses a is to find out what kind of widget it is or something and make a decision have you ever seen that it kind of sneaks that into the code isn't it and then it's sitting there fine until two months later oh you know what we got to go back and change that code a little bit further and then you write a little bit of code and that works and for three months later you got a little bit of code that's called scotch tape driven development right you put a little tape on it it sticks for a while well that becomes expensive why because everywhere you have to deal with the type you got to keep changing that code in different places that's a violation of open closed principle the is that you see here is called the runtime type identification and for a very long time language like c++ resisted introducing this for the same fear that the code won't be extensible if we do it but language like c-shop kind of generously provided it but we have to have the wisdom of not using it in 95% of cases so what do we do to fix it well one way to fix this problem is you would say well let's make it polymorphic and the way to make it polymorphic is you would simply say here engine equals other dot engine dot something like clone and you can ask it to be cloned for you so you could use a clone to do this and what would this do it'll perform the cloning but because the method clone is polymorphic you will if this was an engine you will get a copy of an engine if this was a turbo engine you will get a copy of turbo engine because clone can do it well this only opens the door just a little bit because you will soon end with one other problem this code will seem like it's working and you would use clone but the problem is this you would say what is good about clone well clone is a special method implemented in c-sharp you can use clone and it can make a copy of the object wonderfully but unfortunately though if you go back to this code and if you make one of the properties read only properties that you cannot modify but you want that property to be unique for example let's say I create an id int id and I want to make this property as read only so if I make a property as read only property what's going to happen well it turns out read only properties can be modified in the point of definition they can also be modified in the constructor but can you modify the read only properties in the clone method not really right so clones are not permitted to modify read only properties so what's going to happen you're going to get a compilation error very quickly because a clone cannot set this property which is read only and you're going to sit there and scratch your head don't it clone doesn't work either so a combination of clone and copy constructor would actually be needed to solve this problem the problem is not with the clone the problem is the way clone is implemented in c-sharp and in java because they all kind of went through the same path and fell off the cliff so the point really is what you do is you write your own clone method but in your clone method you call your copy constructor and you make your copy constructor a protected method so people don't directly call it so the eventual solution to this problem is you will call a clone a clone will turn on and call the copy constructor let that create the object setting the read only fields and then the clone can return the object to you and that would be the eventual solution for it but in a sense what we need to do is we need to think about the extensibility of the class and again like I mentioned earlier you want to think about this not when you design first but when you evolve the code so the minute you introduce a turbo engine that's when you want to solve this problem not until then you don't want to do premature solutions for these problems so open close principle open closed principle is a very useful principle to think about oftentimes when I work with programmers I would be doing code reviews for them or we would be sitting and doing design together and we would suggest oh how about doing this and eventually we would say oh that's a violation of open close principle we saw one example here in the copy method but open close principle violation happens in several other places sometimes we don't think about it but imagine you are dealing with the content of a file you're reading and you are doing some processing based on the content of the file and you are making a decision if this is the content do this if this is the content you do this that could be a violation of open close principle also because if that rule changes tomorrow you got to come and change that code and you got to ask yourself is there a way to extract this out so we don't have to continue to modify the code with a little bit of an effort and refactoring we can make the code extensible without failing the open close principle quite nicely the next principle I want to talk about here is called the Liskov substitution principle what does the Liskov substitution principle say the Liskov substitution principle says essentially if I have to nail it down to simple words Liskov's Liskov's substitution so substitution principle says that use inheritance only when you mean substitutability so what does that really mean it really says that inheritance is one of the most abused concepts in programming we use inheritance way too loosely than we should be so let's say we have a class so we have a class a and we also have a class let's say have a class called b so my question is should I inherit b from a so the way I look at this is inherit b from a only if anywhere an instance of instance of a can be used then so in other words inherit b from a only if anywhere an instance of a is used is used an instance of b can also be used so the substitutability is extremely important to think about can I use an instance of b anywhere an instance of a is used then the answer is use inheritance assuming b has been designed to comply with the behavior in that regard external behavior of b must be compatible right so compatible with external behavior of a this is a huge burden we take on our hands if we use inheritance if you are using inheritance for class reusability inheritance is a wrong tool so if your intention merely was was to use the implementation of a in the implementation of b then use delegation instead of inheritance so how do we see examples of this I'm going to give you one example of this which is pretty clear out there class vector now what does a class vector really do we can use a vector to add stuff remove stuff from anywhere right anywhere in the collection so that is what a vector can do for us now what if I create a class stack well what is a stack a stack is a basically a lifeful right last in first out that is the intention of a stack is to really provide a last in first out now imagine I come along and I tell you I got a bright idea I'm going to extend a stack from a vector what do you think of this idea good idea or bad idea bad idea why is it a bad idea let's think about this for a minute let's imagine for a second you are writing a piece of code that uses a vector and what does this code do it takes a vector deals with a vector as he's supposed to do with the vector he has a code that accepts a vector and he sends the vector to this particular gentleman's code and life seems to be fine so far well I come along I take a stack on my hand and I say hey you stack you are inheriting from a vector no worries because it's inherent from a vector I can use the stack anywhere a vector is being used and I send it to his function he takes the stack but he really doesn't care it's a stack he says hello vector come on in and what does he do he takes the vector and sends it to his code well his code says I got a vector on my hand and he inserts in the middle and removes from the middle and then I get back the stack on my hand and say hey stack how did it go and the stack says I feel violated right so it's been really poked and punctured in different places and he says don't send me back to him anymore right I don't like him right so the point really is this was a mistreating of an object violating its invariant and what is the invariant of the object that you should only do a life oh remove from the top and and add to the top itself and that clearly got violated in fact you would be surprised this is such a violation you would say you shouldn't do it but if you go back and look at google for or look for the stack class in the JDK java stack actually inherits from vector which is not a bright idea so this can be in different other places for example you can see evidence of this in different languages suppose I have a class let's say b uh let's call it as derived and the derived class inherits from let's say base class now in the derived class I'm going to say public something foo I'm going to add a function here called foo and I'm going to override this function so I'm going to say override like this now in C sharp java and other languages there are some rules if the base class function let's say let's go ahead and say this is a base class so I have this class base and the base class let's say has this method called foo which is public let's also say this has got a method let's say f which is oh let's call it as protected now in the case of java you can either make foo uh public or you can that's pretty much you can do right you cannot make it any more restrictive in the case of java you can take f the method f and you could actually say that method f is protected over here and of course in java you won't write override like this but nevertheless the point taken here and but if you want to you can make this public also but you cannot make make this private so java doesn't allow you to restrict it more than what the base allows in C sharp you cannot change it at all right public has to be public protected as we protected why why do they do this again for the same reason you don't want the derived class to restrict more than what the base class provides for the sake of substitutability that is very very important so the idea really is that it emphasizes some of these rules for you that falls into list of substitution principle that's where it comes from the last one i want to talk about is dependency inversion principle and i'm going to talk about this with the non-coding example i'll talk about my first experience my first visit to norway this was back in 2001 and i was excited to come to this lovely country but as you do when you come to a new place you kind of get to know about a few different things so i went to the hotel the first day i was my first visit brought to stavanger i was there in the hotel and i'm a very serious coffee drinker and i looked around there was no coffee machine in the room so i was a bit frustrated i went to the hotel staff and said there's no coffee machine in the room and they were kind enough to say okay you can borrow this coffee maker it can make bad coffee for you is it okay with you and i'm like i was happy well a few hours went by i was getting ready for bed and i looked around the room and i found something strange there was no clock in the room so i said what's the problem with these people they don't give you anything that is useful and i went back to the reservation or the front desk and said and and i went there and the lady said what is it now what do you want i said there's no clock in the room and she said yes we don't give you clocks and i said well this is going to be a problem and she said why is there a problem i said well if you don't give me a clock how do i wake up in the morning and remember this was 2001 before the days of cell phone and all those good stuff right and i and then she kind of looked a little bit confused and said i don't get it why would you need a clock to wake up and i thought for a minute and said well what else would you need and she said do you mean you need an alarm to wake up and i was getting angry because she's i thought she was getting technical on me and i said okay fine i need an alarm but in this case she was right but you never admit she's right so she said you need an alarm i said you know what you are right i've got a clock by my bedside it makes such a one you know lousy noise i cannot sleep for the rest of the day that's why i said a clock but you're right i need an alarm and she said well you don't need a clock then like no i don't need a clock i need an alarm well notice what happened here my coupling was wrong i was coupled coupled to a clock but i don't need a clock i really need an alarm i learned this lesson in norway so and then she said well there's an alarm in your room i said really this is exciting i didn't see it she said did you turn on the tv i said no i don't watch tv she said this week you will it's like okay so i went back to my room turned on the tv it said dear venkat subraman welcome to our hotel i'm like why i've been here for six hours i didn't realize that they even have my name on the tv and then i kind of looked at it it said you can set the alarm i'm a guy who believes in tdd what did i do i set the alarm for two minutes from now turn it off and wait for two minutes and two minutes later it goes on i was like hey this is wonderful this worked like an alarm i should watch tv from time to time and i put it again right you want to make sure it really works two minutes later and guess what it turned on but that was a bit strange because it turned on back only to cnn i would switch channels i would turn it off it would turn on to cnn anyway i kind of thought that was funny and i left it i'm a guy who wakes pretty early in the morning so i set up the clock to about four in the morning and i went to bed it was a very peaceful sleep i don't get jet lags by the way because i traveled so much so i was sleeping through the night and now i'm in a dark room honestly i don't know where i am right and suddenly at four in the morning i hear this loud noise in the room i jump out of my bed because there's somebody in my room i forgot about this alarm i said and i'm in panic mode i look around the tv is on and the volume keeps increasing i'm like where's the remote right lower the volume and look at the tv and i saw the most scariest thing there was this guy in suspenders with this dark glass and said hello this is larry king life can you imagine waking up to larry king live in the morning i had to go to therapy when i went back to back home right anyway now that i was awake and scared by larry king i started thinking what a great idea now i asked for a clock she said i don't have it but i could use a tv what does the tv do it supports an alarm interface i'm of course i'm i'm pretty smart i said you know what i'm not going to deal with larry king for the entire week so end of that by the end of the week i had a program written on my machine that would wake up at four o'clock and blare the computer so a computer could be an alarm these days my smartphone could be an alarm right or when i was growing up i had the best alarm one can have my grandma i would tell my grandma grandma i've got an exam could you please wake me at four o'clock and she would promptly wake me up at two o'clock and say honey don't worry about it i'm awake i'll wake you but four so the point really is i can have different implementations of this and this is an example of dependency inversion principle if you coupled directly to an implementation like clock then it doesn't give you the flexibility but rather than depending on a clock you think about what part of clock i really care about and it turns out i didn't care about a clock i really wanted an alarm so i depend on the alarm and as a result i was able to get multiple different implementation this provides a better extensibility i've used dip probably as one of the most widely used principle i often look for violation of ocp but really use of dip if you have ever used mocking for example you use dip pretty extensively you really depend on an abstraction and then you can substitute with mock objects also very easily so this is one of my favorite principles that i've used quite extensively as well so to summarize we looked at a few principles design principles here i find these principles are extremely valuable even more valuable than design patterns but i find them very useful when i apply them in the tactical design during test event development is when i get the most leverage of these i really hope you found these useful thank you
about some core design principles. And I have to they look beyond that and look at design help us to create better quality software. And I There are a few principles that are outside of take a little bit of time to refactor the code, that's a lot of lines of code to read, to little bit of an effort and refactoring we can make the code extensible without failing the open this and this is an example of dependency