using System;
// 1. Принцип разделения интерфейсов (ISP)
public interface IEmailSender
{
void SendEmail(string to, string subject, string body);
}
public interface ISmsSender
{
void SendSms(string phone, string message);
}
// 2. Инверсия зависимостей: вводим абстракцию для логгера
public interface ILogger
{
void Log(string message);
}
// 3. Выносим логику скидок (SRP и OCP)
public interface IDiscountStrategy
{
decimal CalculateDiscount(Order order);
}
// Реализация логгера
public class FileLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine($"[LOG] {message}");
}
}
// Реализации уведомлений
public class EmailSender : IEmailSender
{
public void SendEmail(string to, string subject, string body)
{
Console.WriteLine($"Sending email to {to}: {subject} - {body}");
}
}
public class SmsSender : ISmsSender
{
public void SendSms(string phone, string message)
{
Console.WriteLine($"Sending SMS to {phone}: {message}");
}
}
// Реализации стратегий скидок (LSP соблюден, контракт общий)
public class DefaultDiscountStrategy : IDiscountStrategy
{
public decimal CalculateDiscount(Order order)
{
if (order.Total > 100) return order.Total * 0.1m;
if (order.Total > 50) return order.Total * 0.05m;
return 0;
}
}
public class SpecialDiscountStrategy : IDiscountStrategy
{
public decimal CalculateDiscount(Order order)
{
return order.Total >= 100 ? order.Total * 0.2m : 0; // Больше никаких исключений
}
}
public class Order
{
public int Id { get; set; }
public decimal Total { get; set; }
}
public class OrderProcessor
{
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
private readonly IDiscountStrategy _discountStrategy;
// 4. Внедрение зависимостей (Dependency Injection)
public OrderProcessor(
IEmailSender emailSender,
ISmsSender smsSender,
ILogger logger,
IDiscountStrategy discountStrategy)
{
_emailSender = emailSender;
_smsSender = smsSender;
_logger = logger;
_discountStrategy = discountStrategy;
}
public void Process(Order order, string customerEmail, string customerPhone)
{
_logger.Log($"Processing order {order.Id}");
// Применяем скидку через абстракцию
decimal discount = _discountStrategy.CalculateDiscount(order);
order.Total -= discount;
// Отправка уведомлений
_emailSender.SendEmail(customerEmail, "Order processed", $"Total: {order.Total}");
_smsSender.SendSms(customerPhone, $"Order {order.Id} total: {order.Total}");
_logger.Log($"Finished processing order {order.Id}");
}
}