Класс Infantryman /// /// Пехотинец
/// public class Infantryman : Warrior
{
/// /// Информация о воине
/// /// public override string Info()
{
return "Infantryman";
}
}
Класс Archer /// /// Лучник
/// public class Archer : Warrior
{
/// /// Информация о воине
/// /// public override string Info()
{
return "Archer";
}
}
Класс Horseman /// /// Всадник
/// public class Horseman : Warrior
{
/// /// Информация о воине
/// /// public override string Info()
{
return "Horseman";
}
}
Абстрактный базовый класс Warrior определяет общий интерфейс, а производные от него классы Infantryman, Archer и Horseman реализуют особенности каждого вида воина. Сложность заключается в том, что хотя код системы и оперирует готовыми объектами через соответствующие общие интерфейсы, в процессе игры требуется создавать новые персонажи, непосредственно указывая их конкретные типы. Если код их создания рассредоточен по всему приложению, то добавлять новые типы персонажей или заменять существующие будет затруднительно.
В таких случаях на помощь приходит фабрика объектов, локализующая создание экземпляров классов. С её помощью можно создавать объекты нужных классов, не указывая напрямую их типы. В самом простом случае, для этого используются идентификаторы типов. Следующий пример демонстрирует простейший вариант фабрики объектов - фабричную функцию.
public enum WarriorTypes
{
Infantryman,
Archer,
Horseman
}
…
/// /// Создание воина
/// ///
Тип воина
///
public static Warrior CreateWarrior(WarriorTypes parWattiorType)
{
Warrior warrior = null;
switch (parWattiorType)
{
case WarriorTypes.Infantryman:
warrior = new Infantryman();
break;
case WarriorTypes.Archer:
warrior = new Archer();
break;
case WarriorTypes.Horseman:
warrior = new Horseman();
break;
}
return warrior;
}
Теперь, скрывая детали, код создания объектов разных типов игровых персонажей сосредоточен в одном месте, а именно, в фабричной функции CreateWarrior( ). Эта функция получает в качестве аргумента тип объекта, который нужно создать, создает его и возвращает соответствующий указатель на базовый класс.
Несмотря на очевидные преимущества, у этого варианта фабрики также существуют недостатки. Например, для добавления нового вида боевой единицы необходимо сделать несколько шагов - завести новый идентификатор типа и модифицировать код фабричной функции CreateWarrior( ).
Показав основные проблемы, которые возникают при добавлении новых типов классов, рассмотрим порождающие шаблоны и особенности каждого из них: