InfoQ你应该了解的5种TypeScript设计模式( 三 )

} abstract class Observable { protected observers: Observer = //the list of observers protected state:InternalState = { event: "" } //the internal state observers are watching public addObserver(o:Observer):void { this.observers.push(o) } protected notify { this.observers.forEach( o => o.update(this.state) ) } } //Actual implementations class ConsoleLogger extends Observer { public update(newState: InternalState) { console.log("New internal state update: ", newState) } } class InputElement extends Observable { public click:void { this.state = { event: "click" } this.notify } } const input = new InputElement input.addObserver(new ConsoleLogger) input.click 如你所见 , 通过两个抽象类 , 我们可以定义 Observer , 它代表对 Observable 实体上的更改做出反应的对象 。 在上面的示例中 , 我们假装有一个被点击的 InputElement 实体(类似于你在前端的 HTML 输入字段) , 以及一个 ConsoleLogger , 用于自动记录 Console 发生的所有事情 。 这种模式的优点在于 , 它使我们能够了解 Observable 的内部状态并对其做出反应 , 而不必弄乱其内部代码 。 我们可以继续添加执行其他操作的 Observer , 甚至包括对特定事件做出反应的观察者 , 然后让它们的代码决定对每个通知执行的操作 。
装饰器 装饰器模式会在运行时向现有对象添加行为 。 从某种意义上说 , 你可以将其视为动态继承 , 因为即使你没有创建新类来添加行为 , 也会创建具有扩展功能的新对象 。
比如你有一个带有 move 方法的 Dog 类 , 现在你想扩展其行为 , 因为你想要一只超人狗(当你让它移动时它可以飞起来)和一只游泳狗(当你告诉它移动时就钻进水里) 。
一般来说 , 你会在 Dog 类中添加标准移动行为 , 然后以两种方式扩展该类 , 即 SuperDog 和 SwimmingDog 类 。 但是 , 如果你想将两者混合起来 , 则必须再创建一个新类来扩展它们的行为 。 其实这里有更好的方法 。
组合(Composition)使你可以将自定义行为封装在不同的类中 , 然后使用该模式将原始对象传递给它们的构造器来创建这些类的新实例 。 看一下代码:
abstract class Animal { abstract move: void } abstract class SuperDecorator extends Animal { protected comp: Animal constructor(decoratedAnimal: Animal) { super this.comp = decoratedAnimal } abstract move: void } class Dog extends Animal { public move:void { console.log("Moving the dog...") } } class SuperAnimal extends SuperDecorator { public move:void { console.log("Starts flying...") this.comp.move console.log("Landing...") } } class SwimmingAnimal extends SuperDecorator { public move:void { console.log("Jumps into the water...")