Ответ
Паттерн Фабрика (в частности, Simple Factory или Factory Method) решает проблему создания объектов, когда клиентский код не должен зависеть от конкретных классов создаваемых продуктов. Он инкапсулирует логику создания в отдельном компоненте.
Зачем это нужно?
- Соблюдение принципа открытости/закрытости (OCP): Чтобы добавить новый тип продукта, вы изменяете код фабрики, а не все места в коде, где этот продукт создается.
- Упрощение клиентского кода: Клиент работает с абстракцией (
IDocument), а не с конкретными классами (PdfDocument,WordDocument). - Централизация сложной логики инициализации: Если создание объекта требует сложных шагов (например, конфигурации, проверок), это скрыто внутри фабрики.
Практический пример: Фабрика документов для системы отчетов
// 1. Абстракция продукта
public interface IDocument
{
string Name { get; }
byte[] Generate();
}
// 2. Конкретные продукты
public class PdfDocument : IDocument
{
public string Name => "Report.pdf";
public byte[] Generate()
{
// Логика генерации PDF (например, с помощью iTextSharp)
Console.WriteLine("Generating PDF...");
return new byte[] { /* PDF bytes */ };
}
}
public class ExcelDocument : IDocument
{
public string Name => "Data.xlsx";
public byte[] Generate()
{
// Логика генерации Excel (например, с помощью EPPlus)
Console.WriteLine("Generating Excel spreadsheet...");
return new byte[] { /* Excel bytes */ };
}
}
// 3. Фабрика (Simple Factory)
public static class DocumentFactory
{
public static IDocument CreateDocument(string documentType, string data)
{
return documentType.ToUpper() switch
{
"PDF" => new PdfDocument(), // Может принимать data для наполнения
"EXCEL" => new ExcelDocument(),
_ => throw new ArgumentException($"Unsupported document type: {documentType}")
};
}
}
// 4. Использование клиентом
public class ReportService
{
public void ExportReport(string format, string data)
{
// Клиент НЕ знает о конкретных классах PdfDocument/ExcelDocument
IDocument document = DocumentFactory.CreateDocument(format, data);
byte[] fileContent = document.Generate();
File.WriteAllBytes(document.Name, fileContent);
Console.WriteLine($"Document saved as {document.Name}");
}
}
Развитие паттерна: Для более сложных сценариев используются Abstract Factory (создание семейств связанных объектов) и Factory Method (делегирование создания подклассам).