Дизайн Патерн - ФАБРИЧНИЙ МЕТОД (Factory Method)
Уявіть, що ваша аплікація є дуже складною і так склалося, що ви використовуєте два логінг провайдери - один Log4Net та інший Enterprise.Logging. Ваш колега догадався помістити вибір провайдера прямо у конфіг файл. Так як ви всю логіку логування абстрагуєте за інтерфейсом ILogger, то вам б також хотілося приховати специфіку створення конкретного провайдера та винести її в окремий клас.
Як на мене то цей дизайн патерн є одним із найбільш відомих і найпростіших. Я переконаний, що більшість читачів бачили його багато раз. Завдання Фабричного Методу полягає в прихованні конкретного класу, що має бути створений та повернений під виглядом спільної абстракції. Якщо в метод передаються параметри, від яких залежить який клас буде створено, то такий Фабричний Метод називають Параметризованим Фабричним Методом. В нашому прикладі, класи що мають бути створені є Log4NetLogger та EnterpriseLogger, які імплементують ILogger, який широко використовується у нас в аплікації.
public interface ILogger<br />{<br /> void LogMessage(string message);<br /> void LogError(string message);<br /> void LogVerboseInformation(string message);<br />}<br />
Як можна здогадуватися, може статися що в майбутньому нам знадобиться додати ще декілька провайдерів логування (мало чого). Як ми уже згадували вирішення приймається на основі того, що є у файлі конфігурації. Щоб не показувати, який клас ми створюємо ми делегуємо цю роботу до LoggerProviderFactory. Ось використання:
public static void Run()<br />{<br /> var providerType = GetTypeOfLoggingProviderFromConfigFile();<br /> ILogger logger = LoggerProviderFactory.GetLoggingProvider(providerType);<br /> logger.LogMessage("Hello Factory Method Design Pattern.");<br />}<br /><br />private static LoggingProviders GetTypeOfLoggingProviderFromConfigFile()<br />{<br /> return LoggingProviders.Log4Net;<br />}<br />
То що ж ми отримуємо від методу GetLoggingProvider є об'єктом реалізуючим потрібний інтерфейс. Фабричний Метод вирішує яикй із конкретних класів створювати на основі вхідного параметру, в нашому випадку це енам. А ось реалізація Фабричного Методу:
public class LoggerProviderFactory<br />{<br /> public static ILogger GetLoggingProvider(LoggingProviders logProviders)<br /> {<br /> switch (logProviders)<br /> {<br /> case LoggingProviders.Enterprise:<br /> return new EnterpriseLogger();<br /> case LoggingProviders.Log4Net:<br /> return new Log4NetLogger();<br /> default:<br /> return new EnterpriseLogger();<br /> }<br /> }<br />}<br />
Оскільки моя хардкоджена конфігурація повертає Log4Net і оскільки імплементація методу LogMessage виглядає приблизно так:
public void LogMessage(string message)<br />{<br /> Console.WriteLine(string.Format("{0}: {1}", "Log4Net", message));<br />}<br />
Я отримую наступний вивід: Log4Net: Hello Factory Method Design Pattern.