Skip to content

Instantly share code, notes, and snippets.

@mybearworld
Last active May 20, 2024 07:35
Show Gist options
  • Save mybearworld/d9d657dc29a360cd8e5022e2b93bf5c3 to your computer and use it in GitHub Desktop.
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.
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