更多精彩内容,欢迎观看:
前端工程中的设计模式应用(上):https://developer.aliyun.com/article/1396344
▐ 结构型
结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
- 桥接模式
桥接模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为不同的层次结构, 从而能在开发时分别使用。
桥接模式结构:
代码实现:
// 定义了所有Implementation类的接口 interface Implementation { operationImplementation(): string; } class Abstraction {// 提供对Implementation的引用,并将所有的实际工作委托给它 protected implementation: Implementation; constructor(implementation: Implementation) { this.implementation = implementation; } public operation(): string { const result = this.implementation.operationImplementation(); return `抽象部分: 基础操作: ${result}`; } } // 在不改变Implementation类的前提下继承Abstraction class ExtendedAbstraction extends Abstraction { public operation(): string { const result = this.implementation.operationImplementation(); return `继承的抽象部分: 继承的操作:${result}`; } } class ConcreteImplementationA implements Implementation { public operationImplementation(): string { return '具体实现A: 这里是A的结果'; } } class ConcreteImplementationB implements Implementation { public operationImplementation(): string { return '具体实现B: 这里是B的结果'; } } // 客户端代码 function clientCode(abstraction: Abstraction) { console.log(abstraction.operation()); } let implementation = new ConcreteImplementationA(); let abstraction = new Abstraction(implementation); clientCode(abstraction); // 抽象部分:基础操作:具体实现A: 这里是A的结果. implementation = new ConcreteImplementationB(); abstraction = new ExtendedAbstraction(implementation); clientCode(abstraction); // 继承的抽象部分: 继承的操作: 具体实现B: 这里是B的结果.
简单来说,对于一个复杂庞大的系统,可以将其分层,第一层是抽象层,第二层为具体层,抽象层可以把对自己的调用委派给实现层实现,而所有的实现层都具有统一接口,所以实现层可以在抽象部分内部进行相互替换。
- 外观模式
外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。
举个现实的例子,淘宝就是一个外观,它提供了你购物、支付、送花上门等接口。
外观模式结构:
代码实现:
// 为一个或多个子系统的复杂逻辑提供简单接口 class Facade { protected subsystem1: Subsystem1; protected subsystem2: Subsystem2; constructor(subsystem1?: Subsystem1, subsystem2?: Subsystem2) { this.subsystem1 = subsystem1 || new Subsystem1(); this.subsystem2 = subsystem2 || new Subsystem2(); } public operation(): string { let result = 'Facade初始化子系统'; result += this.subsystem1.operation1(); result += this.subsystem2.operation1(); result += 'Facade命令子系统执行操作'; result += this.subsystem1.operationN(); result += this.subsystem2.operationZ(); return result; } } class Subsystem1 { public operation1(): string { return 'Subsystem1准备好了!'; } public operationN(): string { return 'Subsystem1执行!'; } } class Subsystem2 { public operation1(): string { return 'Subsystem2准备好了'; } public operationZ(): string { return 'Subsystem2执行!'; } } // 客户端代码 function clientCode(facade: Facade) { console.log(facade.operation()); } const subsystem1 = new Subsystem1(); const subsystem2 = new Subsystem2(); const facade = new Facade(subsystem1, subsystem2); clientCode(facade); // Facade初始化子系统 Subsystem1准备好了! Subsystem2准备好了 Facade命令子系统执行操作 Subsystem1执行! Subsystem2执行!
- 组合模式
组合模式是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。
举个现实的例子,比如学校,学校由年级组成,年级由班级组成,班级由学生个体组成。当学校下达重要通知时,是逐级下发的,通过一个个层级的传递,直到每个学生都接收到通知。
组合模式结构:
代码示例:
// 描述了 简单 和 复杂 所共有的操作 abstract class Component { protected parent!: Component | null; public setParent(parent: Component | null) { this.parent = parent; } public getParent(): Component | null { return this.parent; } public add(component: Component): void { } public remove(component: Component): void { } public isComposite(): boolean { return false; } public abstract operation(): string; } // 叶子 执行具体的工作,不再包含子项目 class Leaf extends Component { public operation(): string { return 'Leaf'; } } // 容器 将具体工作委托给子项目,然后汇总结果 class Composite extends Component { protected children: Component[] = []; public add(component: Component): void { this.children.push(component); component.setParent(this); } public remove(component: Component): void { const componentIndex = this.children.indexOf(component); this.children.splice(componentIndex, 1); component.setParent(null); } public isComposite(): boolean { return true; } public operation(): string { const results = []; for (const child of this.children) { results.push(child.operation()); } return `Branch(${results.join('+')})`; } } // 客户端 通过基础接口与所有的组件链接 function clientCode(component: Component) { console.log(`RESULT: ${component.operation()}`); } const simple = new Leaf(); console.log('Client: 简单的:'); clientCode(simple); // RESULT: Leaf const tree = new Composite(); const branch1 = new Composite(); branch1.add(new Leaf()); branch1.add(new Leaf()); const branch2 = new Composite(); branch2.add(new Leaf()); tree.add(branch1); tree.add(branch2); console.log('Client: 复杂的:'); clientCode(tree); // RESULT: Branch(Branch(Leaf+Leaf)+Branch(Leaf)) function clientCode2(component1: Component, component2: Component) { if (component1.isComposite()) { component1.add(component2); } console.log(`RESULT: ${component1.operation()}`); } console.log('Client: 当在管理树状结构时,不需要检查组件类'); clientCode2(tree, simple); // RESULT: Branch(Branch(Leaf+Leaf)+Branch(Leaf)+Leaf)
简单来说,组合模式最主要的功能是在整个树状结构上递归调用方法并对结果进行汇总。
- 装饰器模式
装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
举个现实的例子,比如天冷加衣服,觉得冷了可以加一件毛衣,还觉得冷可以再加一件羽绒服。这些衣物扩展了你的基本行为,但他们并不是你的一部分,如果不再需要了,可以随时脱掉。如果下雨了,还可以随时再加一件雨衣。
装饰器模式结构:
代码示例:
interface Component { // 定义了可被装饰器修改的操作 operation(): string; } // 具体部件提供了操作的默认实现 但是装饰类可以改变这些操作 class ConcreteComponent implements Component { public operation(): string { return 'ConcreteComponent'; } } // class Decorator implements Component { protected component: Component; constructor(component: Component) { this.component = component; } public operation(): string { return this.component.operation(); } } class ConcreteDecoratorA extends Decorator { public operation(): string { return `ConcreteDecoratorA(${super.operation()})`; } } class ConcreteDecoratorB extends Decorator { public operation(): string { return `ConcreteDecoratorB(${super.operation()})`; } } // 客户端 function clientCode(component: Component) { console.log(`RESULT: ${component.operation()}`); } const simple = new ConcreteComponent(); console.log('Client: 简单的部件:'); clientCode(simple); // RESULT: ConcreteComponent const decorator1 = new ConcreteDecoratorA(simple); const decorator2 = new ConcreteDecoratorB(decorator1); console.log('Client: 装饰器部件:'); clientCode(decorator2); // RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))
简答来说,目标对象和装饰器是遵循同一接口的,因此可以使用装饰对对象进行无限次的封装,结果对象将获得所有装饰器装饰后的叠加结果。
- 适配器模式
适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。
举个现实的例子,电源适配器。
适配器模式结构:
代码示例:
class Target { // 目标 public request(): string { return 'Target: The default target\'s behavior.'; } } class Adaptee { // 被适配者 public specificRequest(): string { return '.eetpadA eht fo roivaheb laicepS'; } } class Adapter extends Target { private adaptee: Adaptee; constructor(adaptee: Adaptee) { super(); this.adaptee = adaptee; } public request(): string { const result = this.adaptee.specificRequest().split('').reverse().join(''); return `Adapter: (TRANSLATED) ${result}`; } } // 客户端 支持所有遵循Target接口的类 function clientCode(target: Target) { console.log(target.request()); } const target = new Target(); clientCode(target); // Target: 这是默认的目标行为. const adaptee = new Adaptee(); console.log(`Adaptee: ${adaptee.specificRequest()}`); // Adaptee: .eetpadA eht fo roivaheb laicepS const adapter = new Adapter(adaptee); clientCode(adapter); // Adapter: (TRANSLATED) Special behavior of the Adaptee.
简而言之,适配器接收对一个对象的调用,并将其转换为另一个对象可识别的格式和接口。
- 代理模式
代理模式是一种结构型设计模式, 它能够提供对象的替代品或占位符。代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。
举个现实的例子,我们的数字支付工具比如支付宝支付、微信支付就是现金的代理,他们都实现了同一的接口,均可以用于支付。消费者和被消费者都会非常的满意,因为双方都很便捷。
代理模式结构:
代码示例:
interface ServiceInterface { // 声明服务接口,实际服务者和代理者要遵循相同的接口 request(): void; } // 实际服务者 class Service implements ServiceInterface { public request(): void { console.log('实际服务者: 处理请求'); } } // 代理者 class Proxy implements ServiceInterface { private service: Service; // 代理会维护一个对实际服务者的引用 constructor(service: Service) { this.service = service; } public request(): void { if (this.checkAccess()) { this.service.request(); this.logAccess(); } } private checkAccess(): boolean { // 在这里执行一些处理 console.log('代理:触发真正的请求之前进行检查访问'); return true; } private logAccess(): void { console.log('代理:请求之后的一些处理'); } } // 客户端代码 function clientCode(serviceInterface: ServiceInterface) { serviceInterface.request(); } // 客户端直接调用实际服务者 const service = new Service(); clientCode(service); // 实际服务者: 处理请求. // 客户端通过代理调用实际服务者 const proxy = new Proxy(service); clientCode(proxy); // 代理:触发真正的请求之前进行检查访问. 实际服务者: 处理请求. 代理:请求之后的一些处理
- 享元模式
享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
享受元模式结构:
代码示例:
// 存储共有状态,接收其余状态 class Flyweight { private sharedState: any; constructor(sharedState: any) { this.sharedState = sharedState; } public operation(uniqueState): void { const s = JSON.stringify(this.sharedState); const u = JSON.stringify(uniqueState); console.log(`享元: 共享 (${s}),独有 (${u})`); } } // 创建和管理Flyweight对象 class FlyweightFactory { private flyweights: {[key: string]: Flyweight} = <any>{}; constructor(initialFlyweights: string[][]) { for (const state of initialFlyweights) { this.flyweights[this.getKey(state)] = new Flyweight(state); } } private getKey(state: string[]): string { return state.join('_'); } public getFlyweight(sharedState: string[]): Flyweight { const key = this.getKey(sharedState); if (!(key in this.flyweights)) { console.log('享元工厂: 不能够寻找到享元,创建一个新的'); this.flyweights[key] = new Flyweight(sharedState); } else { console.log('享元工厂: 找到了已存在的享元'); } return this.flyweights[key]; } public listFlyweights(): void { const count = Object.keys(this.flyweights).length; console.log(`享元工厂: 我有 ${count} 个享元:`); for (const key in this.flyweights) { console.log(key); } } } // 客户端代码 先创建一些预先填充的flyweight const factory = new FlyweightFactory([ ['Chevrolet', 'Camaro2018', 'pink'], ['Mercedes Benz', 'C300', 'black'], ['Mercedes Benz', 'C500', 'red'], ['BMW', 'M5', 'red'], ['BMW', 'X6', 'white'], ]); factory.listFlyweights(); // 享元工厂: 我有5个享元: // Chevrolet-Camaro2018-pink // Mercedes Benz-C300-black // Mercedes Benz-C500-red // BMW-M5-red // BMW-X6-white function addCarToPoliceDatabase( ff: FlyweightFactory, plates: string, owner: string, brand: string, model: string, color: string, ) { const flyweight = ff.getFlyweight([brand, model, color]); flyweight.operation([plates, owner]); } addCarToPoliceDatabase(factory, 'CL234IR', 'James Doe', 'BMW', 'M5', 'red'); // 享元工厂: 找到了已存在的享元. // 享元: 共享 (['BMW', 'M5', 'red']), 独有 (['CL234IR', 'James Doe']). addCarToPoliceDatabase(factory, 'CL234IR', 'James Doe', 'BMW', 'X1', 'red'); // 享元工厂: 不能够寻找到享元,创建一个新的 // 享元: 共享 (['BMW', 'X1', 'red']), 独有 (['CL234IR', 'James Doe']) state. factory.listFlyweights(); // 享元工厂: 我有6个享元: // Chevrolet-Camaro2018-pink // Mercedes Benz-C300-black // Mercedes Benz-C500-red // BMW-M5-red // BMW-X6-white // BMW-X1-red
简单来说,享元模式通过共享多个对象的部分状态来实现上述功能,享元会将不同对象的相同数据进行缓存以节省内存。如同上述例子中,车的型号会被存储在享元中,车的主人是独享的。当将一个 主人-车辆 数据加入数据库中时,享元工厂先查找享元中是否已存在该型号车的数据,有的话直接返回,没有的话创建这个型号。
行为型
行为模式负责对象间的高效沟通和职责委派。
- 迭代器模式
迭代器模式是一种行为设计模式, 它能够在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。
举个现实的例子,假如去北京旅游,故宫、长城、天安门、颐和园、北大、清华是此次旅行的游览目标,可以将他们组成一个目的地集合。第一种游览方式是按照自己的意愿顺序去游玩,第二种方式是按照某些博主推荐的游览顺序游玩,第三种方式是报个旅行团,按照旅行团安排的顺序游玩。以上这三种选择就是目的地集合的迭代器。
迭代器模式结构:
代码示例:
interface Iterator<T> { current(): T; // 返回当前的元素 next(): T; // 返回下一个元素 key(): number; // 返回当前元素的key valid(): boolean; // 检测当前位置是否是有效的 rewind(): void; // 将迭代器回退到第一个元素 } interface Aggregator { getIterator(): Iterator<string>; // 获取外部迭代器 } // 具体迭代器实现各种遍历算法。这些类在任何时候都存储当前遍历位置 class AlphabeticalOrderIterator implements Iterator<string> { private collection: WordsCollection; private position: number = 0; private reverse: boolean = false; constructor(collection: WordsCollection, reverse: boolean = false) { this.collection = collection; this.reverse = reverse; if (reverse) { this.position = collection.getCount() - 1; } } public rewind() { this.position = this.reverse ? this.collection.getCount() - 1 : 0; } public current(): string { return this.collection.getItems()[this.position]; } public key(): number { return this.position; } public next(): string { const item = this.collection.getItems()[this.position]; this.position += this.reverse ? -1 : 1; return item; } public valid(): boolean { if (this.reverse) { return this.position >= 0; } return this.position < this.collection.getCount(); } } // 具体集合提供一个或多个方法来检索新的迭代器实例,与集合类兼容。 class WordsCollection implements Aggregator { private items: string[] = []; public getItems(): string[] { return this.items; } public getCount(): number { return this.items.length; } public addItem(item: string): void { this.items.push(item); } public getIterator(): Iterator<string> { return new AlphabeticalOrderIterator(this); } public getReverseIterator(): Iterator<string> { return new AlphabeticalOrderIterator(this, true); } } // 客户端代码 const collection = new WordsCollection(); collection.addItem('First'); collection.addItem('Second'); collection.addItem('Third'); const iterator = collection.getIterator(); console.log('Straight traversal:'); while (iterator.valid()) { console.log(iterator.next()); // First Second Third } const reverseIterator = collection.getReverseIterator(); while (reverseIterator.valid()) { console.log(reverseIterator.next()); // Third Second First }
最简单的理解方式的话,其实就是我们常说的ES6中的迭代器。
- 解释器模式
解释器模式是一种行为设计模式。给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。
代码示例:
class Context { constructor() { this._list = []; // 存放 终结符表达式 this._sum = 0; // 存放 非终结符表达式(运算结果) } get sum() { return this._sum; } set sum(newValue) { this._sum = newValue; } add(expression) { this._list.push(expression); } get list() { return [...this._list]; } } class PlusExpression { interpret(context) { if (!(context instanceof Context)) { throw new Error("TypeError"); } context.sum = ++context.sum; } } class MinusExpression { interpret(context) { if (!(context instanceof Context)) { throw new Error("TypeError"); } context.sum = --context.sum; } } // 客户端代码 const context = new Context(); // 添加加法表达式 context.add(new PlusExpression()); // 添加加法表达式 context.add(new PlusExpression()); // 添加减法表达式 context.add(new MinusExpression()); // 依次执行: 加法、加法、减法表达式 context.list.forEach(expression => expression.interpret(context)); console.log(context.sum); // 1
- 观察者模式
观察者模式是一种行为设计模式,又被称为发布订阅模式。它允许定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
举个现实的例子,比如你订阅了人民日报,每当它发版的时候,都会有邮递员将报纸送到你手中,而不需要你跑去报刊亭自己购买。出版社为发布者,你为订阅者,出版社维护着一份订阅者的名单,当你不想再订阅时可以申请退出订阅。
观察者模式结构:
代码示例:
interface Subject { // 声明了一组管理订阅者的方法 attach(observer: Observer): void; // 为订阅者附加观察者 detach(observer: Observer): void; // 从订阅者身上剥离观察者 notify(): void; // 通知所有观察者的方法 } // 具体订阅者 class ConcreteSubject implements Subject { public state: number; private observers: Observer[] = []; public attach(observer: Observer): void { const isExist = this.observers.includes(observer); if (isExist) { return console.log('Subject: Observer has been attached already.'); } console.log('Subject: Attached an observer.'); this.observers.push(observer); } public detach(observer: Observer): void { const observerIndex = this.observers.indexOf(observer); if (observerIndex === -1) { return console.log('Subject: Nonexistent observer.'); } this.observers.splice(observerIndex, 1); console.log('Subject: Detached an observer.'); } // 触发每个订阅者更新 public notify(): void { console.log('Subject: Notifying observers...'); for (const observer of this.observers) { observer.update(this); } } // 业务逻辑等,当其发生变化时,触发notify方法 public someBusinessLogic(): void { console.log('\nSubject: I\'m doing something important.'); this.state = Math.floor(Math.random() * (10 + 1)); console.log(`Subject: My state has just changed to: ${this.state}`); this.notify(); } } interface Observer { // 声明更新方法,由订阅者调用 // Receive update from subject. update(subject: Subject): void; } // 具体观察者 class ConcreteObserverA implements Observer { public update(subject: Subject): void { if (subject instanceof ConcreteSubject && subject.state < 3) { console.log('ConcreteObserverA: Reacted to the event.'); } } } class ConcreteObserverB implements Observer { public update(subject: Subject): void { if (subject instanceof ConcreteSubject && (subject.state === 0 || subject.state >= 2)) { console.log('ConcreteObserverB: Reacted to the event.'); } } } // 客户端代码 const subject = new ConcreteSubject(); const observer1 = new ConcreteObserverA(); subject.attach(observer1); // Subject: Attached an observer. const observer2 = new ConcreteObserverB(); subject.attach(observer2); // Subject: Attached an observer. subject.someBusinessLogic(); // Subject: I'm doing something important. Subject: My state has just changed to: 6. Subject: Notifying observers... ConcreteObserverB: Reacted to the event. subject.someBusinessLogic(); // Subject: I'm doing something important. Subject: My state has just changed to: 1. Subject: Notifying observers... ConcreteObserverA: Reacted to the event. subject.detach(observer2); // Subject: Detached an observer. subject.someBusinessLogic(); // Subject: I'm doing something important. Subject: My state has just changed to: 5. Subject: Notifying observers...
- 中介者模式
中介者模式是一种行为设计模式, 能够减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。
举个现实的例子,航班与航班之间不会直接沟通,而是与塔台沟通,从而可来避免航线交叉、重复而可能引起的飞机之间的碰撞。当然现实中还有很多其他的例子,中介者模式其实就是我们字面上理解的中介者的意思。
中介者模式结构:
代码示例:
interface Mediator { notify(sender: object, event: string): void; } class ConcreteMediator implements Mediator { private component1: Component1; private component2: Component2; constructor(c1: Component1, c2: Component2) { this.component1 = c1; this.component1.setMediator(this); this.component2 = c2; this.component2.setMediator(this); } public notify(sender: object, event: string): void { if (event === 'A') { console.log('Mediator reacts on A and triggers following operations:'); this.component2.doC(); } if (event === 'D') { console.log('Mediator reacts on D and triggers following operations:'); this.component1.doB(); this.component2.doC(); } } } class BaseComponent { protected mediator: Mediator; constructor(mediator?: Mediator) { this.mediator = mediator!; } public setMediator(mediator: Mediator): void { this.mediator = mediator; } } class Component1 extends BaseComponent { public doA(): void { console.log('Component 1 does A.'); this.mediator.notify(this, 'A'); } public doB(): void { console.log('Component 1 does B.'); this.mediator.notify(this, 'B'); } } class Component2 extends BaseComponent { public doC(): void { console.log('Component 2 does C.'); this.mediator.notify(this, 'C'); } public doD(): void { console.log('Component 2 does D.'); this.mediator.notify(this, 'D'); } } // 客户端代码 const c1 = new Component1(); const c2 = new Component2(); const mediator = new ConcreteMediator(c1, c2); // 触发操作A c1.doA(); // Component 1 does A. Mediator reacts on A and triggers following operations: Component 2 does C. // 触发操作B c2.doD(); // Component 2 does D. Mediator reacts on D and triggers following operations: Component 1 does B. Component 2 does C.
程序组件通过特殊的中介者对象进行间接沟通, 达到了减少组件之间依赖关系的目的。
- 访问者模式
访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。
举个现实的例子,一个房地产销售人员,他可以向各种各样的人推销,如果面对富豪,他推销别墅,如果面对高收入人群,他推销普大平层,如果面对普通收入人群,他推销普通高层。
访问者模式结构:
代码示例:
interface Component { accept(visitor: Visitor): void; } class ConcreteComponentA implements Component { public accept(visitor: Visitor): void { visitor.visitConcreteComponentA(this); } public exclusiveMethodOfConcreteComponentA(): string { return 'A'; } } class ConcreteComponentB implements Component { public accept(visitor: Visitor): void { visitor.visitConcreteComponentB(this); } public specialMethodOfConcreteComponentB(): string { return 'B'; } } interface Visitor { visitConcreteComponentA(element: ConcreteComponentA): void; visitConcreteComponentB(element: ConcreteComponentB): void; } class ConcreteVisitor1 implements Visitor { public visitConcreteComponentA(element: ConcreteComponentA): void { console.log(`${element.exclusiveMethodOfConcreteComponentA()} + ConcreteVisitor1`); } public visitConcreteComponentB(element: ConcreteComponentB): void { console.log(`${element.specialMethodOfConcreteComponentB()} + ConcreteVisitor1`); } } class ConcreteVisitor2 implements Visitor { public visitConcreteComponentA(element: ConcreteComponentA): void { console.log(`${element.exclusiveMethodOfConcreteComponentA()} + ConcreteVisitor2`); } public visitConcreteComponentB(element: ConcreteComponentB): void { console.log(`${element.specialMethodOfConcreteComponentB()} + ConcreteVisitor2`); } } // 客户端代码 function clientCode(components: Component[], visitor: Visitor) { // ... for (const component of components) { component.accept(visitor); } // ... } const components = [ new ConcreteComponentA(), new ConcreteComponentB(), ]; // 通过基础访问者接口,客户端代码与所有的访问者一同工作 const visitor1 = new ConcreteVisitor1(); clientCode(components, visitor1); // A + ConcreteVisitor1 B + ConcreteVisitor1 // 同样的客户端代码可以与不同类型的访问者一同工作 const visitor2 = new ConcreteVisitor2(); clientCode(components, visitor2); // A + ConcreteVisitor2 B + ConcreteVisitor2
- 状态模式
状态模式是一种行为设计模式, 可以在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。
举个实际的例子,你的手机,有话费状态,可以打电话,无话费状态,不可以打电话。设计上就是不同的状态下所对应的功能不同。
状态模式结构:
代码示例:
class Context { private state: State; constructor(state: State) { this.transitionTo(state); } public transitionTo(state: State): void { console.log(`Context: Transition to ${(<any>state).constructor.name}.`); this.state = state; this.state.setContext(this); } public request1(): void { this.state.handle1(); } public request2(): void { this.state.handle2(); } } abstract class State { protected context: Context; public setContext(context: Context) { this.context = context; } public abstract handle1(): void; public abstract handle2(): void; } class ConcreteStateA extends State { public handle1(): void { console.log('ConcreteStateA handles request1.'); console.log('ConcreteStateA wants to change the state of the context.'); this.context.transitionTo(new ConcreteStateB()); } public handle2(): void { console.log('ConcreteStateA handles request2.'); } } class ConcreteStateB extends State { public handle1(): void { console.log('ConcreteStateB handles request1.'); } public handle2(): void { console.log('ConcreteStateB handles request2.'); console.log('ConcreteStateB wants to change the state of the context.'); this.context.transitionTo(new ConcreteStateA()); } } // 客户端代码 const context = new Context(new ConcreteStateA()); context.request1(); // Context: Transition to ConcreteStateA. ConcreteStateA handles request1. ConcreteStateA wants to change the state of the context. context.request2(); // Context: Transition to ConcreteStateB. ConcreteStateB handles request2. ConcreteStateB wants to change the state of the context. Context: Transition to ConcreteStateA.
更多精彩内容,欢迎观看:
前端工程中的设计模式应用(下):https://developer.aliyun.com/article/1396341