Dynamically add some additional responsibilities to an object. In terms of extended functionality, the decorators pattern is more flexible than the way in which subclasses are generated.
Take the. NET Framework 2.0 System.IO class as an example.
System.IO.Streampublic abstract class Stream:marshalbyrefobject, idisposable{public abstract int Read ([in, out] byte] buffer, int offset, int count); public abstract void Write (byte] buffer, int offset, int count); System.IO.MemoryStreampublic class memorystream:stream{public MemoryStream (byte] buffer) {} public override int Read ([ In, out] byte] buffer, int offset, int count) {} public override void Write (byte] buffer, int offset, int count) {}} System . IO. Filestreampublic class filestream:stream{Public FileStream (String path, FileMode mode) {} public override int Read ( Out] byte] buffer, int offset, int count) {} public override void Write (byte] buffer, int offset, int count) {}} System.IO. Bufferedstreampublic class bufferedstream:stream{private Stream _s; Public BufferedStream (Stream stream) {} public override int Read (byte] buffer, int offset, int count) {_s.read (); public override void Write (byte] buffer, int offset, int count) {_s.write (); }}
Calling code
public class client{public static void Main () {FileStream stream = new FileStream (@) c:\\c:\windows\system32\drivers\etc\ Services ", FileMode.Open); BufferedStream BufferedStream = new BufferedStream (stream, 1024); }}
In the. NET framework, all stream operations have a common base class System.IO.Stream, which is an abstract class that includes behavior such as read, write, and so on. For file flow and memory flow operations, defined FileStream and MemoryStream classes, all inherit stream classes, respectively, to achieve different read and write operations. In order to improve the reading and writing performance of the stream, buffer buffer is needed to store the stream data. At this point, the role of buffer for the flow of read and write operations, is equivalent to a decorative role.
Decorate mode should be used in the following situations:
You need to extend the functionality of a class or add additional responsibility to a class. You need to dynamically add functionality to an object that can be undone dynamically. The need to increase the number of functions generated by the permutations of some basic functions makes the inheritance relationship impractical.