Design patterns can turbo boost your software development. Once you understand them, you can apply them to make your code more efficient and maintainable. Instead of re-creating the wheel, just use the patterns you need and move on.
Our free real world C# design patterns, created in .NET Core, can be in use immediately. No copying and pasting file after file into your IDE. Just download them and start using them. Each pattern can be run individually to step through the code, and see the results.
You could spend time and energy reading dry academic tests, but why bother when you can just run through working code and see what it does and why? This set of patterns, defined by the gang of four (GOF), will help you blast through your coding.
The full set of C# design patterns is listed below, as are some examples of what you will get in the small download with a big impact.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Blightysoft.CSharpDesignPatterns.Singleton
{
/* Start here.
*
* The Singleton pattern is a way of allowing just one instance of a class to be created.
* An example is with databases, where we might only want to get one object to deal with it
* rather than creating many connections over and over again.
*
* After the first instance is created, all others use the same object. In order to achieve
* this, the instance is created inside the singleton, and anyone can then access it via
* a static variable.
*/
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DataBase.Description);
Thread.Sleep(1000);
/* Although we run through this ten times (asynchronously to mimic an overload of
* requests for instances of the DataBase class), it will only be instantiated once.*/
for (int i = 0; i < 10; i++)
{
Task.Factory.StartNew(() => Console.WriteLine(DataBase.Instance.ToString()));
}
Console.ReadKey();
}
}
}
using System;
namespace Blightysoft.CSharpDesignPatterns.Singleton
{
public class Database
{
/*
* This usage of `Lazy` creates just one instance of the `Database` class.
*/
private static readonly Lazy<Database> lazyInstance = new Lazy<Database>(() =>
{
Console.WriteLine(value: "Initialising the lazy singleton to access the database.");
return new Database();
});
private Database()
{
}
public static Database Instance
{
get
{
/* The first time that `Value` is accessed, the instantiation occurs. */
return lazyInstance.Value;
}
}
public static string Description
{
get
{
return "A static description that can be called without instantiating this class.";
}
}
}
}
using System;
namespace Blightysoft.CSharpDesignPatterns.Decorator
{
/* Start here.
*
* The Decorator pattern is a way to add responsibilities to a class dynamically. It is a
* very flexible alternative to sub-classing, and prevents a classic problem, whereby a super
* class changes and disrupts the sub classes. With the decorator pattern, there is a great deal
* more abstraction. It embodies the idea of code being open to extension but closed to modification.
*/
internal class Program
{
private static void Main(string[] args)
{
IWindow window = new SimpleWindow();
Console.WriteLine(window.GetDescription());
window = new VerticalScrollbarWindow(new SimpleWindow());
Console.WriteLine(window.GetDescription());
window = new HorizontalScrollbarWindow(new VerticalScrollbarWindow(new SimpleWindow()));
Console.WriteLine(window.GetDescription());
Console.ReadKey();
}
}
}
namespace Blightysoft.CSharpDesignPatterns.Decorator
{
/* This interface defines the contract that all decorators must implement
* in order to be allowed to decorate each other. */
internal interface IWindow
{
void Draw();
string GetDescription();
}
}
namespace Blightysoft.CSharpDesignPatterns.Decorator
{
/* A simple window that doesn't decorate anything, but because
* it implements IWindow, it can be decorated by something else.
*/
internal class SimpleWindow : IWindow
{
public void Draw()
{
/* Draws the window on the screen. */
}
public string GetDescription()
{
return "Simple window";
}
}
}
namespace Blightysoft.CSharpDesignPatterns.Decorator
{
/* Provides the base functionality for the decorators. */
internal class WindowDecorator : IWindow
{
protected IWindow DecoratedWindow;
/* This constructor allows the class to decorate anything that implements IWindow. */
public WindowDecorator(IWindow decoratedWindow)
{
DecoratedWindow = decoratedWindow;
}
public virtual void Draw()
{
DecoratedWindow.Draw();
}
public virtual string GetDescription()
{
return "Window decorator";
}
}
}
namespace Blightysoft.CSharpDesignPatterns.Decorator
{
/* Decorates any IWindow by drawing a vertical scrollbar as well as any other
* drawing carried out by the decorated class. */
internal class VerticalScrollbarWindow : WindowDecorator
{
/* This constructor allows the class to decorate anything that implements IWindow. */
public VerticalScrollbarWindow(IWindow decoratedWindow) : base(decoratedWindow)
{
}
public override void Draw()
{
/* Draws via the base class, and then this class. */
base.Draw();
DrawVerticalScrollbar();
}
private void DrawVerticalScrollbar()
{
/* Draws a vertical scrollbar. */
}
public override string GetDescription()
{
return DecoratedWindow.GetDescription() + ", with vertical scrollbars";
}
}
}
namespace Blightysoft.CSharpDesignPatterns.Decorator
{
/* Decorates any IWindow by drawing a horizontal scrollbar as well as any other
* drawing carried out by the decorated class. */
internal class HorizontalScrollbarWindow : WindowDecorator
{
/* This constructor allows the class to decorate anything that implements IWindow. */
public HorizontalScrollbarWindow(IWindow decoratedWindow) : base(decoratedWindow)
{
}
public override void Draw()
{
/* Draws via the base class, and then this class. */
base.Draw();
DrawHorizontalScrollbar();
}
private void DrawHorizontalScrollbar()
{
/* Draws a horizontal scrollbar. */
}
public override string GetDescription()
{
return DecoratedWindow.GetDescription() + ", with horizontal scrollbars";
}
}
}