So now let's start with an example which is the duck simulation game. In this game, you're going to simulate the behavior of different dots within the game. And within a game, we're going to utilize inheritance because we have dots and then we have different types of dots within the game. For example, Malik, doc and redhead duck. And that is an abstract class. Then all the ducks, they can crack and swim. Then we're going to implement these operations under the super type. And because each duck is going to have a different look, then we're going to implement display under the subtypes. But now prepare for the big innovation. Now dots can fly, then we have to add another fly operation under the super type. And then we're going to implement this fly operation under the super type. But then something goes wrong because later on we have to add another type of duck, which is rubber ducks. And you know that rubber duck, they cannot fly. And if we implement the operation fly under the super type, It will be utilized by all these subtypes. But now, since rubber duck does not crack, then we have to override this quack operation to squeak instead of doing cracking. And also since rubber duck does not fly, we also have to override the fly method to do nothing because rubber duck does not fly. But then later on we plan to also include another type of duck, which is wooden decoy ducks. Then we know that wooden decoy duck does not quack and does not fly. So we have to override crack to do nothing and also fly to do nothing. So initially joe thought that it would be great to use inheritance for the purpose of re use. But eventually it has not turned out so well because we have different types of ducks and then they have different behavior. And it becomes difficult to maintain if we simply use inheritance to implement ducks and different types of ducts. So now think about what are the disadvantage of using inheritance to provide that behavior? How about a code is duplicated across the classes. Yes or no, no, because we only have to define for example, fly in the super type ones, then it's going to be used by all these subtypes. So we don't have to duplicate across the sub classes. How about runtime behavior changes are difficult. Yes right. Because during the game, if we want to change for example, rubber duck to quack instead of squeak, then it's going to be difficult. We have to because we had coke the behavior under the subtype. We can make ducks dance. So this one is true. How about we can make duck stance. We can actually make ducks dance by including another operation called dance under the super time. How about how to gain knowledge of all the ducks behavior. This one is yes. Right. Because in our example, in order to see that rubber duck cannot quack is going to squeak instead and also rubber ducts cannot fly. We have to actually go into the subtype and take a look at the source code and double check those operations and see that they are overridden by the operations that we defined under the subtype. So it's difficult to gain knowledge about all the ducks. How about ducks can fly in quack at the same time. Ducks can fly in crack at the same time because we can simply call those two operations at the same time. Global changes can unintentionally affect other ducts. This one is yes. Right. Because if you change something in the super type, it's going to affect all the subtypes. How about if we implement the ducks behavior using an interface? So we have an interface called flyable and also have an interface called trackable. And we have the operation fly and the operation crack and they are abstract operations. That means we're going to implement this operations under the actual implementation. Is this a good design? No, because the fly operation that we have under mullah duck and the fly operation that we have under Redhead duck, they are exactly the same. That means we're going to have duplicated code under the implementation for melody and redhead duck. So it's not a good idea. And the reason is that we're going to have duplicated code. So how to come up with a better design. Now we're going to utilize a design principle which is we're going to identify the expects of your application that vary and separate them from what stays the same. So what we're going to do is that we're going to take what varies and encapsulate it so that it won't affect the rest of your code. So what are we going to achieve if we utilize this design principle? Eventually we're going to get fewer unintended consequences from code changes and also more flexibility in your systems. So now let's go back to the duck simulation game. What varies are actually the flying behaviors and cracking behaviors. So we're going to pull them out and then put them somewhere else. So now the duck classes still the super class of orthodox. But now we're going to pull out the flying behavior and cracking behavior and then put them somewhere else. And now flying and quicken behavior. Each get their own set of classes and various behavior implementations are going to live here within the flying behaviors and corrected behaviors. Another design principle that we can utilize in the duck simulation game is this one. We try to program to an interface but not an implementation. So by doing it this way, the duck classes will need to know any of the implementation details of their behaviors. So what do we mean by program to an interface but not an implementation. Now let's take a look at an example. Now let's say we have the super type animal and then we have the concrete implementations for example, duck and cat then programming to an implementation to a particular implementation. Would mean that we're going to initialize the duck as a duck and then we're going to make the duck bark. Okay. This means that we're going to hot coat the variable D as a duck. And it's not flexible because later on, if we want to change the duck into a cat, for example, it's not possible. So that's why it's better to program to an interface or to the super tight. That means we're going to create an animal and then we're going to initialize the animal as a duck and then we're going to call the animal to make sound. And this is a better way to define an animal because later on in the game we can change the animal into another type, for example a cat. And rather than hard coding the subtype into the code, we should assign the concrete implementation object at runtime. That means we can create an animal and then we can use an operation to create the animal. For example, if we want the animal to be a duck, then this operation will return a dog. If we want the animal to be a cat, then this operation will return a cat and then assign a cat to this variable. And then eventually we can call the animal to make sound. And by doing this, we achieve more flexibility because we can create any type of animal during the game. And also we can call this mixing operation to make sank according to the type of animal that we have created. So now we're going to do the same for that behaviors. Now we're going to have an interface called fly behavior and then we're going to have different implementations of flight behavior under the subtypes for example, fly with wings or flying away. So fly with wings is the implementation of lying for other ducks that have wings. And fly no ways they are for for example, rubber duck or wouldn't decoy duck, those ducks that cannot fly. And then we will also have a crack behavior interface and then we're going to implement the concrete cracking behavior under the subtypes, for example, crack, squeak or mute. So now by using this design, we can be used to fly and crack behavior for different types of ducks. And we can also easily add new behaviors into these two interfaces. So now the tax simulation game has the benefit of reuse while still being maintainable. Because if we want to maintain the cracking behavior and flying behavior, we simply have to modify the interface for flying behavior and also the interface for correct behavior. So now using the new design, what would you do if you need to add rocket powered flying to the ducks simulation game? It's going to be easy right under it's going to be easy under the flying behavior. We're going to have another implementation which is called fly rocket powered and can you think of a class that may want to use the cracking behavior that's not a duck. For example, in your game you may have a dark core to try to pretend to be a duck. So this duck object may utilize the cracking behavior in the game. And now we also need to add two variables to keep track the frying behavior and cracking behavior of each duck. And these variables, they are declared as the behavior interface type. And then we're going to implement some further operations to perform cracking and perform flying. Now each duck has a reference to something that implements the flight behavior and correct behavior interfaces. And then when you try to perform flying and try to perform cracking, you're going to call these two operations and utilize the flying behavior to perform flying. And also utilize the specified as cracking behavior to perform cracking. For example, formal attack, cracking behavior is going to be crack and flying behavior is going to be flying with wings. How about a rubber duck? For a rubber duck? The cracking behavior should be squeak and the flying behavior should be flying away because rubber ducks cannot fly and this is the whole picture. Each duck is going to have some flying behavior and cracking behavior and we're going to define the exact cracking behavior and flying behavior under the subtype, for example, cracking behavior. Formula club. We're going to utilize this particular implementation, cracking and fly behavior. We're going to utilize this particular implementation which is fly with wings. So to make the game even more flexible, we're going to implement this to operations, set flying behavior. And set cracking behavior so that we can dynamically change the flying behavior and cracking behavior while we are playing the game during runtime. And this is the whole picture under the super type duck, we have to declare the flying behavior and cracking behavior and then we have different types of ducks. Then we define the flying behavior and cracking behavior. Using an interface. Under each interface we're going to have the concrete implementations for flying behavior and also the concrete implementations for cracking behavior. And now you can see that flying behavior is encapsulated within this interface. Flight behavior and cracking behavior is encapsulated within this interface, correct behavior and then under the super type we have different types of ducks. So that's why we say that here we have some relationship, super type and subtype. And then under the interface we have different concrete implementations and each duck you can see that each duck is going to have some flying behavior and cracking behavior. So that's why we say that each duck has some flying behavior and has some cracking behavior. So now think of each set of behaviors under an interface as a family of algorithms. So we have different algorithms for flying and also different algorithms for cracking and these behaviors or L A thumbs. They are interchangeable and also clients they're going to make use of and encapsulate the family of algorithms for both flying and cracking. So in calculation means you don't have to know exactly how we implement the flying behaviors and correcting behaviors. You simply have to use the behavior in your game. That's it. And this is known as the strategy pattern because we are using different strategies or different algorithms for doing something. And this is the class diagram that we use for a strategy pattern. In strategy pattern. We have a client for example, duck. Okay then each duck has a reference. This arrow means has a reference to different strategies that ducks can use for flying and cracking. And then the flying and cracking strategies they are part of the duck. Right? Because under the duck we have to declare the flying behavior and cracking behavior. And now we say that this client has a reference to the strategy object and this strategy classes going to declare a common interface to all supported algorithms. So we're going to have different algorithms under different implementations of strategy. And then these are the concrete implementations of the different algorithms. And this is an other design principle that we utilize in strategy pattern. We try to favor has our relationship rather than inheritance. So inheritance means we have super type and then we have subtypes. But has a relationship means each client they're going to have different strategies for flying and cracking for example. So that means in our class diagram we favor this horizontal line. That means the client's going to have different strategies on doing something rather than inheritance. And in the duck simulation game we also favor, has a relationship because each duck is going to have different flying behavior and also different cracking behavior.