Skip to content

Instantly share code, notes, and snippets.

@wilk
Last active March 22, 2020 14:48
Show Gist options
  • Save wilk/9efa50b9323b25c2cbe6d830e1ae128c to your computer and use it in GitHub Desktop.
Save wilk/9efa50b9323b25c2cbe6d830e1ae128c to your computer and use it in GitHub Desktop.
OOP vs FP (both with immutables)
interface IElement {
state: string;
temperature: number;
warm: (degrees: number) => IElement;
cool: (degrees: number) => IElement;
deriveState: (temperature: number) => string;
};
class WaterElement implements IElement {
private _state = 'liquid';
private _temperature = 20;
constructor(temperature: number = 20) {
this._temperature = temperature;
this._state = this.deriveState(temperature);
}
get state(): string {
return this._state;
}
get temperature(): number {
return this._temperature;
}
deriveState(temperature: number): string {
if (temperature > 100) return 'gaseous';
if (temperature > 0 && temperature < 100) return 'liquid';
return 'solid';
}
warm(degrees: number): IElement {
const temperature = this.temperature + degrees;
return new WaterElement(temperature);
}
cool(degrees: number): IElement {
const temperature = this.temperature - degrees;
return new WaterElement(temperature);
}
}
const liquidWater = new WaterElement(20);
const solidWater = liquidWater.cool(40);
const steamWater = solidWater.warm(150);
console.log(liquidWater.temperature, liquidWater.state); // 20 liquid
console.log(solidWater.temperature, solidWater.state); // -20 solid
console.log(steamWater.temperature, steamWater.state); // 130 gaseous
function AlcoholElement(temperature: number = 20): IElement {
const state = deriveState(temperature);
function deriveState(temperature: number): string {
if (temperature > 78) return 'gaseous';
if (temperature > -114 && temperature < 78) return 'liquid';
return 'solid';
};
function warm(degrees: number): IElement {
const _temperature = temperature + degrees;
return AlcoholElement(_temperature);
}
function cool(degrees: number): IElement {
const _temperature = temperature - degrees;
return AlcoholElement(_temperature);
}
const element = {
deriveState,
warm,
cool
};
Object.defineProperties(element, {
temperature: {
value: temperature,
writable: false
},
state: {
value: state,
writable: false
}
});
return element as IElement;
}
const liquidAlcohol = AlcoholElement(20);
const solidAlcohol = liquidAlcohol.cool(240);
const steamAlcohol = solidAlcohol.warm(450);
console.log(liquidAlcohol.temperature, liquidAlcohol.state); // 20 liquid
console.log(solidAlcohol.temperature, solidAlcohol.state); // -220 solid
console.log(steamAlcohol.temperature, steamAlcohol.state); // 230 gaseous
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment