Статические классы повышают связность кода (увеличивают coupling), но с важными нюансами. Рассмотрим детально:
public class OrderService
{
public void ProcessOrder(Order order)
{
Logger.Log(order); // Прямая привязка к конкретной реализации
Database.Save(order); // Нельзя подменить в тестах
}
}
public static class Logger // Статический класс-синглтон
{
public static void Log(Order order) {...}
}
public static class AppConfig
{
public static string ConnectionString { get; set; } // Общее состояние
}
// Где-то в другом месте кода:
AppConfig.ConnectionString = "..."; // Неявная зависимость
public static class MathUtils
{
public static double CalculateVAT(double amount)
=> amount * 0.2; // Нет состояния, только логика
}
public static class StringExtensions
{
public static string Truncate(this string s, int length)
=> s.Length > length ? s[..length] : s;
}
public static class PaymentProviderFactory
{
public static IPaymentProvider Create(string type)
=> type switch {
"PayPal" => new PayPalProvider(),
_ => new DefaultProvider()
};
}
public interface ILogger
{
void Log(Order order);
}
public class OrderService
{
private readonly ILogger _logger;
public OrderService(ILogger logger) // Внедрение зависимости
{
_logger = logger;
}
}
public class DatabaseService
{
private static Lazy<IDatabase> _instance = new Lazy<IDatabase>(CreateDb);
public static IDatabase Instance => _instance.Value;
private static IDatabase CreateDb() {...}
}
Характеристика | Статический класс | DI через интерфейс |
---|---|---|
Тестируемость | ❌ Низкая | ✅ Высокая |
Гибкость | ❌ Жесткая | ✅ Подменяемая |
Связность | ❌ Высокая | ✅ Низкая |
Параллельное выполнение | ⚠️ Риск состояний | ✅ Безопасно |
Правило: "Static рассматриваем как последнее средство, а не как решение по умолчанию"