Application Scenario Description: if we need to develop a tank for the game, in addition to a variety of different types of tanks, we also hope to add one or more of the following features for it in different occasions, for example, infrared night vision functions, such as amphibious functions, such as satellite positioning functions;
In general, we may do this during programming:
// Define the abstract class of the tank
Public abstract class tank {
Public abstract shot ();
Public abstract run ();
}
// Various models
Public class T50: Tank {........}
Public class t70: Tank {........}
Public class T90: Tank {........}
Public class T30: Tank {........}
// The combination of various additional features and different types of tanks. Among them, IA, IB, and IC indicate the interfaces of the three functions described above.
Public class T50: Tank, Ia {........}
Public class T50: Tank, IB {........}
Public class T50: Tank, IA, IB, IC {........}
Public class T50: Tank, IA, IC {........}
..................
In this way, there is a problem that cannot be ignored:Explosive growth of subclass!
ProblematicRoot Cause: Excessive use of inheritance to extend the object function, because inheritance is a type-introducedStaticSuch expansion lacks flexibility.
How to solve the problem: static (compile-time) --> dynamic (runtime)
Dynamically add some additional responsibilities to an object. In terms of functions, the decorator mode is more flexible than the subclass generation. -- Design Pattern gof
The solution to the above problem using the decorator mode is given below:
Namespace consoleapplication5 <br/>{< br/> public abstract class tank <br/>{< br/> public abstract void shot (); </P> <p> public abstract void run (); <br/>}</P> <p> // decoration Class A <br/> public class decoratora: tank // The interface inherits the IS-A relationship <br/>{< br/> private tank; // the has-a relationship </P> <p> Public decoratora (tank) <br/>{< br/> This. tank = tank; <br/>}</P> <p> Public override void shot () <br/>{< br/> // do something; function Expansion <br/> tank. shot (); </P> <p >}</P> <p> Public override void run () <br/>{< br/> // do something; function Expansion <br/> tank. run (); <br/>}</P> <p> // decoration Class B <br/> public class decoratorb: tank <br/>{< br/> private tank; </P> <p> Public decoratorb (tank) <br/>{< br/> This. tank = tank; <br/>}</P> <p> Public override void shot () <br/>{< br/> // do something; function Expansion <br/> tank. shot (); </P> <p >}</P> <p> Public override void run () <br/>{< br/> // do something; function Expansion <br/> tank. run (); <br/>}</P> <p> public class tank50: tank <br/> {<br/> Public override void run () <br/>{</P> <p >}</P> <p> Public override void shot () <br/>{</P> <p >}< br/>}</P> <p> class Program <br/>{< br/> Public static void main () <br/>{< br/> tank T50 = new tank50 (); </P> <p> decoratora t50_a = new decoratora (t50); // added the function; </P> <p> decoratora t50_ B = new decoratora (t50); // extended function B. </P> <p> decoratora t50_ AB = new decoratora (t50_a ); // extended functions a and B </P> <p >}< br/>
DecoratorCombinationRatherInheritance, Used to solveFeature expansion in multiple directions of the Subject Class.
A typical application of the decorator mode in the. NET Framework: stream class extension.