What is the design pattern?
Design pattern is the solution to the occurring problem that occurs in software design.
This article will discuss how to implement a decorator
design pattern` in C# with some real-world examples. Decorator design pattern in behavioural design pattern which:-
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality (also known as Wrapper)
Let’s understand the decorator design pattern with a real-world example.
This example shows how Decorator can adjust the behaviour of an object without changing its code. Initially, Stream can only read and write data in plain text. Then we created ‘UpperStream’ wrapper/decorator classes, which add new behaviour to convert text to UpperCase
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DecoratorPattern
{
public class UpperStream: Stream
{
private Stream _stream;
public UpperStream(Stream stream)
{
this._stream = stream;
}
public override long Length
{
get { return _stream.Length; }
}
public override int Read(byte[] buffer, int offset, int count)
{
var numberOfBytesRead = _stream.Read(buffer, offset, count);
for (int i = 0; i < numberOfBytesRead; i++)
{
buffer[i] = (byte)char.ToUpper((char)((int)buffer[i]));
}
return numberOfBytesRead;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { throw new NotImplementedException(); }
}
public override bool CanWrite
{
get { throw new NotImplementedException(); }
}
public override void Flush()
{
throw new NotImplementedException();
}
public override long Position
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
string message = "Hello Decorator";
MemoryStream ms=new MemoryStream(Encoding.UTF8.GetBytes(message));
UpperStream stream = new UpperStream(ms);
StreamReader reader = new StreamReader(stream);
Console.WriteLine(reader.ReadToEnd());
}
}
}
Where is it used in the .net framework
All the stream classes in the .net framework like FileStream,
CryptoStream,
and GzipStream
are examples of decorator patterns. They decorate the abstract class Stream.