Skip to content

Instantly share code, notes, and snippets.

@linadk
Created February 23, 2024 16:05
Show Gist options
  • Save linadk/0fd26b0278963c550afcff875fe28bd5 to your computer and use it in GitHub Desktop.
Save linadk/0fd26b0278963c550afcff875fe28bd5 to your computer and use it in GitHub Desktop.
A TypeScript observer pattern implementation that uses UIDs for lookup
"use strict";
/**
* Contains interfaces for the Observer design pattern.
*/
/**
* Base Observer class that uses unique id system to make lookups more efficient.
*
* @example
*
* ```
* class WatchDB extends Observer{
* private data:DBData;
* public update(subject:DBInstance){
* this.data = subject.getNewData()
* };
* }
* ```
*/
export class Observer{
public uid:string = crypto.randomUUID()
public update(subject:Subject): void{
throw new Error("Observers should not call the base update method!")
}
}
/**
* Base Subject class that allows observers to watch for notifications.
* @example
*
* ```
* class DBInstance extends Subject{
* public getNewData(){
* return data;
* }
* public onChange(data:DBData){
* //do stuff
* this.notify()
* };
* }
* ```
*
*/
export class Subject{
private observers:Map<string,Observer> = new Map<string,Observer>()
private readonly MAX_OBSERVERS:number = 200
public attach(observer:Observer): void {
if(this.numObservers() == this.MAX_OBSERVERS){
throw new RangeError(`Observer limit ${this.MAX_OBSERVERS} reached for subject ${this}!`)
}
this.observers.set(observer.uid,observer)
}
public detach(observer:Observer): void {
this.observers.delete(observer.uid)
}
public detachAll(): void {
this.observers.clear()
}
public numObservers(): number{
return this.observers.size;
}
public notify(): void {
this.observers.forEach( (observer) => {
observer.update(this)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment