-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPatternVisitorTask.txt
More file actions
100 lines (70 loc) · 5.42 KB
/
PatternVisitorTask.txt
File metadata and controls
100 lines (70 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Суть паттерна Visitor (для контекста)
Visitor позволяет добавить новую операцию к группе объектов, не изменяя сами эти объекты.
Это идеально, когда у тебя есть иерархия классов (например, типы врагов или объектов на сцене),
и ты хочешь добавить новое поведение (например, рендер, сохранение, применение урона),
но не хочешь лезть в каждый класс и добавлять новый метод.
Практическое задание: "Система логирования боевых событий"
Контекст:
"У нас в игре есть разные типы объектов, которые могут участвовать в бою: Player, Enemy, Trap, Chest.
Геймдизайнер хочет добавить систему логирования (Logging),
которая будет записывать в консоль и (в будущем) в файл информацию о том, что произошло с каждым объектом.
Но разработчики уже заморозили код этих классов, и мы не можем добавлять в них новые методы (например, Log()).
Нужно использовать паттерн Visitor, чтобы добавить логирование без изменения существующих классов."
Что дано (ты должен это создать):
1. Интерфейс IBattleElement — его реализуют все боевые объекты.
public interface IBattleElement
{
void Accept(IBattleVisitor visitor);
}
2. Интерфейс IBattleVisitor — объявляет методы для каждого типа объекта.
public interface IBattleVisitor
{
void Visit(Player player);
void Visit(Enemy enemy);
void Visit(Trap trap);
void Visit(Chest chest);
}
3. Классы боевых объектов (уже заморожены, не меняешь их структуру, только добавляешь метод Accept):
- Player — есть поля: string Name, int Health, int Level
- Enemy — string Type, int Health, int Damage
- Trap — string TrapName, int Damage, bool IsTriggered
- Chest — string Contents, int GoldAmount, bool IsOpened
Твоя задача:
Создать класс-посетитель BattleLogger, который реализует IBattleVisitor
и для каждого типа объекта выводит в консоль специфическое сообщение.
Требования к выводу (формат сообщений):
Тип объекта | Пример вывода
Player | [LOG] Игрок Gandalf (Уровень 5) имеет 120 HP.
Enemy | [LOG] Враг Dragon (Урон 45) имеет 300 HP.
Trap | [LOG] Ловушка "Огненная яма" нанесла 50 урона. Активирована: True
Chest | [LOG] Сундук содержит "Легендарный меч" и 150 золота. Открыт: False
Что нужно реализовать в Main:
1. Создать List<IBattleElement> и добавить туда 2-3 экземпляра каждого класса (всего 8-10 объектов).
2. Создать экземпляр BattleLogger.
3. В цикле foreach пройтись по всем элементам списка и вызвать для каждого element.Accept(logger).
4. Никакой другой логики не требуется.
Бонус-задание (если справишься быстро):
Создать второго посетителя — DamageCalculatorVisitor,
который будет считать общий урон, который могут нанести все объекты в списке:
- У Player урон = Level * 10
- У Enemy урон = Damage (берётся напрямую)
- У Trap урон = Damage (если IsTriggered == true, иначе 0)
- У Chest урон = 0
Посетитель должен накапливать сумму и иметь метод GetTotalDamage(),
который вернет результат после обхода всех объектов.
Важные ограничения (как в реальном ТЗ):
1. Не менять классы Player, Enemy, Trap, Chest
(кроме добавления метода Accept — это стандартная реализация Visitor).
2. Каждый посетитель должен быть отдельным классом.
3. Логирование должно работать через интерфейс IBattleVisitor, без приведения типов (as, is) внутри Accept.
Подсказка (как будет выглядеть метод Accept в одном из классов):
public class Player : IBattleElement
{
public string Name { get; set; }
public int Health { get; set; }
public int Level { get; set; }
public void Accept(IBattleVisitor visitor)
{
visitor.Visit(this); // this передается с правильным типом
}
}