你是否曾经在JavaScript
代码中迷失过? 是否曾经感到自己的代码像一团乱麻? 别担心,这就是我们需要设计模式的时候了! 让我们一起探索这些神奇的模式,让你的代码变得像个天才!
序言 总体来说设计模式分为三大类:
创建型模式: 工厂方法模式 、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式: 适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式: 策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
准备好了吗?让我们一起进入JavaScript
设计模式的神奇世界,让你的代码变得像Tony Stark
一样聪明!
工厂方法模式(Factory Method Pattern) 工厂方法模式定义了一个创建对象的接口,但是由子类决定要实例化的类是哪一个
。可以将对象的创建和使用分离
,使得系统更加灵活。其代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Animal { speak ( ) { throw new Error ('This method must be implemented.' ); } }class Dog extends Animal { speak ( ) { return 'Woof!' ; } }class Cat extends Animal { speak ( ) { return 'Meow!' ; } }class AnimalFactory { createAnimal (animalType ) { switch (animalType) { case 'dog' : return new Dog (); case 'cat' : return new Cat (); default : throw new Error (`Invalid animal type: ${animalType} ` ); } } }const animalFactory = new AnimalFactory ();const dog = animalFactory.createAnimal ('dog' );console .log (dog.speak ()); const cat = animalFactory.createAnimal ('cat' );console .log (cat.speak ());
抽象工厂模式(Abstract Factory Pattern) 抽象工厂模式提供了一种封装一组具有相同主题的单个工厂的方式
。它有一个接口,用于创建相关或依赖对象的家族,而不需要指定实际实现的类
。其代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 class AnimalFood { provide() { throw new Error ('This method must be implemented.'); } }class AnimalToy { provide() { throw new Error ('This method must be implemented.'); } }class HighQualityDogFood extends AnimalFood { provide() { return 'High quality dog food'; } }class HighQualityDogToy extends AnimalToy { provide() { return 'High quality dog toy'; } }class CheapCatFood extends AnimalFood { provide() { return 'Cheap cat food'; } }class CheapCatToy extends AnimalToy { provide() { return 'Cheap cat toy'; } }class AnimalProductsAbstractFactory { createFood() { throw new Error ('This method must be implemented.'); } createToy() { throw new Error ('This method must be implemented.'); } }class HighQualityAnimalProductsFactory extends AnimalProductsAbstractFactory { createFood() { return new HighQualityDogFood (); } createToy() { return new HighQualityDogToy (); } }class CheapAnimalProductsFactory extends AnimalProductsAbstractFactory { createFood() { return new CheapCatFood (); } createToy() { return new CheapCatToy (); } } const highQualityAnimalProductsFactory = new HighQualityAnimalProductsFactory (); console.log(highQualityAnimalProductsFactory.createFood().provide()); console.log(highQualityAnimalProductsFactory.createToy().provide()); const cheapAnimalProductsFactory = new CheapAnimalProductsFactory (); console.log(cheapAnimalProductsFactory.createFood().provide()); console.log(cheapAnimalProductsFactory.createToy().provide());
单例模式(Singleton Pattern) 单例模式的目的是确保一个类只有一个实例,并为该实例提供全局访问点
。其代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Logger { constructor ( ) { if (!Logger .instance ) { this .logs = []; Logger .instance = this ; } return Logger .instance ; } log (message ) { this .logs .push (message); console .log (`Logger: ${message} ` ); } printLogCount ( ) { console .log (`Number of logs: ${this .logs.length} ` ); } }const logger = new Logger ();Object .freeze (logger); logger.log ('First message' ); logger.printLogCount (); const anotherLogger = new Logger (); anotherLogger.log ('Second message' ); anotherLogger.printLogCount ();
建造者模式(Builder Pattern) 建造者模式是一种对象创建设计模式,它旨在通过一步步的构建流程来创建复杂对象
。其代码示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 class Sandwich { constructor () { this .ingredients = []; } addIngredient(ingredient) { this .ingredients.push(ingredient); } toString() { return this .ingredients.join(', ' ); } }class SandwichBuilder { constructor () { this .sandwich = new Sandwich(); } reset() { this .sandwich = new Sandwich(); } putMeat(meat) { this .sandwich.addIngredient(meat); } putCheese(cheese) { this .sandwich.addIngredient(cheese); } putVegetables(vegetables) { this .sandwich.addIngredient(vegetables); } get result() { return this .sandwich; } }class SandwichMaker { constructor () { this .builder = new SandwichBuilder(); } createCheeseSteakSandwich() { this .builder.reset(); this .builder.putMeat('ribeye steak' ); this .builder.putCheese('american cheese' ); this .builder.putVegetables(['peppers' , 'onions' ]); return this .builder.result; } }const sandwichMaker = new SandwichMaker();const sandwich = sandwichMaker.createCheeseSteakSandwich(); console.log(`Your sandwich: ${sandwich}`);
原型模式(Prototype Pattern) 原型模式(Prototype Pattern
)是一种创建型设计模式
,它可以用于创建对象的成本相对较高,但对于由相同属性的对象可以通过克隆来创建。原型模式将对象的创建过程和对象的使用过程分离,它通过克隆已有对象来创建新的对象,从而避免了昂贵的对象创建过程。在 JavaScript
中,原型模式的实现很容易,因为它天然支持对象的 clone(即浅拷贝
)。
这是一个使用原型模式的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const carPrototype = { wheels : 4 , color : 'red' , start ( ) { console .log ('Starting the car...' ); }, stop ( ) { console .log ('Stopping the car...' ); }, };const car1 = Object .create (carPrototype);console .log (car1); car1.wheels = 6 ;console .log (car1.wheels ); console .log (car1.color ); car1.start (); car1.stop (); const car2 = Object .create (carPrototype);console .log (car2); car2.color = 'blue' ; console .log (car2.color ); console .log (car2.wheels ); car2.start (); car2.stop ();
在这个例子中,我们创建了一个名为 carPrototype
的原型对象。然后,我们通过 Object.create()
方法克隆了该原型对象。由于我们使用了浅拷贝,所以在使用前我们可以修改对象的属性,并且 car2
和 car1
对象的 start()
和 stop()
方法是相同的,因为它们来自相同的原型对象。
原型模式的一个优点是它提供了一种简便的方式来创建具有相同属性的对象
。它可以减少重复代码,并且在创建对象时节省时间和资源
。当然,它也有一些缺点,例如在使用深拷贝时可能会出现意想不到的问题,因为深拷贝将复制所有属性,而这些属性还可能引用其他对象。
适配器模式(Adapter Pattern) 适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将不兼容的对象包装在适配器中,从而使它们能够在一起工作
。以下是适配器模式的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Target { request ( ) { console .log ('Target: 请求已被调用' ); } }class Adaptee { specificRequest ( ) { console .log ('Adaptee 方法已被访问' ); } }class Adapter extends Target { constructor (adaptee ) { super (); this .adaptee = adaptee; } request ( ) { this .adaptee .specificRequest (); } }const client = new Adapter (new Adaptee ()); client.request ();
在上述代码中,我们有一个目标接口 Target
和一个需要适配的类 Adaptee
。我们通过创建一个适配器类 Adapter
将 Adaptee
转换为 Target
,并使用适配器进行通信的客户端 client
调用 request()
方法,从而实现 Adaptee
的功能。
装饰模式(Decorator Pattern) 装饰模式(Decorator Pattern)是一种结构型设计模式
,它允许在不影响其他对象的情况下,动态地将功能添加到对象中
。以下是装饰模式的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class Component { operation() { console.log('Component :基础操作'); } }class ConcreteComponent extends Component { operation() { console.log('ConcreteComponent :具体操作'); } }class Decorator extends Component { constructor(component) { super (); this .component = component; } operation() { this .component.operation(); } }class ConcreteDecoratorA extends Decorator { operation() { super .operation(); console.log('ConcreteDecoratorA :添加操作'); } }class ConcreteDecoratorB extends Decorator { operation() { super .operation(); console.log('ConcreteDecoratorB :添加操作'); } } const component = new ConcreteComponent (); const decoratorA = new ConcreteDecoratorA (component); const decoratorB = new ConcreteDecoratorB (decoratorA); decoratorB.operation();
在上述代码中,我们有一个抽象组件类 Component
和一个具体组件类 ConcreteComponent
。我们创建了两个装饰器类 ConcreteDecoratorA
和 ConcreteDecoratorB
,它们都继承自 Decorator
类,并且可以添加新的行为到被装饰的对象上。最后,我们实例化 ConcreteComponent
类,将其封装在 ConcreteDecoratorA
和 ConcreteDecoratorB
类中,最终组成一个具有多个操作的对象。
代理模式(Proxy Pattern) 代理模式(Proxy Pattern)是一种结构型设计模式
,它允许在访问对象时提供一个占位符或代理,以控制对对象的访问
。以下是代理模式的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Subject { request ( ) { console .log ('Subject:处理请求' ); } }class RealSubject extends Subject { request ( ) { console .log ('RealSubject:处理请求' ); } }class Proxy extends Subject { constructor (realSubject ) { super (); this .realSubject = realSubject; } request ( ) { if (this .checkAccess ()) { this .realSubject .request (); this .logAccess (); } } checkAccess ( ) { console .log ('Proxy:检查访问权限' ); return true ; } logAccess ( ) { console .log ('Proxy:记录访问日志' ); } }const realSubject = new RealSubject ();const proxy = new Proxy (realSubject); proxy.request ();
在上述代码中,我们有一个主题接口 Subject
和一个真实主题类 RealSubject
。我们创建了一个代理类 Proxy
,它封装了一个真实主题,并在对其进行访问时提供了额外的功能,例如检查访问权限和记录访问日志。我们通过实例化 RealSubject
类并封装它在 Proxy
类中,最终通过代理访问真实的主题对象。
外观模式(Facade Pattern) 外观模式(Facade Pattern)是一种结构型设计模式
,它为一组复杂的子系统提供了一个更简单的接口
。以下是外观模式的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Subsystem1 { operation1 ( ) { console .log ('Subsystem1:执行操作1' ); } }class Subsystem2 { operation2 ( ) { console .log ('Subsystem2:执行操作2' ); } }class Facade { constructor ( ) { this .subsystem1 = new Subsystem1 (); this .subsystem2 = new Subsystem2 (); } operation ( ) { this .subsystem1 .operation1 (); this .subsystem2 .operation2 (); } }const facade = new Facade (); facade.operation ();
在上述代码中,我们有两个子系统 Subsystem1
和 Subsystem2
,它们都提供了复杂的操作。我们通过使用外观模式创建了一个 Facade
类,它的接口更加简单,通过组合 Subsystem1
和 Subsystem2
对象的操作来实现其功能。最后,我们实例化 Facade
类并调用操作方法 operation()
,完成了复杂的功能操作。
桥接模式(Bridge Pattern) 桥接模式(Bridge Pattern)是一种结构型设计模式,它将一个对象的抽象和实现分离开来,从而使它们都可以独立变化
。以下是桥接模式的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Implementor { operationImpl ( ) { console .log ('Implementor:执行操作' ); } }class Abstraction { constructor (implementor ) { this .implementor = implementor; } operation ( ) { this .implementor .operationImpl (); } }class RefinedAbstraction extends Abstraction { otherOperation ( ) { console .log ('RefinedAbstraction:其他操作' ); } }const implementor = new Implementor ();const abstraction = new Abstraction (implementor); abstraction.operation (); const refinedAbstraction = new RefinedAbstraction (implementor); refinedAbstraction.operation (); refinedAbstraction.otherOperation ();
在上述代码中,我们有一个实现类接口 Implementor
和一个抽象类 Abstraction
。我们通过创建一个扩展抽象类 RefinedAbstraction
来扩展抽象类的功能,它们都使用了某个实现类的实例对象。然后,我们实例化 Implementor
并通过在 Abstraction
和 RefinedAbstraction
类的声明中传递 Implementor
对象来创建两个具有不同行为的对象。通过将实现和抽象分离开来,我们可以随意地组合实现与抽象,并使其易于扩展。
组合模式(Composite Pattern) 组合模式(Composite Pattern)是一种结构型设计模式,它使用树形结构来表示对象的部分-整体层次结构
,并使用户能够以统一的方式处理单个对象和对象组合
。以下是组合模式的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 class Component { constructor (name ) { this .name = name; } operation ( ) { console .log (`Component ${this .name} :执行操作` ); } add (component ) { console .log ('Component:不支持的操作' ); } remove (component ) { console .log ('Component:不支持的操作' ); } getChild (index ) { console .log ('Component:不支持的操作' ); } }class Leaf extends Component { constructor (name ) { super (name); } }class Composite extends Component { constructor (name ) { super (name); this .children = []; } add (component ) { this .children .push (component); } remove (component ) { const index = this .children .indexOf (component); if (index >= 0 ) { this .children .splice (index, 1 ); } } getChild (index ) { return this .children [index]; } }const root = new Composite ('根' );const branch1 = new Composite ('树枝1' );const branch2 = new Composite ('树枝2' );const leaf1 = new Leaf ('叶子1' );const leaf2 = new Leaf ('叶子2' );const leaf3 = new Leaf ('叶子3' ); root.add (branch1); root.add (branch2); branch1.add (leaf1); branch1.add (leaf2); branch2.add (leaf3); root.operation (); branch1.operation (); branch1.remove (leaf2); branch2.operation (); root.getChild (0 ).operation ();
在上述代码中,我们有一个抽象构件 Component
,通过创建两个具体构建 Leaf
和 Composite
来扩展抽象构件的功能。 Composite
保持着一个子对象的数组,并实现了在包含其他组件的能力。然后,我们使用所有这些组件来建立一个树形结构, 父节点模型是 Component
对象,而子节点可以是 Component
对象或 Composite
对象。最终,我们可以通过调用操作方法来进行操作。
享元模式(Flyweight Pattern) 享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享对象来最小化内存使用和类实例化的数量
。以下是享元模式的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class FlyweightFactory { constructor ( ) { this .flyweights = {}; } getFlyweight (key ) { if (!this .flyweights [key]) { this .flyweights [key] = new ConcreteFlyweight (key); } return this .flyweights [key]; } }class ConcreteFlyweight { constructor (key ) { this .key = key; } operation ( ) { console .log (`ConcreteFlyweight ${this .key} : 执行操作` ); } }const factory = new FlyweightFactory ();const flyweight1 = factory.getFlyweight ('key' );const flyweight2 = factory.getFlyweight ('key' ); flyweight1.operation (); flyweight2.operation (); console .log (flyweight1 === flyweight2);
在上述代码中,我们有一个 Flyweight 工厂类 FlyweightFactory
,用于创建并管理基础的共享 ConcreteFlyweight
对象。ConcreteFlyweight
对象包含需要共享的数据或状态。我们实例化 FlyweightFactory
,并通过在 FlyweightFactory
的 getFlyweight()
方法中获取对象,以及通过多个对象来验证是否共享相同的对象。最终,结果显示 flyweight1
跟 flyweight2
指向同一个对象,由此证明了共享对象的概念。
策略模式(Strategy Pattern) 策略模式是一种设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换
。策略模式让算法独立于使用它的客户端而独立变化。这种模式属于行为型模式。 示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Strategy { constructor(name) { this .name = name; } execute() {} }class StrategyA extends Strategy { execute() { console.log('Executing strategy A '); } } class StrategyB extends Strategy { execute() { console.log('Executing strategy B '); } }class Context { constructor(strategy) { this .strategy = strategy; } executeStrategy() { this .strategy.execute(); } } let context = new Context (new StrategyA ('A ')); context.executeStrategy(); context.strategy = new StrategyB ('B '); context.executeStrategy();
模板方法模式(Template Method Pattern) 模板方法模式是一种行为设计模式。它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现。模板方法使得子类可以不改变算法的结构即可重新定义该算法的某些特定步骤
。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 class Game { setup ( ) {} start ( ) { this .setup (); this .play (); this .finish (); } play ( ) {} finish ( ) {} }class Chess extends Game { setup ( ) { console .log ('Setting up chess game' ); } play ( ) { console .log ('Playing chess' ); } finish ( ) { console .log ('Finishing chess game' ); } }class TicTacToe extends Game { setup ( ) { console .log ('Setting up TicTacToe game' ); } play ( ) { console .log ('Playing TicTacToe' ); } finish ( ) { console .log ('Finishing TicTacToe game' ); } }let game = new Chess (); game.start (); game = new TicTacToe (); game.start ();
观察者模式(Observer Pattern) 观察者模式是一种行为设计模式,其中对象之间存在一对多的依赖关系。当一个对象的状态发生变化时,它的所有依赖者都得到通知并自动更新。观察者模式将对象之间的关系解耦,使得它们可以独立变化
。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class Subject { constructor ( ) { this .observers = []; } attach (observer ) { this .observers .push (observer); } detach (observer ) { const index = this .observers .indexOf (observer); if (index > -1 ) { this .observers .splice (index, 1 ); } } notify ( ) { for (const observer of this .observers ) { observer.update (this ); } } }class Observer { update (subject ) {} }class ConcreteSubject extends Subject { constructor (state ) { super (); this .state = state; } set_state (state ) { this .state = state; this .notify (); } get_state ( ) { return this .state ; } } class ConcreteObserver extends Observer { update (subject ) { console .log (`Got updated value: ${subject.get_state()} ` ); } }let subject = new ConcreteSubject ('initial state' );let observer = new ConcreteObserver (); subject.attach (observer); subject.set_state ('new state' );
迭代器模式(Iterator Pattern) 迭代器模式是一种行为设计模式,它提供了一种方式来顺序访问集合对象中的元素
。迭代器模式将遍历集合的责任交给迭代器,而不是集合自己。这样就可以将集合的实现和遍历算法的实现分离开来,从而提供更好的灵活性。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Iterator { constructor (items) { this .items = items; this .cursor = 0 ; } has_next() { return this .cursor < this .items.length; } next() { const item = this .items[this .cursor]; this .cursor += 1 ; return item; } }class Collection { constructor () { this .items = []; } add_item(item) { this .items.push(item); } iterator() { return new Iterator(this .items); } }const collection = new Collection(); collection.add_item('item 1' ); collection.add_item('item 2' ); collection.add_item('item 3' );const iterator = collection.iterator();while (iterator.has_next()) { console.log(iterator.next()); }
责任链模式(Chain of Responsibility) 责任链模式(Chain of Responsibility)是一种行为型设计模式。它可以让多个对象都有机会处理请求,从而避免将请求的发送者和接收者耦合在一起
。将这些对象连成一个链,并沿着这条链传递请求,直到有一个对象处理它为止。
实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 class Handler { constructor() { this .nextHandler = null ; } setNextHandler(handler){ this .nextHandler = handler; } handleRequest(request) { if (this .nextHandler !== null ) { return this .nextHandler.handleRequest(request); } return null ; } }class ConcreteHandlerA extends Handler { handleRequest(request) { if (request === 'A ') { return `Handle Request ${request}`; } return super .handleRequest(request); } }class ConcreteHandlerB extends Handler { handleRequest(request) { if (request === 'B ') { return `Handle Request ${request}`; } return super .handleRequest(request); } }class ConcreteHandlerC extends Handler { handleRequest(request) { if (request === 'C ') { return `Handle Request ${request}`; } return super .handleRequest(request); } } const handlerA = new ConcreteHandlerA (); const handlerB = new ConcreteHandlerB (); const handlerC = new ConcreteHandlerC (); handlerA.setNextHandler(handlerB); handlerB.setNextHandler(handlerC); console.log(handlerA.handleRequest('A ')); console.log(handlerA.handleRequest('B ')); console.log(handlerA.handleRequest('C ')); console.log(handlerA.handleRequest('D '));
命令模式(Command) 命令模式(Command)是一种行为型设计模式,它将请求或操作封装到一个对象中,从而允许你将请求或操作的发起者与具体执行者解耦
。命令模式可以将请求或操作参数化,甚至在运行时动态地组合命令
实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 class Command { constructor (receiver ) { this .receiver = receiver; } execute ( ) { throw new Error ('You have to implement the method execute!' ); } }class ConcreteCommandA extends Command { execute ( ) { this .receiver .actionA (); } }class ConcreteCommandB extends Command { execute ( ) { this .receiver .actionB (); } }class Receiver { actionA ( ) { console .log ('Receiver Action A.' ); } actionB ( ) { console .log ('Receiver Action B.' ); } }class Invoker { constructor ( ) { this .commands = new Map (); } setCommand (key, command ) { this .commands .set (key, command); } executeCommand (key ) { const command = this .commands .get (key); if (!command) { console .log (`Command ${key} is not found.` ); return ; } command.execute (); } }const receiver = new Receiver ();const invoker = new Invoker (); invoker.setCommand ('A' , new ConcreteCommandA (receiver)); invoker.setCommand ('B' , new ConcreteCommandB (receiver)); invoker.executeCommand ('A' ); invoker.executeCommand ('B' );
备忘录模式(Memento) 备忘录模式(Memento)是一种行为型设计模式,它允许你在不暴露对象实现细节的情况下保存和恢复对象的状态。备忘录模式涉及到三个角色:备忘录(Memento), 发起人(Originator), 管理者(Caretaker)
。
实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 class Memento { constructor (state ) { this .state = state; } getState ( ) { return this .state ; } }class Originator { constructor (state ) { this .state = state; } setState (state ) { this .state = state; } createMemento ( ) { return new Memento (this .state ); } restoreMemento (memento ) { this .state = memento.getState (); } getState ( ) { return this .state ; } }class Caretaker { constructor ( ) { this .mementos = []; } addMemento (memento ) { this .mementos .push (memento); } getMemento (index ) { return this .mementos [index]; } }const originator = new Originator ('State A' );const caretaker = new Caretaker (); caretaker.addMemento (originator.createMemento ()); originator.setState ('State B' );console .log (`Current State: ${originator.getState()} ` ); originator.restoreMemento (caretaker.getMemento (0 ));console .log (`Current State: ${originator.getState()} ` );
状态模式(State) 状态模式(State)是一种行为型设计模式,它允许对象在其内部状态发生改变时改变其行为
。状态模式通过将每个状态封装在一个类中,使得对于该状态进行的任何操作都可以在该类中处理。从而将状态转换的代码从主要业务逻辑中抽离出来,避免出现大量 if-else 语句
。
实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Context { constructor() { this .state = new ConcreteStateA (this ); } setState(state) { this .state = state; } request() { this .state.handle(); } }class State { constructor(context) { this .context = context; } handle() { throw new Error ('You have to implement the method handle!'); } }class ConcreteStateA extends State { handle() { console.log('Handle State A '); this .context.setState(new ConcreteStateB (this .context)); } }class ConcreteStateB extends State { handle() { console.log('Handle State B '); this .context.setState(new ConcreteStateA (this .context)); } } const context = new Context (); context.request(); context.request(); context.request();
访问者模式(Visitor) 访问者模式(Visitor)是一种行为型设计模式,它允许你将算法封装在一个或多个访问者类中,从而让你在不改变各个元素类接口的前提下定义作用于这些元素的新操作
。
实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Element { accept(visitor ) { throw new Error ('You have to implement the method accept !'); } } class ConcreteElementA extends Element { accept(visitor ) { visitor.visitConcreteElementA(this ); } operationA() { console.log('Operation A of Concrete Element A .'); } } class ConcreteElementB extends Element { accept(visitor ) { visitor.visitConcreteElementB(this ); } operationB() { console.log('Operation B of Concrete Element B .'); } } class Visitor { visitConcreteElementA(element ) { console.log(`Visit Concrete Element A with ${element .operationA ()}`); } visitConcreteElementB(element ) { console.log(`Visit Concrete Element B with ${element .operationB ()}`); } } const elementA = new ConcreteElementA (); const elementB = new ConcreteElementB (); const visitor = new Visitor (); elementA.accept(visitor ); elementB.accept(visitor );
中介者模式(Mediator)是一种行为型设计模式,它允许你减少组件之间的直接依赖关系,将它们通过一个中介者对象进行交互
。通过避免在组件之间显式引用彼此,中介者可以让你更容易地复用组件。
实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Mediator { constructor ( ) { this .components = new Set (); } register (component ) { component.mediator = this ; this .components .add (component); } notify (sender, event ) { this .components .forEach ((component ) => { if (component !== sender) { component.receive (sender, event); } }); } }class Component { constructor (name ) { this .name = name; this .mediator = null ; } send (event ) { console .log (`Send event ${event} from ${this .name} ` ); this .mediator .notify (this , event); } receive (sender, event ) { console .log (`Receive event ${event} from ${sender.name} by ${this .name} ` ); } }const mediator = new Mediator ();const componentA = new Component ('Component A' );const componentB = new Component ('Component B' );const componentC = new Component ('Component C' ); mediator.register (componentA); mediator.register (componentB); mediator.register (componentC); componentA.send ('Hello' );
解释器模式(Interpreter) 解释器模式(Interpreter)是一种行为型设计模式,它能够将一种语言(通常是一种编程语言)或者表达式的文法表示为解析树,并定义一个解释器,使用该解释器来解释这个语言或者表达式
。
实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 class Context { constructor(input) { this .input = input; this .output = 0 ; } }class Expression { interpreter(context) { throw new Error ('You have to implement the method interpreter!'); } }class ThousandExpression extends Expression { interpreter(context) { const str = context.input; if (str.startsWith('M ')) { context.output += 1000 ; context.input = str.slice(1 ); } } }class HundredExpression extends Expression { interpreter(context) { const str = context.input; if (str.startsWith('C ')) { context.output += 100 ; context.input = str.slice(1 ); } else if (str.startsWith('CD ')) { context.output += 400 ; context.input = str.slice(2 ); } else if (str.startsWith('CM ')) { context.output += 900 ; context.input = str.slice(2 ); } } }class TenExpression extends Expression { interpreter(context) { const str = context.input; if (str.startsWith('X ')) { context.output += 10 ; context.input = str.slice(1 ); } else if (str.startsWith('XL ')) { context.output += 40 ; context.input = str.slice(2 ); } else if (str.startsWith('XC ')) { context.output += 90 ; context.input = str.slice(2 ); } } }class OneExpression extends Expression { interpreter(context) { const str = context.input; if (str.startsWith('I ')) { context.output += 1 ; context.input = str.slice(1 ); } else if (str.startsWith('IV ')) { context.output += 4 ; context.input = str.slice(2 ); } else if (str.startsWith('V ')) { context.output += 5 ; context.input = str.slice(1 ); } else if (str.startsWith('IX ')) { context.output += 9 ; context.input = str.slice(2 ); } } }class Interpreter { static parse(roman) { const context = new Context (roman); const tree = [ new ThousandExpression (), new HundredExpression (), new TenExpression (), new OneExpression (), ]; tree.forEach((expression) => expression.interpreter(context)); return context.output; } } console.log(Interpreter .parse('CDXLVIII '));
总结 现在你已经掌握了这些设计模式,是时候让你的代码从“我不知道这是什么”变成“这是我写的,我知道它是什么了”了!快去展示你的新技能吧,让你的同事们惊叹不已!
本文转自 https://juejin.cn/post/7240248679516012603 ,如有侵权,请联系删除。