public void Execute() { // using the original superclass, the client can access the old functionality IDoesSomething oldFunctionality = new LegacyClass(); oldFunctionality.DoSomeThing("foo", 5); // new functionality A can be accessed via the FunctionalityA class, // which additionally provides the old functionality IDoesSomething functionalityA = new FunctionalityA(); oldFunctionality.DoSomeThing("foo", 5); // new functionality B can be accessed via the FunctionalityB class, // which also provides the old functionality IDoesSomething functionalityB = new FunctionalityB(); oldFunctionality.DoSomeThing("foo", 5); // what happens when we want both A and B? // IDoesSomething functionalityAandB = new FunctionalityAAndB(); ? // what when we want A and C but not B? // when functionalities C-Z or more are added, we need either an unwieldy // subclass hierarchy or some convoluted logic. }
public void Execute() { // using the original class, the client can access the old functionality IDoesSomething oldFunctionality = new LegacyClass(); oldFunctionality.DoSomeThing("foo", 5); // now adding functionality A; each decorator is constructed with the interface that it implements IDoesSomething functionalityWithA = new LegacyClassDecoratorA(new LegacyClass()); functionalityWithA.DoSomeThing("foo", 5); // similar pattern for functionality B on top of the old functionality.. IDoesSomething functionalityWithB = new LegacyClassDecoratorB(new LegacyClass()); functionalityWithB.DoSomeThing("foo", 5); // combinations of functionality are possible with constructor chaining - original + A + C IDoesSomething functionalityWithAandC = new LegacyClassDecoratorC(new LegacyClassDecoratorA(new LegacyClass()), 10); functionalityWithAandC.DoSomeThing("foo", 5); // the .Net streams library is a good example of the decorator pattern in the wild: using (var outputStream = new GZipStream( new BufferedStream( new FileStream("hello.txt.gz", FileMode.Create)), CompressionMode.Compress)) { byte[] someData = Encoding.UTF8.GetBytes("Hello world!"); outputStream.Write(someData, 0, someData.Length); outputStream.Flush(); } }