The Decorator Pattern allows you to "Wrap" an object to add new functionality at runtime, without modifying the original class. This is far more flexible than inheritance because you can stack multiple decorators on top of each other like Russian nesting dolls.
You have a FileStore. You want to add Logging and Encryption. If you use inheritance, you need: LoggedFileStore, EncryptedFileStore, and LoggedEncryptedFileStore. With Decorators, you just wrap them.
// The core object
var store = new SimpleFileStore();
// Wrap it in a Logger!
var loggedStore = new LoggingDecorator(store);
// Wrap THAT in an Encryptor!
var secureStore = new EncryptionDecorator(loggedStore);
// When you call .Save(), it runs Encryption -> Logging -> Simple Saving.
secureStore.Save("data.txt");
The System.IO namespace is filled with decorators. FileStream is the base. BufferedStream decorates it with a buffer. CryptoStream decorates it with encryption. You can pipe them together seamlessly!
Q: "How does the Decorator pattern relate to the Open/Closed Principle?"
Architect Answer: "It is the perfect manifestation of OCP. We want to add new behavior (e.g., Auditing) to an existing service. Instead of opening the existing service code and potentially breaking it, we keep it 'Closed' for modification. We 'Open' the system for extension by creating a separate Decorator class that wraps the original. The original code remains pure and untouched, while the application gains new capabilities."