Examples of design patterns .NET 8
These are examples of design patterns written in C#. Most of the popular design patterns that can be used in application development are described here.
- Design pattern: Strategy
using DesignPatterns.Interfaces;
using System.ComponentModel;
namespace DesignPatterns.Patterns.Behavioral;
/// <summary>
/// Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ.
/// </summary>
/// <remarks>
/// ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠ΅ΠΌΠ΅ΠΉΡΡΠ²Π° Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠ², ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΡΡΠΈΡ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ
ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²Π·Π°ΠΈΠΌΠΎΠ·Π°ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡΠΈ.
///
/// ΠΠ°ΡΡΠ΅ΡΠ½ Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ (Strategy) ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ°Π±Π»ΠΎΠ½ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π½Π°Π±ΠΎΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠ², ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΡΠ΅Ρ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· Π½ΠΈΡ
ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΠΈΡ
Π²Π·Π°ΠΈΠΌΠΎΠ·Π°ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡΡ.
/// Π Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΈΡΡΠ°ΡΠΈΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π»Π΅Π³ΠΊΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ Π΄ΡΡΠ³ΠΈΠΌ.
/// ΠΡΠΈ ΡΡΠΎΠΌ Π·Π°ΠΌΠ΅Π½Π° Π°Π»Π³ΠΎΡΠΈΡΠΌΠ° ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π΄Π°Π½Π½ΡΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ.
///
/// <see cref="https://metanit.com/sharp/patterns/3.1.php"/>
/// </remarks>
[Description("Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ: ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠ΅ΠΌΠ΅ΠΉΡΡΠ²Π° Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠ², ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΡΡΠΈΡ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ
ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²Π·Π°ΠΈΠΌΠΎΠ·Π°ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡΠΈ.\r\n\r\nΠΠ°ΡΡΠ΅ΡΠ½ Π‘ΡΡΠ°ΡΠ΅Π³ΠΈΡ (Strategy) ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ°Π±Π»ΠΎΠ½ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π½Π°Π±ΠΎΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠ², ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΡΠ΅Ρ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· Π½ΠΈΡ
ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΠΈΡ
Π²Π·Π°ΠΈΠΌΠΎΠ·Π°ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡΡ. \r\nΠ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΈΡΡΠ°ΡΠΈΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π»Π΅Π³ΠΊΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ Π΄ΡΡΠ³ΠΈΠΌ. \r\nΠΡΠΈ ΡΡΠΎΠΌ Π·Π°ΠΌΠ΅Π½Π° Π°Π»Π³ΠΎΡΠΈΡΠΌΠ° ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π΄Π°Π½Π½ΡΠΉ Π°Π»Π³ΠΎΡΠΈΡΠΌ.")]
internal class Strategy : IPattern
{
/// <summary>
/// ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΡΠΈΡΠ°ΡΠ΅Π»Ρ.
/// </summary>
interface IReader
{
void Parse(string url);
}
/// <summary>
/// Π§ΠΈΡΠ°ΡΠ΅Π»Ρ ΡΠ΅ΡΡΡΡΠΎΠ² (ΠΈΡΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Ρ ΡΡΡΠ°ΡΠ΅Π³ΠΈΠΉ).
/// </summary>
class ResourceReader
{
private IReader _reader;
public ResourceReader(IReader reader) => _reader = reader;
public void SetStrategy(IReader reader) => _reader = reader;
public void Read(string url) => _reader.Parse(url);
}
/// <summary>
/// Π§ΠΈΡΠ°ΡΠ΅Π»Ρ Π½ΠΎΠ²ΠΎΡΡΠ½ΡΡ
ΡΠ°ΠΉΡΠΎΠ².
/// </summary>
class NewsSiteReader : IReader
{
public void Parse(string url) => Console.WriteLine($"Π§ΡΠ΅Π½ΠΈΠ΅ Π΄Π°Π½Π½ΡΡ
Ρ Π½ΠΎΠ²ΠΎΡΡΠ½ΠΎΠ³ΠΎ ΡΠ°ΠΉΡΠ°: {url}");
}
/// <summary>
/// Π§ΠΈΡΠ°ΡΠ΅Π»Ρ ΡΠΎΡΠΈΠ°Π»ΡΠ½ΡΡ
ΡΠ΅ΡΠ΅ΠΉ.
/// </summary>
class SocialNetworkReader : IReader
{
public void Parse(string url) => Console.WriteLine($"Π§ΡΠ΅Π½ΠΈΠ΅ Π»Π΅Π½ΡΡ Π½ΠΎΠ²ΠΎΡΡΠ΅ΠΉ ΠΈΠ· ΡΠΎΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ ΡΠ΅ΡΠΈ: {url}");
}
/// <summary>
/// Π§ΠΈΡΠ°ΡΠ΅Π»Ρ Telegram ΠΊΠ°Π½Π°Π»ΠΎΠ².
/// </summary>
class TelegramChannelReader : IReader
{
public void Parse(string url) => Console.WriteLine($"Π§ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΠΈΠ· Telegram-ΠΊΠ°Π½Π°Π»Π°: {url}");
}
/// <summary>
/// ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΠ°ΡΡΠ΅ΡΠ½Π° ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
/// </summary>
public void ShowExample()
{
ResourceReader resourceReader = new ResourceReader(new NewsSiteReader());
string url = "https://news.com";
resourceReader.Read(url);
url = "https://vk.com";
resourceReader.SetStrategy(new SocialNetworkReader());
resourceReader.Read(url);
url = "@telegram-channel";
resourceReader.SetStrategy(new TelegramChannelReader());
resourceReader.Read(url);
}
}
- Design pattern: Observer
using DesignPatterns.Interfaces;
using System.ComponentModel;
namespace DesignPatterns.Patterns.Behavioral;
/// <summary>
/// ΠΠ°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ.
/// </summary>
/// <remarks>
/// ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΡΡ
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΡ
ΡΠΎΡΡΠΎΡΠ½ΠΈΡ.
///
/// ΠΠ°ΡΡΠ΅ΡΠ½ "ΠΠ°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ" (Observer) ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΡΠ΅ΡΠΊΠΈΠΉ ΡΠ°Π±Π»ΠΎΠ½ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ "ΠΎΠ΄ΠΈΠ½ ΠΊΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠΌ".
/// Π ΡΡΠΎΠΌ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΈ Π΅ΡΡΡ ΠΎΠ΄ΠΈΠ½ Π½Π°Π±Π»ΡΠ΄Π°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΈ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Π΅ΠΉ.
/// Π ΠΏΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π½Π°Π±Π»ΡΠ΄Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Ρ
Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Π΅ΠΉ.
///
/// <see cref="https://metanit.com/sharp/patterns/3.2.php"/>
/// </remarks>
[Description("ΠΠ°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ: ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΡΡ
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΡ
ΡΠΎΡΡΠΎΡΠ½ΠΈΡ.\r\n\r\nΠΠ°ΡΡΠ΅ΡΠ½ \"ΠΠ°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ\" (Observer) ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΡΠ΅ΡΠΊΠΈΠΉ ΡΠ°Π±Π»ΠΎΠ½ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ \"ΠΎΠ΄ΠΈΠ½ ΠΊΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠΌ\". \r\nΠ ΡΡΠΎΠΌ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΈ Π΅ΡΡΡ ΠΎΠ΄ΠΈΠ½ Π½Π°Π±Π»ΡΠ΄Π°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΈ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Π΅ΠΉ. \r\nΠ ΠΏΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π½Π°Π±Π»ΡΠ΄Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Ρ
Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Π΅ΠΉ.")]
internal class Observer : IPattern
{
/// <summary>
/// ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ.
/// </summary>
interface IObserver
{
void Update(double price);
}
/// <summary>
/// ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π½Π°Π±Π»ΡΠ΄Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°.
/// </summary>
interface IObservable
{
void AddObserver(IObserver observer);
void RemoveObserver(IObserver observer);
void Notify();
}
/// <summary>
/// ΠΠ»Π°ΡΡ ΠΏΡΠΎΠ΄ΡΠΊΡΠ° (Π½Π°Π±Π»ΡΠ΄Π°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ).
/// </summary>
class Product : IObservable
{
private List<IObserver> _observers;
private double _price;
public Product(double price)
{
Console.WriteLine($"Π‘ΡΠ°ΡΡΠΎΠ²Π°Ρ ΡΠ΅Π½Π° ΠΏΡΠΎΠ΄ΡΠΊΡΠ° {price}");
_price = price;
_observers = new List<IObserver>();
}
public void ChangePrice(double price)
{
Console.WriteLine($"Π¦Π΅Π½Π° Π½Π° ΠΏΡΠΎΠ΄ΡΠΊΡ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»Π°ΡΡ. ΠΠΎΠ²Π°Ρ ΡΠ΅Π½Π°: {price}");
_price = price;
Notify();
}
public void AddObserver(IObserver observer)
{
_observers.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
_observers.Remove(observer);
}
public void Notify()
{
foreach (var observer in _observers.ToList())
{
observer.Update(_price);
}
}
}
/// <summary>
/// ΠΠ»Π°ΡΡ ΠΎΠΏΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠΊΡΠΏΠ°ΡΠ΅Π»Ρ (Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ).
/// </summary>
class Wholesale : IObserver
{
private IObservable _observable;
public Wholesale(IObservable observable)
{
_observable = observable;
_observable.AddObserver(this);
}
public void Update(double price)
{
if (price < 300)
{
Console.WriteLine($"{nameof(Wholesale)} Π·Π°ΠΊΡΠΏΠΈΠ» ΡΠΎΠ²Π°Ρ ΠΏΠΎ ΡΠ΅Π½Π΅: {price}.");
_observable.RemoveObserver(this);
}
}
}
/// <summary>
/// ΠΠ»Π°ΡΡ ΠΎΠ±ΡΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠΊΡΠΏΠ°ΡΠ΅Π»Ρ (Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ).
/// </summary>
class Buyer : IObserver
{
private IObservable _observable;
public Buyer(IObservable observable)
{
_observable = observable;
_observable.AddObserver(this);
}
public void Update(double price)
{
if (price < 350)
{
Console.WriteLine($"{nameof(Buyer)} Π·Π°ΠΊΡΠΏΠΈΠ» ΡΠΎΠ²Π°Ρ ΠΏΠΎ ΡΠ΅Π½Π΅: {price}.");
_observable.RemoveObserver(this);
}
}
}
/// <summary>
/// ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΠ°ΡΡΠ΅ΡΠ½Π° ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
/// </summary>
public void ShowExample()
{
Product product = new Product(400);
Wholesale wholesale = new Wholesale(product);
Buyer buyer = new Buyer(product);
Console.WriteLine();
product.ChangePrice(550);
Console.WriteLine();
product.ChangePrice(530);
Console.WriteLine();
product.ChangePrice(320);
Console.WriteLine();
product.ChangePrice(280);
Console.WriteLine();
product.ChangePrice(120);
}
}
- .NET 8
2024