Шаблоны проектирования — это фантастический способ использовать повторно используемые решения известных проблем. Они также предоставляют разработчикам программного обеспечения универсальный язык для общения друг с другом во время обсуждения дизайна и архитектуры.

Ниже приведен базовый список шаблонов проектирования, которые должны знать все разработчики программного обеспечения. Это ни в коем случае не исчерпывающий список. Однако, по моим наблюдениям, это самые распространенные из тех, с которыми я сталкивался в своей повседневной работе.

В этом посте я сосредоточусь на некоторых наиболее распространенных творческих шаблонах, с которыми я сталкивался в своей повседневной разработке.

Заводской метод

Создайте объект, не указывая точный класс объекта, который будет создан

Пример

public class Vehicle {}
public class Hatchback : Vehicle {}
public class Sedan : Vehicle {}
public class Van : Vehicle {}
public class Bus : Vehicle {}
public class VehicleFactory
{
    public Vehicle GetVehicle(int numPassengers)
    {
        if (numPassengers < 5) 
        {
            return new Hatchback();
        }
        else if (numPassengers < 6) 
        {
            return new Sedan();
        }
        else if (numPassengers < 8) 
        {
            return new Van();
        }
        return new Bus();
    }
}

Строитель

Поэтапно создает сложный объект, используя более простые объекты, что позволяет нам писать простой читаемый код.

Пример

public class TradeBuilder
{
    private decimal _price;
    private decimal _quantity;
    private Trader _trader;
    private Portfolio _portfolio;
    private Security _security;
    public TradeBuilder()
    {
        _price = 0m;
        _quantity = 0m;
        _trader = Trader.DefaultTrader;
        _portfolio = Portfolio.DefaultPortfolio;
        _security = Security.DefaultSecurity;
    }
    
    public TradeBuilder WithPrice(decimal price)
    {
        _price = price;
        return this;
    }
    public TradeBuilder WithQuantity(decimal quantity)
    {
        _quantity = quantity;
        return this;
    }
    public TradeBuilder WithTrader(Trader trader)
    {
        _trader = trader;
        return this;
    }
    public TradeBuilder WithPortfolio(Portfolio portfolio)
    {
        _portfolio = portfolio;
        return this;
    }
    public TradeBuilder WithSecurity(Security security)
    {
        _security = security;
        return this;
    }
    public Trade Build()
    {
        return new Trade 
        {
            Price = _price;
            Quantity = _quantity;
            Trader = _trader;
            Portfolio = _portfolio;
            Security = _security;
        };
    }
}
public class TradeGenerator
{
    public List<Trade> GenerateSampleTrades()
    {
        return new List<Trade> 
        {
            new TradeBuilder()
                .WithPrice(10m)
                .WithQuantity(25m)
                .Build(),
            new TradeBuilder()
                .WithPrice(100m)
                .WithQuantity(30m)
                .WithPortfolio(new Portfolio("Day Trading"))
                .Build(),
            new TradeBuilder()
                .WithPrice(25m)
                .WithQuantity(30m)
                .WithTrader(new Trader("shankarvasudevan"))
                .Build()
         }
    }
}

Синглтон

Убедитесь, что у класса есть только один экземпляр, и предоставьте ему единую точку

Пример

public class DefaultPortfolioProvider
{
    private static Portfolio defaultPortfolio = new Portfolio("Default");
    private DefaultPortfolioProvider() {}
    public static Portfolio GetDefault()
    {
        return defaultPortfolio;
    }
}

Внедрение зависимости

Класс принимает объекты, которые ему требуются, путем внедрения, а не создает их локально.

Пример

public interface IPnlCalculator 
{
    decimal CalculatePnl(Trade trade);  
}
public interface ITradeRetriever
{
    List<Trade> GetTrades();
}
public class TradePnlCalculator
{
    private IPnlCalculator _pnlCalculator;
    private ITradeRetriever _tradeRetriever;
    public TradePnlCalculator(
        IPnlCalculator pnlCalculator,
        ITradeRetriever tradeRetriver)
    { 
        // injected via a dependency injection framework (e.g. Unity for .NET)
        // rather than created in this class
        _pnlCalculator = pnlCalculator;
        _tradeRetriever = tradeRetriever;
    }
}