Last active
May 20, 2024 07:35
-
-
Save mybearworld/d9d657dc29a360cd8e5022e2b93bf5c3 to your computer and use it in GitHub Desktop.
The agile enterprise object-oriented encapsulated composition-based SOLID FizzBuzz program in a Microsoft-backed programming language.
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
class FizzBuzz { | |
constructor() { | |
const counter = new Counter(); | |
const looper = new Looper(); | |
const counterBoundsChecker = new CounterBoundsChecker(counter, 101); | |
const fizzBuzzMainLoop = new FizzBuzzMainLoop(counter); | |
looper.doWhile(counterBoundsChecker, fizzBuzzMainLoop); | |
} | |
} | |
class Counter { | |
private count: number = 1; | |
increment() { | |
this.count++; | |
} | |
get value() { | |
return this.count; | |
} | |
} | |
class CounterBoundsChecker implements Checker { | |
private counter: Counter; | |
private maximum: number; | |
constructor(counter: Counter, maximum: number) { | |
this.counter = counter; | |
this.maximum = maximum; | |
} | |
check() { | |
return this.counter.value < this.maximum; | |
} | |
} | |
class FizzBuzzMainLoop implements Executor { | |
private counter: Counter; | |
constructor(counter: Counter) { | |
this.counter = counter; | |
} | |
execute() { | |
const conditionalExecutor = new ConditionalExecutor(); | |
const divisibleBy3Checker = new CounterDivisibilityChecker(this.counter, 3); | |
const divisibleBy5Checker = new CounterDivisibilityChecker(this.counter, 5); | |
const divisibleByBoth3And5Checker = new DoubleChecker( | |
divisibleBy3Checker, | |
divisibleBy5Checker | |
); | |
const fizzPrinter = new Printer("Fizz"); | |
const buzzPrinter = new Printer("Buzz"); | |
const fizzBuzzPrinter = new Printer("FizzBuzz"); | |
const numberPrinter = new Printer(this.counter.value.toString()); | |
try { | |
conditionalExecutor.executeConditionally( | |
divisibleByBoth3And5Checker, | |
fizzBuzzPrinter | |
); | |
} catch { | |
this.counter.increment(); | |
return; | |
} | |
try { | |
conditionalExecutor.executeConditionally( | |
divisibleBy3Checker, | |
fizzPrinter | |
); | |
} catch { | |
this.counter.increment(); | |
return; | |
} | |
try { | |
conditionalExecutor.executeConditionally( | |
divisibleBy5Checker, | |
buzzPrinter | |
); | |
} catch { | |
this.counter.increment(); | |
return; | |
} | |
try { | |
numberPrinter.execute(); | |
} catch {} | |
this.counter.increment(); | |
} | |
} | |
class Printer implements Executor { | |
private message: string; | |
constructor(message: string) { | |
this.message = message; | |
} | |
execute() { | |
console.log(this.message); | |
throw new Error(); | |
} | |
} | |
class CounterDivisibilityChecker implements Checker { | |
private counter: Counter; | |
private number: number; | |
constructor(counter: Counter, number: number) { | |
this.counter = counter; | |
this.number = number; | |
} | |
check() { | |
return this.counter.value % this.number === 0; | |
} | |
} | |
class Looper { | |
doWhile(condition: Checker, body: Executor) { | |
while (condition.check()) { | |
body.execute(); | |
} | |
} | |
} | |
class ConditionalExecutor { | |
executeConditionally(checker: Checker, body: Executor) { | |
if (checker.check()) { | |
body.execute(); | |
} | |
} | |
} | |
class DoubleChecker implements Checker { | |
private checker1: Checker; | |
private checker2: Checker; | |
constructor(checker1: Checker, checker2: Checker) { | |
this.checker1 = checker1; | |
this.checker2 = checker2; | |
} | |
check() { | |
return this.checker1.check() && this.checker2.check(); | |
} | |
} | |
interface Checker { | |
check(): boolean; | |
} | |
interface Executor { | |
execute(): void; | |
} | |
new FizzBuzz(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment