Фабричных методов на самом деле много.
Даже базовые конструкции if else являются фабричным методом, так как и switch.
Но ведь это не удобно читать и расширять.
Представим простой пример. У нас есть игра slasher с монстрами. У нас есть несколько режимов: easy, medium, hard. Следовательно пусть у нас будут отличаться у монстров жизни и урон. Как организовать удобное создание монстров и в одном месте? Все в подcut`e.
1. Создадим примерное описание монстра в виде Description.
[Serializable] public class MobDescription { public float MaxHealth; public float Damage; }
2. Заполним наших монстров по уровням
Способов заполнить такие Descriptions на самом деле много, будь то json, xml или же просто ScriptableObject. Для примера воспользуемся ScriptableObject и создадим класс списков описаний монстров.
[CreateAssetMenu(fileName = "MobDescriptions", menuName = "MobDescriptions", order = 51)] public class MobDescriptions : ScriptableObject { [SerializeField] private List<MobDescription> _listOgre; [SerializeField] private List<MobDescription> _listTroll; public List<MobDescription> ListOgre => _listOgre; public List<MobDescription> ListTroll => _listTroll; }
И получим вот это.

Так как мы делаем 3 уровня сложности, то давайте заполним

Хорошо у нас теперь есть все описания по уровням сложности для наших монстров.
3. Создадим Model для mvc монстра.
Это лишь шаблон использования расширения модели, для того чтобы не хранить данные о монстре прямо в модели.
public class MobModel { private MobDescription _description; private float _currentHealth; public MobDescription Description => _description; public MobModel(MobDescription description){ _description = description; _currentHealth = _description.MaxHealth; } // Ваша логика монстра }
4. Теперь создадим класс фабрики, которая будет создавать монстров в зависимости от уровня сложности. Такую фабрику легко расширить, а так же добавлять другие фабрики для генерацию дропа или спавна объектов.
public class Factory { private Dictionary<string, Func<int, MobModel>> mobFactory; public void Init(MobDescriptions descriptions) { mobFactory = new Dictionary<string, Func<int, MobModel>>() { {"ogre", (level) => new MobModel(descriptions.ListOgre[level])}, {"troll", (level) => new MobModel(descriptions.ListTroll[level])} }; } public MobModel CreateMobModel(string nameMob, int level) { return mobFactory[nameMob](level); } }
5. Ну и конечно же пример вызова создания монстра.
Пока нет никакой логики используем хардкод. В итоговом варианты это может быть доп описание уровня, в котором будут параметры для спавна монстров с нормальными условиями. Например когда игрок прошел конкретную точку, спавнятся N enemy X уровня.
public class GameManager : MonoBehaviour { [SerializeField] private MobDescriptions _mobDescriptions; private Factory _factory; private void Start() { _factory = new Factory(); _factory.Init(_mobDescriptions); _factory.CreateMobModel("ogre", 2); } }
ссылка на оригинал статьи https://habr.com/ru/post/482402/
Добавить комментарий