Starting with a video game about Ducks "Simuduck", the initial design was
At this point, with a new demand, the Ducks need to be able to fly
First design: (Add a Fly method to the parent class duck, at which point all subclasses inherit the method)
However, when the manager was demonstrating the project, he used a rubber duck and said that the rubber duck should not fly (the grieving programmer. )
How do we solve this problem? (Adds a method to a parent class, but some subclasses don't need the method, not even the method)
Second design: (Add flyable interface and quackable interface to enable the desired duck to implement the interface)
It is true that the design solves our previous problem, each duck has its own method, but the method creates code redundancy and violates the dry principle.
How do we solve this problem? (each subclass needs to implement the interface, resulting in redundant code between subclasses)
Third design: (different implementations of the interface, at this time the Duck class does not inherit or implement the interface, but in the class to instantiate an object, at this time, there will be no inheritance between the duck class and fly and quack, solve the problem of the first design, but also because the fly interface has been implemented, Duck class does not need to implement the Fly interface itself, solve the problem of the second design)
Code (Duck abstract class, defining interface Type):
Also, add Set method (can change dynamically)
In Duck subclasses, instantiate the interface
Summarize:
1. Separate the areas where the application may need to change, and do not mix with code that does not need to change {
As the Fly method in the example, because there is variability, do not and similar to the display method such as the fixed-need method of mixing together
}
2. Programming for interfaces, not programming for implementation {
In the example, instead of implementing the fly interface by the Duck class, we are creating a new Flyxx class to implement the Fly interface, so that the duck behaves as a standalone class rather than being implemented by the Duck parent class (design 1), or by a subclass implementation (design 2) after inheriting an interface. So the duck's behavior will not be tied to death on the Duck class.
}
3. Multi-use combination, less inheritance {
In the example, the combination is a combination of the Duck class and the fly and other behavior classes, using the combination to build the system can have a great flexibility, but also can change the behavior at run time
}
4. The process of rewriting the above example is using the strategy mode {
The strategy pattern defines a series of algorithms (The fly and quack behaviors in the example are algorithms), respectively, so that they can be replaced by each other, so that the algorithm changes independently of the client using the algorithm (example, Duck class and Fly class will not affect each other because of inheritance relationship)
}
Of course, the strategy model also has drawbacks:
1. The client needs to know all the policy classes
2. Policy mode generates many policy classes
Introduction of design pattern--Strategy mode