Observer
Observer is a behavioral design pattern also known as Publish-Subscribe which allows one object to notify muliple objects about events or state changes.
interface Publisher {
subscribe(observer: Observer): void
unsubscribe(observer: Observer): void
notify(): void
}
interface Observer {
update(publisher: Publisher): void
getId(): string
}
class Timer implements Publisher {
private observers: Observer[] = [];
time = 0
subscribe(observer: Observer): void {
const isExist = this.observers.filter(existObserver => existObserver.getId() === observer.getId())[0];
if (isExist) {
console.log('Observer has been subscribed already.');
return
}
this.observers.push(observer);
};
//unSubscribe an observer from the Publisher.
unsubscribe(observer: Observer): void {
const observerIndex = this.observers.findIndex(existObserver => existObserver.getId() === observer.getId());
if (observerIndex === -1) {
console.log('Nonexistent observer.');
return
}
this.observers.splice(observerIndex, 1);
};
// Notify all observers about an event.
notify(): void {
for (const observer of this.observers) {
observer.update(this);
}
};
tick() {
this.time++
this.notify()
}
}
class DigitalClock implements Observer {
private timer: Timer
private displayTime = 0
private id: string
constructor(timer: Timer) {
this.timer = timer
this.id = "randomId1"
this.timer.subscribe(this)
this.setDisplayTime(this.timer.time)
}
getId() {
return this.id
}
setDisplayTime(time: number){
this.displayTime = time
}
show(){
console.log("Digital Clock:", this.displayTime)
}
update(timer: Timer): void {
this.setDisplayTime(timer.time)
this.show()
}
unsubscribe(){
this.timer.unsubscribe(this)
}
}
class AnalogClock implements Observer {
private timer: Timer
private displayTime = 0
private id: string
constructor(timer: Timer) {
this.timer = timer
this.id = "randomId2"
this.timer.subscribe(this)
this.setDisplayTime(this.timer.time)
}
getId() {
return this.id
}
setDisplayTime(time: number){
this.displayTime = time
}
show(){
console.log("Analog Clock:", this.displayTime)
}
update(timer: Timer): void {
this.setDisplayTime(timer.time)
this.show()
}
unsubscribe(){
this.timer.unsubscribe(this)
}
}
const timer = new Timer()
new DigitalClock(timer)
new AnalogClock(timer)
timer.tick()
timer.tick()
timer.tick()