Closed j03y14 closed 4 months ago
interface Quackable { quack(): void; } class MallardDuck implements Quackable { quack() { console.log('꽉꽉'); } } class RedheadDuck implements Quackable { quack() { console.log('꽉꽉'); } } class DuckCall implements Quackable { quack() { console.log('꽥꽥'); } } class RubberDuck implements Quackable { quack() { console.log('삑삑'); } } class Goose { honk() { console.log('끽끽'); } } class GooseAdapter implements Quackable { constructor(private goose: Goose) {} quack() { this.goose.honk(); } } function simulate(duck: Quackable) { duck.quack(); } simulate(new MallardDuck()); simulate(new RedheadDuck()); simulate(new DuckCall()); simulate(new RubberDuck()); simulate(new GooseAdapter(new Goose()));
만약 오리 클래스는 그대로 두면서 오리가 꽥꽥 소리낸 횟수를 세려면 어떤 패턴을 써야될까?
interface Quackable { quack(): void; } class MallardDuck implements Quackable { quack() { console.log('꽉꽉'); } } class RedheadDuck implements Quackable { quack() { console.log('꽉꽉'); } } class DuckCall implements Quackable { quack() { console.log('꽥꽥'); } } class RubberDuck implements Quackable { quack() { console.log('삑삑'); } } class Goose { honk() { console.log('끽끽'); } } class GooseAdapter implements Quackable { constructor(private goose: Goose) {} quack() { this.goose.honk(); } } function simulate(duck: Quackable) { duck.quack(); } class QuackCounter implements Quackable { duck: Quackable; static numberOfQuacks = 0; constructor(duck: Quackable) { this.duck = duck; } quack() { this.duck.quack(); QuackCounter.numberOfQuacks++; } } // simulate(new MallardDuck()); // simulate(new RedheadDuck()); // simulate(new DuckCall()); // simulate(new RubberDuck()); // simulate(new GooseAdapter(new Goose())); const mallardDuck = new MallardDuck(); const redheadDuck = new RedheadDuck(); const duckCall = new DuckCall(); const rubberDuck = new RubberDuck(); const gooseAdapter = new GooseAdapter(new Goose()); const mallardDuckCounter = new QuackCounter(mallardDuck); const redheadDuckCounter = new QuackCounter(redheadDuck); const duckCallCounter = new QuackCounter(duckCall); const rubberDuckCounter = new QuackCounter(rubberDuck); const gooseAdapterCounter = new QuackCounter(gooseAdapter); simulate(mallardDuckCounter); simulate(redheadDuckCounter); simulate(duckCallCounter); simulate(rubberDuckCounter); simulate(gooseAdapterCounter); console.log(QuackCounter.numberOfQuacks);
어쩌다 counter를 붙이는걸 까먹는 경우가 있다. 오리 생성을 캡슐화 해서 빠지지 않도록 해준다.
interface Quackable { quack(): void; } class MallardDuck implements Quackable { quack() { console.log('꽉꽉'); } } class RedheadDuck implements Quackable { quack() { console.log('꽉꽉'); } } class DuckCall implements Quackable { quack() { console.log('꽥꽥'); } } class RubberDuck implements Quackable { quack() { console.log('삑삑'); } } class Goose { honk() { console.log('끽끽'); } } class GooseAdapter implements Quackable { constructor(private goose: Goose) {} quack() { this.goose.honk(); } } function simulate(duck: Quackable) { duck.quack(); } class QuackCounter implements Quackable { duck: Quackable; static numberOfQuacks = 0; constructor(duck: Quackable) { this.duck = duck; } quack() { this.duck.quack(); QuackCounter.numberOfQuacks++; } } abstract class AbstractDuckFactory { abstract createMallardDuck(): Quackable; abstract createRedheadDuck(): Quackable; abstract createDuckCall(): Quackable; abstract createRubberDuck(): Quackable; } class CountingDuckFactory extends AbstractDuckFactory { createDuckCall(): Quackable { return new QuackCounter(new DuckCall()); } createMallardDuck(): Quackable { return new QuackCounter(new MallardDuck()); } createRedheadDuck(): Quackable { return new QuackCounter(new RedheadDuck()); } createRubberDuck(): Quackable { return new QuackCounter(new RubberDuck()); } } const duckFactory = new CountingDuckFactory(); const mallardDuck = duckFactory.createMallardDuck(); const redheadDuck = duckFactory.createRedheadDuck(); const duckCall = duckFactory.createDuckCall(); const rubberDuck = duckFactory.createRubberDuck(); simulate(mallardDuck); simulate(redheadDuck); simulate(duckCall); simulate(rubberDuck); simulate(new GooseAdapter(new Goose())); console.log(QuackCounter.numberOfQuacks);
오리들을 한 번에 관리하고 싶다.
interface Quackable { quack(): void; } class MallardDuck implements Quackable { quack() { console.log('꽉꽉'); } } class RedheadDuck implements Quackable { quack() { console.log('꽉꽉'); } } class DuckCall implements Quackable { quack() { console.log('꽥꽥'); } } class RubberDuck implements Quackable { quack() { console.log('삑삑'); } } class Goose { honk() { console.log('끽끽'); } } class GooseAdapter implements Quackable { constructor(private goose: Goose) {} quack() { this.goose.honk(); } } function simulate(duck: Quackable) { duck.quack(); } class QuackCounter implements Quackable { duck: Quackable; static numberOfQuacks = 0; constructor(duck: Quackable) { this.duck = duck; } quack() { this.duck.quack(); QuackCounter.numberOfQuacks++; } } abstract class AbstractDuckFactory { abstract createMallardDuck(): Quackable; abstract createRedheadDuck(): Quackable; abstract createDuckCall(): Quackable; abstract createRubberDuck(): Quackable; } class CountingDuckFactory extends AbstractDuckFactory { createDuckCall(): Quackable { return new QuackCounter(new DuckCall()); } createMallardDuck(): Quackable { return new QuackCounter(new MallardDuck()); } createRedheadDuck(): Quackable { return new QuackCounter(new RedheadDuck()); } createRubberDuck(): Quackable { return new QuackCounter(new RubberDuck()); } createGooseAdapter(): Quackable { return new GooseAdapter(new Goose()); } } class Flock implements Quackable { ducks: Quackable[] = []; add(duck: Quackable) { this.ducks.push(duck); } quack() { this.ducks.forEach(duck => duck.quack()); } } const duckFactory = new CountingDuckFactory(); const mallardDuck = duckFactory.createMallardDuck(); const redheadDuck = duckFactory.createRedheadDuck(); const duckCall = duckFactory.createDuckCall(); const rubberDuck = duckFactory.createRubberDuck(); const flockOfDucks = new Flock(); flockOfDucks.add(mallardDuck); flockOfDucks.add(redheadDuck); flockOfDucks.add(duckCall); flockOfDucks.add(rubberDuck); simulate(flockOfDucks); console.log(QuackCounter.numberOfQuacks);
오리를 관찰하고 싶음.
interface Observer { update(duck: QuackObservable): void; } interface QuackObservable { registerObserver(observer: Observer): void; notifyObservers(): void; } interface Quackable extends QuackObservable { quack(): void; } class Observable implements QuackObservable { observers: Observer[] = []; quackObservable: QuackObservable; constructor(quackObservable: QuackObservable) { this.quackObservable = quackObservable; } registerObserver(observer: Observer) { this.observers.push(observer); } notifyObservers() { this.observers.forEach(observer => observer.update(this.quackObservable)); } } class MallardDuck implements Quackable { observable: Observable; constructor() { this.observable = new Observable(this); } quack() { console.log('꽉꽉'); this.notifyObservers(); } registerObserver(observer: Observer) { this.observable.registerObserver(observer); } notifyObservers() { this.observable.notifyObservers(); } } class RedheadDuck implements Quackable { observable: Observable; constructor() { this.observable = new Observable(this); } quack() { console.log('꽉꽉'); this.notifyObservers(); } registerObserver(observer: Observer) { this.observable.registerObserver(observer); } notifyObservers() { this.observable.notifyObservers(); } } class DuckCall implements Quackable { observable: Observable; constructor() { this.observable = new Observable(this); } quack() { console.log('꽥꽥'); this.notifyObservers(); } registerObserver(observer: Observer) { this.observable.registerObserver(observer); } notifyObservers() { this.observable.notifyObservers(); } } class RubberDuck implements Quackable { observalbe: Observable; constructor() { this.observalbe = new Observable(this); } quack() { console.log('삑삑'); } registerObserver(observer: Observer) { this.observalbe.registerObserver(observer); } notifyObservers() { this.observalbe.notifyObservers(); } } class Goose { honk() { console.log('끽끽'); } } class GooseAdapter implements Quackable { observalbe: Observable; constructor(private goose: Goose) { this.observalbe = new Observable(this); } quack() { this.goose.honk(); this.notifyObservers(); } registerObserver(observer: Observer) { this.observalbe.registerObserver(observer); } notifyObservers() { this.observalbe.notifyObservers(); } } function simulate(duck: Quackable) { duck.quack(); } class QuackCounter implements Quackable { duck: Quackable; static numberOfQuacks = 0; constructor(duck: Quackable) { this.duck = duck; } quack() { this.duck.quack(); QuackCounter.numberOfQuacks++; } registerObserver(observer: Observer) { this.duck.registerObserver(observer); } notifyObservers() { this.duck.notifyObservers(); } } abstract class AbstractDuckFactory { abstract createMallardDuck(): Quackable; abstract createRedheadDuck(): Quackable; abstract createDuckCall(): Quackable; abstract createRubberDuck(): Quackable; } class CountingDuckFactory extends AbstractDuckFactory { createDuckCall(): Quackable { return new QuackCounter(new DuckCall()); } createMallardDuck(): Quackable { return new QuackCounter(new MallardDuck()); } createRedheadDuck(): Quackable { return new QuackCounter(new RedheadDuck()); } createRubberDuck(): Quackable { return new QuackCounter(new RubberDuck()); } createGooseAdapter(): Quackable { return new GooseAdapter(new Goose()); } } class Flock implements Quackable { ducks: Quackable[] = []; add(duck: Quackable) { this.ducks.push(duck); } quack() { this.ducks.forEach(duck => duck.quack()); } registerObserver(observer: Observer) { this.ducks.forEach(duck => duck.registerObserver(observer)); } notifyObservers() { this.ducks.forEach(duck => duck.notifyObservers()); } } class Quackologist implements Observer { update(duck: QuackObservable) { console.log('Quackologist: ', duck); } } const duckFactory = new CountingDuckFactory(); const mallardDuck = duckFactory.createMallardDuck(); const redheadDuck = duckFactory.createRedheadDuck(); const duckCall = duckFactory.createDuckCall(); const rubberDuck = duckFactory.createRubberDuck(); const flockOfDucks = new Flock(); flockOfDucks.add(mallardDuck); flockOfDucks.add(redheadDuck); flockOfDucks.add(duckCall); flockOfDucks.add(rubberDuck); const quackologist = new Quackologist(); flockOfDucks.registerObserver(quackologist); simulate(flockOfDucks); console.log(QuackCounter.numberOfQuacks);
만약 오리 클래스는 그대로 두면서 오리가 꽥꽥 소리낸 횟수를 세려면 어떤 패턴을 써야될까?
어쩌다 counter를 붙이는걸 까먹는 경우가 있다. 오리 생성을 캡슐화 해서 빠지지 않도록 해준다.
오리들을 한 번에 관리하고 싶다.
오리를 관찰하고 싶음.