Last active
December 3, 2020 20:33
-
-
Save LemonyPie/80756e1c0662c5b33ef9a018acff204d to your computer and use it in GitHub Desktop.
OOP design solution for FizzBuzz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Value<T> { | |
value: T; | |
} | |
interface Condition { | |
isFulfilled<T>(target: T): boolean; | |
} | |
interface Collection { | |
find<T, K>(target: T, defaultValue: K): K; | |
} | |
interface Rule { | |
isMatch<T>(target: T): boolean; | |
} | |
class Printer<T> { | |
constructor( | |
private context: Value<T> | |
) { } | |
public static print<T>(context: Value<T>): void { | |
console.log(context.value); | |
} | |
public print(): void { | |
Printer.print(this.context) | |
} | |
} | |
class Tag implements Value<string> { | |
constructor( | |
public readonly value: string | |
) { } | |
} | |
class DivisionCondition implements Condition { | |
constructor( | |
private divider: number | |
) { } | |
public isFulfilled(target: number): boolean { | |
return target % this.divider === 0; | |
} | |
} | |
class AllRequiredStrategy implements Condition { | |
constructor( | |
private validators: Condition[] | |
) { } | |
public isFulfilled<T>(target: T): boolean { | |
for(let validator of this.validators) { | |
if (!validator.isFulfilled(target)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
} | |
class TagNumberRule<T> implements Rule { | |
constructor( | |
public tag: Value<T>, | |
private strategy: Condition, | |
) { } | |
public isMatch<T>(target: T): boolean { | |
return this.strategy.isFulfilled(target); | |
} | |
} | |
class TagNumberRules<T> implements Collection { | |
constructor( | |
private rules: TagNumberRule<T>[] | |
) { } | |
public find<K>(value: K, defaultValue: Value<T>): Value<T> { | |
for(let rule of this.rules) { | |
if (rule.isMatch(value)) { | |
return rule.tag; | |
} | |
} | |
return defaultValue; | |
} | |
} | |
const numberTags = new TagNumberRules([ | |
new TagNumberRule(new Tag('FizzBuzz'), new AllRequiredStrategy([new DivisionCondition(3), new DivisionCondition(5)])), | |
new TagNumberRule(new Tag('Fizz'), new AllRequiredStrategy([new DivisionCondition(3)])), | |
new TagNumberRule(new Tag('Buzz'), new AllRequiredStrategy([new DivisionCondition(5)])) | |
]) | |
for(let i = 0; i < 100; i++) { | |
Printer.print(numberTags.find(i, new Tag(i.toString()))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment