JavaScript常用的设计模式

179 阅读10分钟
使用ES6实现

设计模式分为三种类型,共23种

  • 创建型模式:单例模式抽象工厂模式建造者模式工厂模式原型模式
  • 结构型模式:适配器模式桥接模式装饰模式组合模式外观模式享元模式代理模式
  • 行为型模式:模版方法模式命令模式迭代器模式观察者模式中介者模式备忘录模式解释器模式(Interpreter模式)状态模式策略模式职责链模式(责任链模式)访问者模式

创建型模式:

~~~# Signleton.js'use strict';
class Singleton {    constructor(data) {        if (Singleton.prototype.Instance === undefined) {            this.data = data;            Singleton.prototype.Instance = this;        }        return Singleton.prototype.Instance;    }}
let ob1 = new Singleton("one");let ob2 = new Singleton("two");let ob3 = new Singleton("Three");ob2.init = 'Object flg';
console.log(ob1 === ob2);console.log(ob1 === ob3);
console.log(ob1);console.log(ob2);console.log(ob3);~~~

~~~# AbstractFactory.js'use strict';
class AbstractFactory {    constructor() {        console.log("AbstractFactory class created");    }
    createProductA(product) {        console.log("AbstractFactory.createProductA created");    }
    createProductB(product) {        console.log("AbstractFactory.createProductB created");    }}
class ConcreteFactory1 extends AbstractFactory {    constructor() {        super();        console.log("ConcreteFactory1 class created");    }
    createProductA(product) {        console.log('ConcreteFactory1 createProductA');        return new ProductA1();    }
    createProductB(product) {        console.log('ConcreteFactory1 createProductB');        return new ProductB1();    }}
class ConcreteFactory2 extends AbstractFactory {    constructor() {        super();        console.log("ConcreteFactory2 class created");    }
    createProductA(product) {        console.log('ConcreteFactory2 createProductA');        return new ProductA2();    }
    createProductB(product) {        console.log('ConcreteFactory2 createProductB');        return new ProductB2();    }}
class AbstractProductA {    constructor() {        console.log('AbstractProductA class created');    }}
class AbstractProductB {    constructor() {        console.log('AbstractProductB class created');    }}
class ProductA1 extends AbstractProductA {    constructor() {        super();        console.log('ProductA1 class created');    }}
class ProductA2 extends AbstractProductA {    constructor() {        super();        console.log('ProductA2 class created');    }}
class ProductB1 extends AbstractProductB {    constructor() {        super();        console.log('ProductB1 class created');    }}
class ProductB2 extends AbstractProductB {    constructor() {        super();        console.log('ProductB2 class created');    }}
var factory1 = new ConcreteFactory1();var productB1 = factory1.createProductB();var productA1 = factory1.createProductA();
var factory2 = new ConcreteFactory2();var productA2 = factory2.createProductA();var productB2 = factory2.createProductB();~~~

~~~# Builder.js'use strict';
class Builder {    constructor() {        console.log('Builder Class created!');    }
    buildPart(partName) {        console.log('Builder.buildPart invoked!');    }}
class ConcreteBuilder extends Builder {    constructor() {        super();        console.log('ConcreteBuilder Class created!');    }
    buildPart(partName) {        super.buildPart(partName);        console.log('ConcreteBuilder.buildPart invoked!');        this.product = new Product(partName);    }    getResult() {        console.log('ConcreteBuilder.getResult invoked!');        return this.product;    }}
class Product {    constructor(material) {        console.log("Product class created");        this.data = material    }}
class Director {    constructor() {        this.structure = ['Prod1', 'Prod2', 'Prod3'];        console.log("Director class created");    }
    construct() {        console.log("Director.Construct created");        for (var prodName in this.structure) {            let builder = new ConcreteBuilder();            builder.buildPart(this.structure[prodName]);            builder.getResult();        }    }}
let director = new Director();director.construct();~~~

  • Factory(工厂模式):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。

~~~# Factory.js'use strict';
class Product {    constructor() {        console.log('Product Class created');    }}
class ConcreteProduct extends Product {    constructor() {        super();        console.log('ConcreteProduct Class created');    }}
class Creator {    constructor() {        console.log('Creator Class created');    }
    factoryMethod() {        console.log('Creator.factoryMethod created');    }
    anOperation() {        console.log('Creator.anOperation created');        this.product = this.factoryMethod();        console.log(this.product instanceof ConcreteProduct);    }}
class ConcreteCreator extends Creator {
    constructor() {        super();        console.log('ConcreteCreator Class created');    }
    factoryMethod() {        return new ConcreteProduct();    }}
var factory = new ConcreteCreator();factory.anOperation();~~~

~~~# Prototype.js'use strict';
class Prototype {    constructor(prototype) {        console.log("Prototype Class created");    }
    setFeature(key, val) {        this[key] = val    }
    clone() {        console.log("Prototype.clone invoked");    }}
class ConcretePrototype1 extends Prototype {    constructor() {        super();        console.log("ConcretePrototype1 created");        this.feature = "feature 1"    }
    clone() {        console.log('ConcretePrototype1.clone invoked');        let clone = new ConcretePrototype1();        let keys = Object.keys(this);
        keys.forEach(k => clone.setFeature(k, this[k]));
        console.log("ConcretePrototype1 cloned");        return clone;    }}
class ConcretePrototype2 extends Prototype {    constructor() {        super();        console.log("ConcretePrototype2 created");        this.feature = "feature 2"    }
    clone() {        console.log('ConcretePrototype2.Clone function');        let clone = new ConcretePrototype2();        let keys = Object.keys(this);
        keys.forEach(k => clone.setFeature(k, this[k]));        console.log("ConcretePrototype2 cloned");        return clone;    }}
var proto1 = new ConcretePrototype1();proto1.setFeature('feature', "feature 11");var clone1 = proto1.clone();console.log(clone1.feature);console.log(typeof clone1);console.log(clone1 === proto1);
var proto2 = new ConcretePrototype2();proto2.setFeature('feature', "feature 22");var clone2 = proto2.clone();console.log(clone2.feature);console.log(typeof clone2);console.log(clone2 === proto2);~~~

结构型模式:

  • Adapter(适配器模式):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

~~~# Adapter.js'use strict';
class Target {    constructor(type) {        console.log('Target Class created!');        let result = undefined;
        switch (type) {            case 'adapter':                result = new AdapterImpl();                break            default:                result = undefined;        }        return result;    }
    request() {        console.log('Target.request invoked');    }}
class Adapter {    constructor() {        console.log('Adapter Class created');    }
    specificRequest() {        console.log('Adapter.specificRequest invoked');    }}
class AdapterImpl extends Adapter {    constructor() {        super()        console.log('AdapterImpl Class created');    }
    request() {        console.log('AdapterImpl.request invoked');        return this.specificRequest();    }}
var f = new Target("adapter");f.request();~~~

~~~# Bridge.js'use strict';
class Abstraction {    constructor() {        console.log('Abstraction Class created');    }
    operation() {        console.log('Abstraction.operation invoked');        this.imp.operationImp();    }}
class RefinedAbstraction extends Abstraction {    constructor() {        super()        console.log('RefinedAbstraction Class created');    }
    setImp(imp) {        console.log('RefinedAbstraction.setImp invoked');        this.imp = imp    }}
class Implementor {    constructor() {        console.log('Implementor Class created');    }
    operationImp() {        console.log('Implementor.operationImp invoked');    }}
class ConcreteImplementorA extends Implementor {    constructor() {        super()        console.log('ConcreteImplementorA Class created');    }
    operationImp() {        console.log('ConcreteImplementorA.operationImp invoked');    }}
class ConcreteImplementorB extends Implementor {    constructor() {        super()        console.log('ConcreteImplementorB Class created');    }
    operationImp() {        console.log('ConcreteImplementorB.operationImp invoked');    }}
var abstraction = new RefinedAbstraction();abstraction.setImp(new ConcreteImplementorA());abstraction.operation();abstraction.setImp(new ConcreteImplementorB());abstraction.operation();~~~

  • Composite(组合模式):将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。

~~~# Composite.js'use strict';
class Component {    constructor() {        console.log('Component Class created');    }
    operation() {        console.log('Component.operation invoked');    }
    add(Component) {        console.log('Component.add invoked');    }
    remove(Component) {        console.log('Component.remove invoked');    }
    getChild(key) {        console.log('Component.getChild invoked');    }}
class Leaf extends Component {    constructor(name) {        super();        this.name = name;        console.log('Leaf Class created');    }
    operation() {        console.log('Leaf.operation invoked');        console.log(this.name);    }}
class Composite extends Component {    constructor(name) {        super();        this.name = name;        this.children = [];        console.log('Composite Class created');    }
    operation() {        console.log('Composite operation for: ' + this.name)        for (var i in this.children) {            this.children[i].operation();        }    }
    add(Component) {        console.log('Composite.add invoked');        this.children.push(Component);    }
    remove(Component) {        console.log('Composite.remove invoked');        for (var i in this.children) {            if (this.children[i] === Component) {                this.children.splice(i, 1);            }        }    }
    getChild(key) {        console.log('Composite.getChild invoked');        return this.children[key];    }}
var composite1 = new Composite('C1');composite1.add(new Leaf('L1'));composite1.add(new Leaf('L2'));var composite2 = new Composite('C2');composite2.add(composite1);composite1.getChild(1).operation();composite2.operation();~~~

~~~# Decorator.js'use strict';
class Component {    constructor() {        console.log('Component Class created');    }
    operation() {        console.log('Component.operation invoked');    }}
class ConcreteComponent extends Component {    constructor() {        super();        console.log('ConcreteComponent Class created');    }
    operation() {        console.log('ConcreteComponent.operation invoked');    }}
class Decorator extends Component {    constructor(component) {        super();        this.component = component;        console.log('Decorator Class created');    }
    operation() {        console.log('Decorator.operation invoked');        this.component.operation()    }}
class ConcreteDecoratorA extends Decorator {    constructor(component, sign) {        super(component);        this.addedState = sign;        console.log('ConcreteDecoratorA Class created');    }
    operation() {        super.operation();        console.log('ConcreteDecoratorA.operation invoked');        console.log(this.addedState)    }}
class ConcreteDecoratorB extends Decorator {    constructor(component, sign) {        super(component);        this.addedState = sign;        console.log('ConcreteDecoratorB Class created');    }
    operation() {        super.operation();        console.log('ConcreteDecoratorB.operation invoked');        console.log(this.addedState + this.addedState + this.addedState + this.addedState + this.addedState);    }
    addedBehavior() {        this.operation();        console.log('ConcreteDecoratorB.operation invoked');    }}
var component = new ConcreteComponent();var decoratorA = new ConcreteDecoratorA(component, 'decoratorA');var decoratorB = new ConcreteDecoratorB(component, 'decoratorB');console.log('component: ');component.operation();console.log('decoratorA: ');decoratorA.operation();console.log('decoratorB: ');decoratorB.addedBehavior();~~~

  • Facade(外观模式):为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

~~~# Facade.js'use strict';
class Facade {    constructor() {        console.log("Facade class created");    }
    gotoPage(dp) {        switch (dp) {            case "Facade":                console.log("This is the Facade");                break;            case "AbstractFactory":                console.log("This is the AbstractFactory");                break;            case "Builder":                console.log("This is the Builder");                break;            case "Factory":                console.log("This is the Factory");                break;            case "Prototype":                console.log("This is the Prototype");                break;            case "Singleton":                console.log("This is the Singleton");                break;            case "Adapter":                console.log("This is the Adapter");                break;            case "Bridge":                console.log("This is the Bridge");                break;            case "Composite":                console.log("This is the Composite");                break;            case "Decorator":                console.log("This is the Decorator");                break;            case "Flyweight":                console.log("This is the Flyweight");                break;            case "Proxy":                console.log("This is the Proxy");                break;            case "ChainofResponsibility":                console.log("This is the ChainofResponsibility");                break;            case "Command":                console.log("This is the Command");                break;            case "Interpreter":                console.log("This is the Interpreter");                break;            case "Iterator":                console.log("This is the Iterator");                break;            case "Mediator":                console.log("This is the Mediator");                break;            case "Memento":                console.log("This is the Memento");                break;            case "Observer":                console.log("This is the Observer");                break;            case "State":                console.log("This is the State");                break;            case "Strategy":                console.log("This is the Strategy");                break;            case "TemplateMethod":                console.log("This is the TemplateMethod");                break;            case "Visitor":                console.log("This is the Visitor");                break;            default:                console.log("nothing to be matched");        }    }}
let facade = new Facade();facade.gotoPage('Facade');facade.gotoPage('AbstractFactory');facade.gotoPage('Builder');facade.gotoPage('Factory');facade.gotoPage('Prototype');facade.gotoPage('Singleton');facade.gotoPage('Adapter');facade.gotoPage('Bridge');facade.gotoPage('Composite');facade.gotoPage('Decorator');facade.gotoPage('Flyweight');facade.gotoPage('Proxy');facade.gotoPage('ChainofResponsibility');facade.gotoPage('Command');facade.gotoPage('Interpreter');facade.gotoPage('Iterator');facade.gotoPage('Mediator');facade.gotoPage('Memento');facade.gotoPage('Observer');facade.gotoPage('State');facade.gotoPage('Strategy');facade.gotoPage('TemplateMethod');facade.gotoPage('Visitor');~~~

~~~# Flyweight.js'use strict';
class FlyweightFactory {    constructor() {        this.flyweights = {};        console.log('FlyweightFactory Class created');    }
    getFlyweight(key) {        console.log('FlyweightFactory.getFlyweight invoked');        if (this.flyweights[key]) {            return this.flyweights[key];        } else {            this.flyweights[key] = new ConcreteFlyweight(key);            return this.flyweights[key];        }    }
    createGibberish(keys) {        console.log('FlyweightFactory.createGibberish invoked');        return new UnsharedConcreteFlyweight(keys, this);    }}
class Flyweight {    constructor() {        console.log('Flyweight Class created');    }
    operation(extrinsicState) {        console.log('Flyweight.operation invoked');    }}
class ConcreteFlyweight extends Flyweight {    constructor(key) {        super();        this.intrinsicState = key;        console.log('ConcreteFlyweight Class created');    }
    operation(extrinsicState) {        console.log('ConcreteFlyweight.operation invoked');        return extrinsicState + this.intrinsicState;    }}
class UnsharedConcreteFlyweight extends Flyweight {    constructor(keys, flyweights) {        super();        this.flyweights = flyweights;        this.keys = keys;        console.log('UnsharedConcreteFlyweight Class created');    }
    operation(extrinsicState) {        console.log('UnsharedConcreteFlyweight.operation invoked');        var key, word = '';        for (var i = 0; i < extrinsicState; i++) {            key = this.keys[Math.floor(Math.random() * (this.keys.length))];            word = this.flyweights.getFlyweight(key).operation(word);        }        console.log('UnsharedConcreteFlyweight Operation: ');        console.log(word);    }}

var flyweights = new FlyweightFactory();var gibberish = flyweights.createGibberish(['-', '+', '*']);gibberish.operation(5);~~~

~~~# Proxy.js'use strict';
class Subject {    constructor() {        console.log('Subject Class created');    }
    request() {        console.log('Subject.request invoked');    }}
class RealSubject extends Subject {    constructor() {        super()        console.log('RealSubject Class created');    }
    request() {        console.log('RealSubject.request invoked');    }}
class Proxy extends Subject {    constructor() {        super()        console.log('Proxy Class created');    }
    request() {        this.realSubject = new RealSubject();        this.realSubject.request();    }}
var proxy = new Proxy()proxy.request()~~~

行为型模式:

  • Chain of Responsibility(责任链模式):为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

~~~# Chain of Responsibility.js'use strict';class Handler {    constructor() {        console.log('Handler Class created');    }
    handleRequest() {        console.log('Handler.handleRequest invoked');    }}
class ConcreteHandler1 extends Handler {    constructor() {        super();        console.log('ConcreteHandler1 Class created');    }
    setSuccessor(successor) {        this.successor = successor;        console.log('ConcreteHandler1.setSuccessor invoked');    }
    handleRequest(request) {        console.log('ConcreteHandler1.handleRequest invoked');        if (request === 'run')            console.log('ConcreteHandler1 has handled the request');        else {            console.log('ConcreteHandler1 calls his successor');            this.successor.handleRequest(request);        }    }}
class ConcreteHandler2 extends Handler {    constructor() {        super();        console.log('ConcreteHandler2 Class created');    }
    handleRequest(request) {        console.log('ConcreteHandler2.handleRequest invoked');    }}
let handle1 = new ConcreteHandler1();let handle2 = new ConcreteHandler2();handle1.setSuccessor(handle2);handle1.handleRequest('run');handle1.handleRequest('stay');~~~

  • Command(命令模式):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

~~~# Command.js'use strict';
class Invoker {    constructor() {        console.log('Invoker Class created');    }
    storeCommand(command) {        this.command = command;        console.log('Invoker.storeCommand invoked');    }}
class Command {    constructor() {        console.log('Command Class created');    }
    execute() {        console.log('Command.execute invoked');    }}
class ConcreteCommand extends Command {    constructor(receiver, state) {        super();        this.receiver = receiver;        console.log('ConcreteCommand Class created');    }
    execute() {        console.log('ConcreteCommand.execute invoked');        this.receiver.action();    }}
class Receiver {    constructor() {        console.log('Receiver Class created');    }
    action() {        console.log('Receiver.action invoked');    }}
var invoker = new Invoker();var receiver = new Receiver();var command = new ConcreteCommand(receiver);invoker.storeCommand(command);invoker.command.execute();~~~

~~~# Interpreter.js'use strict';
class Context {    constructor(input) {        this.sum = 0;        this.list = [];        console.log('Context Class created');    }
    add(eps) {        console.log('Context.add invoked');        this.list.push(eps);    }
    getList() {        console.log('Context.getList invoked');        return this.list;    }
    getSum() {        console.log('Context.getSum invoked');        return this.sum;    }
    setSum(_sum) {        this.sum = _sum;        console.log('Context.setSum invoked');    }}
class AbstractExpression {    constructor() {        console.log('AbstractExpression Class created');    }
    interpret(context) {        console.log('AbstractExpression.interpret invoked');    }}
class PlusExpression extends AbstractExpression {    constructor(name) {        super();        this.name = name;        console.log('PlusExpression Class created');    }
    interpret(context) {        console.log('PlusExpression.interpret invoked');        var sum = context.getSum();        sum++;        context.setSum(sum);    }}
class MinusExpression extends AbstractExpression {    constructor() {        super();        this.name = '+';        console.log('MinusExpression Class created');    }
    interpret(context) {        console.log('MinusExpression.interpret invoked');        var sum = context.getSum();        sum--;        context.setSum(sum)    }}
var context = new Context();context.setSum(20);
context.add(new PlusExpression());context.add(new PlusExpression());context.add(new PlusExpression());
context.add(new MinusExpression());context.add(new MinusExpression());
var list = context.getList();for (var i = 0; i < list.length; i++) {    var expression = list[i];    expression.interpret(context);}
console.log("Result:" + context.getSum());~~~

~~~# Iterator.js
'use strict';
class Iterator {    constructor() {        console.log('Iterator Class created');    }
    first() {        console.log('Iterator.first invoked');    }
    next() {        console.log('Iterator.next invoked');    }
    isDone() {        console.log('Iterator.isDone invoked');    }
    currentItem() {        console.log('Iterator.currentItem invoked');    }}
class ConcreteIterator extends Iterator {    constructor(aggregate) {        super();        this.index = 0;        this.aggregate = aggregate;        console.log('ConcreteIterator Class created');    }
    first() {        console.log('ConcreteIterator.first invoked');        return this.aggregate.list[0];    }
    next() {        console.log('ConcreteIterator.next invoked');        this.index += 1;        return this.aggregate.list[this.index];    }
    currentItem() {        console.log('ConcreteIterator.currentItem invoked');        return this.aggregate.list[this.index];    }}
class Aggregate {    constructor() {        console.log('Aggregate Class created');    }
    createIterator() {        console.log('Aggregate.CreateIterator invoked');    }}
class ConcreteAggregate extends Aggregate {    constructor(list) {        super();        this.list = list;        console.log('ConcreteAggregate Class created');    }
    createIterator() {        console.log('ConcreteAggregate.CreateIterator invoked');        this.iterator = new ConcreteIterator(this);    }}
var aggregate = new ConcreteAggregate([0, 1, 2, 3, 4, 5, 6, 7]);aggregate.createIterator();console.log(aggregate.iterator.first());console.log(aggregate.iterator.next());console.log(aggregate.iterator.currentItem());~~~

  • Mediator(中介者模式):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

~~~# Mediator.js'use strict';
class Mediator {    constructor() {        console.log('Mediator Class created');    }
    colleagueChanged(colleague) {        console.log('Mediator.colleagueChanged invoked');    }}
class ConcreteMediator extends Mediator {    constructor() {        super();        console.log('ConcreteMediator Class created');        this.colleague1 = new ConcreteColleague1(this);        this.colleague2 = new ConcreteColleague2(this);    }
    colleagueChanged(colleague) {        console.log('ConcreteMediator.colleagueChanged invoked');        switch (colleague) {            case this.colleague1:                console.log('ConcreteColleague1 has Changed -> change ConcreteColleague2.feature: ');                this.colleague2.setFeature('new feature 2');                break            case this.colleague2:                console.log('ConcreteColleague2 has Changed, but do nothing');                break            default:                console.log('Do nothing');        }    }}
class Colleague {    constructor() {        console.log('Colleague Class created');    }
    changed() {        console.log('Colleague.changed invoked');        this.mediator.colleagueChanged(this);    }}
class ConcreteColleague1 extends Colleague {    constructor(mediator) {        super();        console.log('ConcreteColleague1 Class created');        this.mediator = mediator;        this.feature = "feature 1";    }
    setFeature(feature) {        console.log('ConcreteColleague1.setFeature invoked');        console.log('ConcreteColleague1 Feature has changed from ' + this.feature + ' to ' + feature)        this.feature = feature;        this.changed();    }}
class ConcreteColleague2 extends Colleague {    constructor(mediator) {        super();        console.log('ConcreteColleague2 Class created');        this.mediator = mediator;        this.feature = "feature 2";    }
    setFeature(feature) {        console.log('ConcreteColleague2.setFeature invoked');        console.log('ConcreteColleague2 Feature has changed from ' + this.feature + ' to ' + feature);        this.feature = feature;        this.changed();    }}
var mediator = new ConcreteMediator();mediator.colleague1.setFeature("new feature 1");~~~

  • Memento(备忘录模式):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

~~~# Memento.js'use strict';
class Originator {    constructor() {        console.log('Originator Class created');        this.state = 'a';        console.log('Originator created. State= ' + this.state);    }
    setMemento(Memento) {        console.log('Originator.setMemento invoked');        this.state = Memento.getState();        console.log('Originator.setMemento State= ' + this.state);    }
    createMemento(state) {        console.log('Originator.createMemento invoked');        return new Memento(state);    }}
class Memento {    constructor(state) {        console.log('Memento Class created');        this.state = state;        console.log('Memento created. State= ' + this.state);    }
    getState() {        console.log('Memento.getState invoked');        return this.state;    }
    setState(state) {        console.log('Memento.setState invoked');        this.state = state;    }}
class Caretaker {    constructor() {        console.log('Caretaker Class created');        this.mementos = [];    }
    addMemento(memento) {        console.log('Caretaker.addMemento invoked');        this.mementos.push(memento)    }
    setMemento() {        console.log('Caretaker.setMemento invoked');        return this.mementos[this.mementos.length - 1]    }}
let caretaker = new Caretaker();let originator = new Originator();caretaker.addMemento(originator.createMemento('b'));originator.setMemento(caretaker.setMemento());console.log(originator.state);~~~

  • Observer(观察者模式):定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

~~~# Observer.js'use strict';
class Subject {    constructor() {        console.log('Subject Class created');    }
    attach(observer) {        this.observers.push(observer);        console.log('Subject.attach invoked');    }
    dettach(observer) {        console.log('Subject.dettach invoked');        for (var i in this.observers) {            if (this.observers[i] === observer) {                this.observers.splice(i, 1);            }        }    }
    notify() {        console.log('Subject.notify invoked');        for (var i in this.observers) {            this.observers[i].update(this);        }    }}
class ConcreteSubject extends Subject {    constructor() {        super();        this.subjectState = null;        this.observers = [];        console.log('ConcreteSubject Class created');    }
    getState() {        console.log('ConcreteSubject.getState invoked');        return this.subjectState;    }
    setState(state) {        console.log('ConcreteSubject.setState invoked');        this.subjectState = state;        this.notify();    }}
class Observer {    constructor() {        console.log('Observer Class created');    }
    update() {        console.log('Observer.update invoked');    }}
class ConcreteObserver extends Observer {    constructor() {        super();        this.observerState = '';        console.log('ConcreteObserver Class created');    }
    update(Subject) {        console.log('ConcreteObserver.update invoked');        this.observerState = Subject.getState();        console.log('Observer new state: ' + this.observerState);    }}
var observer1 = new ConcreteObserver();var observer2 = new ConcreteObserver();var subject = new ConcreteSubject();subject.attach(observer1);subject.attach(observer2);subject.setState('state 1');~~~

  • State(状态模式):允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

~~~# State.js'use strict';
class Context {    constructor(state) {        console.log("Context Class created");        switch (state) {            case "A":                this.state = new ConcreteStateA()                break            case "B":                this.state = new ConcreteStateB()                break            default:                this.state = new ConcreteStateA()        }    }
    request() {        console.log('Context.request invoked');        this.state.handle(this);    }}
class State {    constructor() {        console.log("State Class created");    }
    handle() {        console.log('State.handle invoked');    }}
class ConcreteStateA extends State {    constructor() {        super();        console.log("ConcreteStateA Class created");    }
    handle(context) {        console.log('ConcreteStateA.handle invoked');    }}
class ConcreteStateB extends State {    constructor() {        super();        console.log("ConcreteStateB Class created");    }
    handle(context) {        console.log('ConcreteStateB.handle invoked');    }}
let context = new Context("A")context.request()~~~

  • Strategy(策略模式):定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

~~~# Strategy.js'use strict';
class Context {    constructor(type) {        console.log('Context Class created!');        switch (type) {            case "A":                this.strategy = new ConcreteStrategyA()                break            case "B":                this.strategy = new ConcreteStrategyB()                break            default:                this.strategy = new ConcreteStrategyA()        }    }
    contextInterface() {        console.log('Context.contextInterface invoked');        this.strategy.algorithmInterface()    }}
class Strategy {    constructor() {        console.log('Strategy Class created!');    }
    algorithmInterface() {        console.log('Strategy.algorithmInterface invoked');    }}
class ConcreteStrategyA extends Strategy {    constructor() {        super();        console.log('ConcreteStrategyA Class created!');    }
    algorithmInterface() {        console.log('ConcreteStrategyA.algorithmInterface invoked');    }}
class ConcreteStrategyB extends Strategy {    constructor() {        super();        console.log('ConcreteStrategyB Class created!');    }
    algorithmInterface() {        console.log('ConcreteStrategyB.algorithmInterface invoked');    }}
let contextA = new Context("A");contextA.contextInterface();let contextB = new Context("B");contextB.contextInterface();~~~

  • Template Method(模版方法模式):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

~~~# Template Method.js'use strict';
class AbstractClass {    constructor() {        console.log('AbstractClass Class created!');    }
    templateMethod() {        console.log('AbstractClass.templateMethod invoked');        this.primitiveOperation1();        this.primitiveOperation2();    }
    primitiveOperation1() {        console.log('AbstractClass.primitiveOperation1 invoked');    }
    primitiveOperation2() {        console.log('AbstractClass.primitiveOperation2 invoked');    }}
class ConcreteClass extends AbstractClass {    constructor() {        super();        console.log('ConcreteClass Class created!');    }
    primitiveOperation1() {        console.log('ConcreteClass.primitiveOperation1 invoked');    }
    primitiveOperation2() {        console.log('ConcreteClass.primitiveOperation2 invoked');    }}
let obj = new ConcreteClass();obj.templateMethod();~~~

  • Visitor(访问者模式):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

~~~# Visitor.js'use strict';
class Visitor {    constructor() {        console.log('Visitor Class created!');    }
    visitConcreteElementA(ConcreteElementA) {        console.log('Visitor.visitConcreteElementA invoked');    }
    visitConcreteElementB(ConcreteElementB) {        console.log('Visitor.visitConcreteElementB invoked');    }}
class ConcreteVisitor1 extends Visitor {    constructor() {        super();        console.log('ConcreteVisitor1 Class created!');    }
    visitConcreteElementA(ConcreteElementA) {        console.log('ConcreteVisitor1.visitConcreteElementA invoked');    }
    visitConcreteElementB(ConcreteElementB) {        console.log('ConcreteVisitor1.visitConcreteElementB invoked');    }}
class ConcreteVisitor2 extends Visitor {    constructor() {        super();        console.log('ConcreteVisitor2 Class created!');    }
    visitConcreteElementA(ConcreteElementA) {        console.log('ConcreteVisitor2.visitConcreteElementA invoked');    }
    visitConcreteElementB(ConcreteElementB) {        console.log('ConcreteVisitor2.visitConcreteElementB invoked');    }}
class ObjectStructure {    constructor() {        console.log('ObjectStructure Class created!');    }}
class Element {    constructor() {        console.log('Element Class created!');    }
    Accept(visitor) {        console.log('Element.visitConcreteElementB invoked');    }}
class ConcreteElementA extends Element {    constructor() {        super();        console.log('ConcreteElementA Class created!');    }
    accept(visitor) {        console.log('ConcreteElementA.accept invoked');        visitor.visitConcreteElementA(this);    }
    operationA() {        console.log('ConcreteElementA.operationA invoked');    }}
class ConcreteElementB extends Element {    constructor() {        super();        console.log('ConcreteElementB Class created!');    }
    accept(visitor) {        console.log('ConcreteElementB.accept invoked');        visitor.visitConcreteElementB(this);    }
    operationB() {        console.log('ConcreteElementB.operationB invoked');    }}
let visitor1 = new ConcreteVisitor1();let visitor2 = new ConcreteVisitor2();let elementA = new ConcreteElementA();let elementB = new ConcreteElementB();elementA.accept(visitor1);elementB.accept(visitor2);~~~