Шаблон Observer в контексте игрового приложения
Шаблон Observer — это шаблон проектирования, который позволяет объектам уведомляться об изменениях состояния другого объекта, называемого "subject". В работе его называют паттерн "Наблюдатель". В контексте игрового приложения это можно использовать для уведомления различных компонентов игры (таких как табло, индикаторы здоровья и т. д.) при изменении состояния игры (например, когда игрок получает бонус или получает урон).
Вот пример фрагмента кода TypeScript, который иллюстрирует шаблон Observer в игровом приложении:
interface Subject {
registerObserver(o: Observer): void;
removeObserver(o: Observer): void;
notifyObservers(): void;
}
interface Observer {
update(score: number, health: number): void;
}
class Game implements Subject {
private score: number = 0;
private health: number = 100;
private observers: Observer[] = [];
public registerObserver(o: Observer): void {
this.observers.push(o);
}
public removeObserver(o: Observer): void {
const index = this.observers.indexOf(o);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
public notifyObservers(): void {
for (const observer of this.observers) {
observer.update(this.score, this.health);
}
}
public collectPowerUp(): void {
this.score += 10;
this.notifyObservers();
}
public takeDamage(): void {
this.health -= 10;
this.notifyObservers();
}
}
class Scoreboard implements Observer {
private score: number = 0;
public update(score: number, health: number): void {
this.score = score;
this.render();
}
public render(): void {
console.log(`Score: ${this.score}`);
}
}
class HealthBar implements Observer {
private health: number = 100;
public update(score: number, health: number): void {
this.health = health;
this.render();
}
public render(): void {
console.log(`Health: ${this.health}`);
}
}
// Usage
const game = new Game();
const scoreboard = new Scoreboard();
const healthBar = new HealthBar();
game.registerObserver(scoreboard);
game.registerObserver(healthBar);
game.collectPowerUp(); // Logs "Score: 10"
game.takeDamage(); // Logs "Health: 90"
game.removeObserver(healthBar);
game.collectPowerUp(); // Logs "Score: 20" (only the Scoreboard is notified)
В этом примере класс Game является субъектом, который поддерживает состояние игры (счет и работоспособность) и уведомляет своих наблюдателей об изменении состояния. Классы Scoreboard и HealthBar являются наблюдателями, которые отслеживают изменения в состоянии игры и соответствующим образом обновляют свои соответствующие дисплеи.
Когда в экземпляре игры вызывается метод collectPowerUp, он увеличивает счет и уведомляет всех наблюдателей, вызывая notifyObservers. Аналогично, когда вызывается метод TakeDamage, он уменьшает работоспособность и уведомляет об этом всех наблюдателей.
Экземпляры Scoreboard и HealthBar реализуют интерфейс Observer, который требует, чтобы у них был метод обновления, который принимает текущие значения оценки и работоспособности. Когда они получают обновление от экземпляра игры, они обновляют свое собственное внутреннее состояние и вызывают render для обновления своего отображения.
Наконец, мы видим, что мы можем удалить наблюдателя, вызвав removeObserver в экземпляре игры, и удаленный наблюдатель больше не будет получать уведомления об обновлениях.