1. 工廠方法模式- 工廠方法模式定義了一個創建對象的接口,但是由子類決定要實例化的類是哪一個.可以將對象的創建和使用分離,使得系統更加靈活.
function FactoryMethod() {
class Animal {
speak() {
console.log('speal');
}
}
class Dog extends Animal {
speak() {
console.log('Dog');
}
}
class Cat extends Animal {
speak() {
console.log('Cat');
}
}
class AnimalFactory {
create(type) {
switch (type) {
case 'dog':
return new Dog();
case 'cat':
return new Cat();
default:
return null;
}
}
}
const animalFactory = new AnimalFactory();
const dog = animalFactory.create('dog');
dog.speak(); // Dog
const cat = animalFactory.create('cat');
cat.speak(); // Cat
}
2. 抽象工廠模式- 抽象工廠模式提供了一種封裝一組具有相同主題的單個工廠的方式.它有一個接口,用于創建相關或依賴對象的家族,而不需要指定實際實現的類.其代碼示例如下:
function AbstractFactory() {
class AnimalFood {
provide() {
console.log('AnimalFood');
}
}
class AnimalToy {
provide() {
console.log('AnimalToy');
}
}
class ExpensiveAnimalFood extends AnimalFood {
provide() {
console.log('ExpensiveAnimalFood');
}
}
class CheapAnimalFood extends AnimalFood {
provide() {
console.log('CheapAnimalFood');
}
}
class ExpensiveAnimalToy extends AnimalToy {
provide() {
console.log('ExpensiveAnimalToy');
}
}
class CheapAnimalToy extends AnimalToy {
provide() {
console.log('CheapAnimalToy');
}
}
// 創建一個抽象工廠
class AnimalProductsAbstractFactory {
createFood() {
console.log('AnimalProductsAbstractFactory createFood');
}
createToy() {
console.log('AnimalProductsAbstractFactory createToy');
}
}
// 創建一個具體工廠類
class ExpensiveAnimalProductsAbstractFactory extends AnimalProductsAbstractFactory {
createFood() {
return new ExpensiveAnimalFood();
}
createToy() {
return new ExpensiveAnimalToy();
}
}
class CheapAnimalProductsAbstractFactory extends AnimalProductsAbstractFactory {
createFood() {
return new CheapAnimalFood();
}
createToy() {
return new CheapAnimalToy();
}
}
const expensiveAnimalProductsAbstractFactory =
new ExpensiveAnimalProductsAbstractFactory();
expensiveAnimalProductsAbstractFactory.createFood().provide(); // ExpensiveAnimalFood
expensiveAnimalProductsAbstractFactory.createToy().provide(); // ExpensiveAnimalToy
const cheapAnimalProductsAbstractFactory =
new CheapAnimalProductsAbstractFactory();
cheapAnimalProductsAbstractFactory.createFood().provide(); // CheapAnimalFood
cheapAnimalProductsAbstractFactory.createToy().provide(); // CheapAnimalToy
}
3. 單例模式- 單例模式的目的是確保一個類只有一個實例,并為該實例提供全局訪問點.
function Singleton() {
class Logger {
constructor() {
if (!Logger.instance) {
this.logs = [];
Logger.instance = this;
}
return Logger.instance;
}
log(message) {
this.logs.push(message);
console.log('[Logger] ', message);
}
printLogsCount() {
console.log('[Logs Count] ', this.logs.length);
}
}
// 可以使用全局變量來訪問實例
const logger = new Logger();
// 對于每個實例,輸出應該是相同的
logger.log('First Message'); // [Logger] First Message
logger.printLogsCount(); // [Logs Count] 1
const anotherLogger = new Logger(); // 此時會返回一個已經存在的實例
anotherLogger.log('Second Message'); // [Logger] Second Message
anotherLogger.printLogsCount(); // [Logs Count] 2
}
4. 建造者模式- 建造者模式是一種對象創建設計模式,它旨在通過一步步的構建流程來創建復雜對象.
function Builder() {
// 創建product類
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);
}
// 加蔬菜
putVegetable(vegetable) {
this.sandwich.addIngredient(vegetable);
}
get result() {
return this.sandwich;
}
}
class SandwichMaker {
constructor() {
this.builder = new SandwichBuilder();
}
createCheeseSteakSandwich() {
this.builder.reset();
this.builder.putMeat('beef');
this.builder.putCheese('cheddar');
this.builder.putVegetable('lettuce');
return this.builder.result;
}
}
const sandwichMaker = new SandwichMaker();
const sandwich = sandwichMaker.createCheeseSteakSandwich();
console.log(sandwich);
// {
// 'ingredients': [
// 'beef',
// 'cheddar',
// 'lettuce'
// ]
// }
}
5. 原型模式- 原型模式(Prototype Pattern)是一種創建型設計模式,它可以用于創建對象的成本相對較高,但對于由相同屬性的對象可以通過克隆來創建.原型模式將對象的創建過程和對象的使用過程分離,它通過克隆已有對象來創建新的對象,從而避免了昂貴的對象創建過程.在 JavaScript 中,原型模式的實現很容易,因為它天然支持對象的 clone(即淺拷貝).
function Prototype() {
const carPrototype = {
wheels: 4,
color: 'red',
start() {
console.log('start');
},
stop() {
console.log('stop');
},
};
const car1 = Object.create(carPrototype);
console.log(car1); // {}
car1.wheels = 6;
console.log(car1.wheels); // 6
console.log(car1.color); // red
car1.start = () => {
console.log('start1');
};
car1.start(); // start1
car1.stop(); // stop
const car2 = Object.create(carPrototype);
car2.color = 'blue';
console.log(car2.color); // blue
console.log(car2.wheels); // 4
car2.start(); // start
car2.stop(); // stop
}
6. 適配器模式- 適配器模式(Adapter Pattern)是一種結構型設計模式,它允許將不兼容的對象包裝在適配器中,從而使它們能夠在一起工作.
- 我們有一個目標接口 Target 和一個需要適配的類 Adaptee.
- 我們通過創建一個適配器類 Adapter 將 Adaptee 轉換為 Target,并使用適配器進行通信的客戶端 client 調用 request() 方法,從而實現 Adaptee 的功能.
function Adapter() {
// 目標接口
class Target {
request() {
console.log('Target request');
}
}
// 需要適配的類
class Adaptee {
specificRequest() {
console.log('Adaptee request');
}
}
// 適配器類,將 Adaptee 轉換為 Target
class Adapter extends Target {
constructor(adaptee) {
super();
this.adaptee = adaptee;
}
request() {
this.adaptee.specificRequest();
}
}
const client = new Adapter(new Adaptee());
client.request(); // Adaptee request
}
7. 裝飾模式- 裝飾模式(Decorator Pattern)是一種結構型設計模式,它允許在不影響其他對象的情況下,動態地將功能添加到對象中.
- 我們有一個抽象組件類 Component 和一個具體組件類 ConcreteComponent.
- 我們創建了兩個裝飾器類 ConcreteDecoratorA 和 ConcreteDecoratorB,它們都繼承自 Decorator 類,并且可以添加新的行為到被裝飾的對象上.
- 最后,我們實例化 ConcreteComponent 類,將其封裝在 ConcreteDecoratorA 和 ConcreteDecoratorB 類中,最終組成一個具有多個操作的對象.
function Decorator() {
console.log('----------------------------');
// 抽象組件類
class Component {
operation() {
console.log('Component operation');
}
}
// 具體組件類
class ConcreteComponent extends Component {
operation() {
console.log('ConcreteComponent operation');
}
}
// 抽象裝飾器類
class Decorator extends Component {
constructor(component) {
super();
this.component = component;
}
operation() {
this.component.operation();
}
}
// 具體裝飾器類
class ConcreteDecoratorA extends Decorator {
operation() {
super.operation();
console.log('ConcreteDecorator-A operation');
}
}
class ConcreteDecoratorB extends Decorator {
operation() {
super.operation();
console.log('ConcreteDecorator-B operation');
}
}
const component = new ConcreteComponent();
const decoratorA = new ConcreteDecoratorA(component);
const decoratorB = new ConcreteDecoratorB(decoratorA);
decoratorB.operation();
// ConcreteComponent operation
// ConcreteDecorator-A operation
// ConcreteDecorator-B operation
}
8. 代理模式- 代理模式(Proxy Pattern)是一種結構型設計模式,它允許在訪問對象時提供一個占位符或代理,以控制對對象的訪問.
- 我們有一個主題接口 Subject 和一個真實主題類 RealSubject.
- 我們創建了一個代理類 Proxy,它封裝了一個真實主題,并在對其進行訪問時提供了額外的功能,例如檢查訪問權限和記錄訪問日志.
- 我們通過實例化 RealSubject 類并封裝它在 Proxy 類中,最終通過代理訪問真實的主題對象.
function Decorator() {
console.log('----------------------------');
// 主題接口
class Subject {
request() {
console.log('Subject request');
}
}
// 真實主題類
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();
// index.js:363 Proxy 檢查訪問權限
// index.js:347 RealSubject 處理請求
// index.js:367 Proxy 記錄訪問日志
}
9. 外觀模式- 外觀模式(Facade Pattern)是一種結構型設計模式,它為一組復雜的子系統提供了一個更簡單的接口.
- 我們有兩個子系統 Subsystem1 和 Subsystem2,它們都提供了復雜的操作.
- 我們通過使用外觀模式創建了一個 Facade 類,它的接口更加簡單,
- 通過組合 Subsystem1 和 Subsystem2 對象的操作來實現其功能.
- 最后,我們實例化 Facade 類并調用操作方法 operation(),完成了復雜的功能操作.
function Facade() {
console.log('----------------------------');
// 子系統1
class Subsystem1 {
operation1() {
console.log('Subsystem1 operation1');
}
}
// 子系統2
class Subsystem2 {
operation2() {
console.log('Subsystem2 operation2');
}
}
// 外觀類
class Facade {
constructor() {
this.subsystem1 = new Subsystem1();
this.subsystem2 = new Subsystem2();
}
operation() {
this.subsystem1.operation1();
this.subsystem2.operation2();
}
}
const facade = new Facade();
facade.operation();
// index.js: 392 Subsystem1 operation1
// index.js: 398 Subsystem2 operation2
}
10. 橋接模式- 橋接模式(Bridge Pattern)是一種結構型設計模式,它將一個對象的抽象和實現分離開來,從而使它們都可以獨立變化.
- 我們有一個實現類接口 Implementor 和一個抽象類 Abstraction.
- 我們通過創建一個擴展抽象類 RefinedAbstraction 來擴展抽象類的功能,它們都使用了某個實現類的實例對象.
- 然后,我們實例化 Implementor 并通過在 Abstraction 和 RefinedAbstraction 類的聲明中傳遞 Implementor 對象來創建兩個具有不同行為的對象.
- 通過將實現和抽象分離開來,我們可以隨意地組合實現與抽象,并使其易于擴展.
function Bridge() {
console.log('----------------------------');
// 實現類接口
class Implement {
operationImpl() {
console.log('Implement operationImpl');
}
}
// 抽象類
class Abstraction {
constructor(implement) {
this.implement = implement;
}
operation() {
this.implement.operationImpl();
}
}
// 擴展抽象類
class RefineAbstraction extends Abstraction {
otherOperation() {
console.log('RefineAbstraction otherOperation');
}
}
// 使用橋接模式
const implementor = new Implement();
const abstraction = new Abstraction(implementor);
abstraction.operation(); // Implement operationImpl
const refineAbstraction = new RefineAbstraction(implementor);
refineAbstraction.operation(); // Implement operationImpl
refineAbstraction.otherOperation(); // RefineAbstraction otherOperation
}
11. 組合模式- 組合模式(Composite Pattern)是一種結構型設計模式,它使用樹形結構來表示對象的部分-整體層次結構,并使用戶能夠以統一的方式處理單個對象和對象組合.
- 我們有一個抽象構件 Component,通過創建兩個具體構建 Leaf 和 Composite 來擴展抽象構件的功能.
- Composite 保持著一個子對象的數組,并實現了在包含其他組件的能力.
- 然后,我們使用所有這些組件來建立一個樹形結構,
- 父節點模型是 Component 對象,而子節點可以是 Component 對象或 Composite 對象.
- 最終,我們可以通過調用操作方法來進行操作.
function Composite() {
console.log('----------------------------');
// 抽象組件
class Component {
constructor(name) {
this.name = name;
}
operation() {
console.log('Component', this.name, 'operation');
}
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.slice(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(); // Component 根 operation
branch1.operation(); // Component 樹枝1 operation
branch1.remove(leaf2);
branch2.operation(); // Component 樹枝2 operation
root.getChild(0).operation(); // Component 樹枝1 operation
}
12. 享元模式- 享元模式(Flyweight Pattern)是一種結構型設計模式,它通過共享對象來最小化內存使用和類實例化的數量.
- 我們有一個 Flyweight 工廠類 FlyweightFactory,用于創建并管理基礎的共享 ConcreteFlyweight 對象.
- ConcreteFlyweight 對象包含需要共享的數據或狀態.
- 我們實例化 FlyweightFactory,并通過在 FlyweightFactory 的 getFlyweight() 方法中獲取對象,以及通過多個對象來驗證是否共享相同的對象.
- 最終,結果顯示 flyweight1 跟 flyweight2 指向同一個對象,由此證明了共享對象的概念.
function Flyweight() {
console.log('----------------------------');
// Flyweight 工廠類
class FlyweightFactory {
constructor() {
this.flyweights = {};
}
getFlyweight(key) {
if (!this.flyweights[key]) {
this.flyweights[key] = new ConcreteFlyweight(key);
}
return this.flyweights[key];
}
}
// 具體 Flyweight 類
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(); // ConcreteFlyweight key 執行操作
flyweight2.operation(); // ConcreteFlyweight key 執行操作
console.log(flyweight2 === flyweight1); // true
}
13. 策略模式- 策略模式是一種設計模式,它定義了一系列算法,并將每個算法封裝起來,使它們可以相互替換.策略模式讓算法獨立于使用它的客戶端而獨立變化.這種模式屬于行為型模式.
function Strategy() {
console.log('------------- Strategy -------------');
class Strategy {
constructor(name) {
this.name = name;
}
execute() {}
}
class StrategyA extends Strategy {
execute() {
console.log('StrategyA execute');
}
}
class StrategyB extends Strategy {
execute() {
console.log('StrategyB execute');
}
}
class Context {
constructor(strategy) {
this.strategy = strategy;
}
executeStrategy() {
this.strategy.execute();
}
}
let context = new Context(new StrategyA('A'));
context.executeStrategy(); // StrategyA execute
context.strategy = new StrategyB('B');
context.executeStrategy(); // StrategyB execute
}
14. 模板方法模式- 模板方法模式是一種行為設計模式.它定義了一個操作中的算法骨架,將某些步驟延遲到子類中實現.模板方法使得子類可以不改變算法的結構即可重新定義該算法的某些特定步驟.
function TemplateMethod() {
console.log('------------- Strategy -------------');
class Game {
setup() {}
play() {}
finish() {}
start() {
this.setup();
this.play();
this.finish();
}
}
class Chess extends Game {
setup() {
console.log('Chess setup');
}
play() {
console.log('Chess play');
}
finish() {
console.log('Chess finish');
}
}
class TicTacToe extends Game {
setup() {
console.log('TicTacToe setup');
}
play() {
console.log('TicTacToe play');
}
finish() {
console.log('TicTacToe finish');
}
}
let game = new Chess();
game.start();
// index.js: 635 Chess setup
// index.js: 638 Chess play
// index.js: 641 Chess finish
game = new TicTacToe();
game.start();
// index.js: 646 TicTacToe setup
// index.js: 649 TicTacToe play
// index.js: 652 TicTacToe finish
}
15. 觀察者模式- 觀察者模式是一種行為設計模式,其中對象之間存在一對多的依賴關系.當一個對象的狀態發生變化時,它的所有依賴者都得到通知并自動更新.觀察者模式將對象之間的關系解耦,使得它們可以獨立變化.
function Observer() {
console.log('------------- Observer -------------');
class Subject {
constructor() {
this.observers = [];
}
attach(observer) {
this.observers.push(observer);
}
detach(observer) {
const index = this.observers.indexOf(observer);
if (index > -1) {
this.observers.slice(index, 1);
}
}
notify() {
for (let index = 0; index < this.observers.length; index++) {
this.observers[index].update(this);
}
}
}
class ConcreteSubject extends Subject {
constructor(state) {
super();
this.state = state;
}
set_state(state) {
this.state = state;
this.notify();
}
get_state() {
return this.state;
}
}
class Observer {
update(subject) {}
}
class ConcreteObserver extends Observer {
update(subject) {
console.log('updated value', subject.get_state());
}
}
let subject = new ConcreteSubject('state');
let observer = new ConcreteObserver();
subject.attach(observer);
subject.set_state('new state'); // updated value new state
}
16. 迭代器模式- 迭代器模式是一種行為設計模式,它提供了一種方式來順序訪問集合對象中的元素.迭代器模式將遍歷集合的責任交給迭代器,而不是集合自己.這樣就可以將集合的實現和遍歷算法的實現分離開來,從而提供更好的靈活性.
function Iterator() {
console.log('------------- Iterator -------------');
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);
}
interator() {
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.interator();
while (iterator.has_next()) {
console.log(iterator.next());
// index.js: 761 item 1
// index.js: 761 item 2
// index.js: 761 item 3
}
}
17. 責任鏈模式- 責任鏈模式(Chain of Responsibility)是一種行為型設計模式.它可以讓多個對象都有機會處理請求,從而避免將請求的發送者和接收者耦合在一起.將這些對象連成一個鏈,并沿著這條鏈傳遞請求,直到有一個對象處理它為止.
function ChainOfResponsibility() {
console.log('------------- 責任鏈模式 -------------');
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);
// ConcreteHandlerA : {
// 'ConcreteHandlerB': {
// 'ConcreteHandlerC': {
// 'nextHandler': null
// }
// }
// }
console.log(handlerA.handleRequest('A')); // index.js:818 Handle Request: A
console.log(handlerA.handleRequest('B')); // index.js:819 Handle Request: B
console.log(handlerA.handleRequest('C')); // index.js:820 Handle Request: C
console.log(handlerA.handleRequest('D')); // index.js:821 null
}
18. 命令模式- 命令模式(Command)是一種行為型設計模式,它將請求或操作封裝到一個對象中,從而允許你將請求或操作的發起者與具體執行者解耦.命令模式可以將請求或操作參數化,甚至在運行時動態地組合命令
function Command() {
console.log('------------- 命令模式 -------------');
class Command {
constructor(receiver) {
this.receiver = receiver;
}
execute() {
throw new Error('你必須實現execute方法!');
}
}
class ConcreteCommandA extends Command {
execute() {
this.receiver.actionA();
}
}
class ConcreteCommandB extends Command {
execute() {
this.receiver.actionB();
}
}
class Receiver {
actionA() {
console.log('Receiver actionA');
}
actionB() {
console.log('Receiver actionB');
}
}
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.`);
}
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'); // index.js: 857 Receiver actionA
invoker.executeCommand('B'); // index.js: 860 Receiver actionB
19. 備忘錄模式- 備忘錄模式(Memento)是一種行為型設計模式,它允許你在不暴露對象實現細節的情況下保存和恢復對象的狀態.備忘錄模式涉及到三個角色:備忘錄(Memento), 發起人(Originator), 管理者(Caretaker).
function Memento() {
console.log('------------- 備忘錄模式 -------------');
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('A');
const caretaker = new Caretaker();
caretaker.addMemento(originator.createMemento());
originator.setState('B');
console.log(originator.getState()); // B
originator.restoreMemento(caretaker.getMemento(0));
console.log(originator.getState()); // A
}
20. 狀態模式- 狀態模式(State)是一種行為型設計模式,它允許對象在其內部狀態發生改變時改變其行為.狀態模式通過將每個狀態封裝在一個類中,使得對于該狀態進行的任何操作都可以在該類中處理.從而將狀態轉換的代碼從主要業務邏輯中抽離出來,避免出現大量 if-else 語句.
function State() {
console.log('------------- 狀態模式 -------------');
class State {
constructor(context) {
this.context = context;
}
handle() {
console.log('你必須實現方法句柄!');
}
}
class ConcreteStateA extends State {
handle() {
console.log('ConcreteStateA handle');
this.context.setState(new ConcreteStateB(this.context));
}
}
class ConcreteStateB extends State {
handle() {
console.log('ConcreteStateB handle');
this.context.setState(new ConcreteStateA(this.context));
}
}
class Context {
constructor() {
this.state = new ConcreteStateA(this);
}
setState(state) {
this.state = state;
}
request() {
this.state.handle();
}
}
const context = new Context();
context.request(); // index.js: 955 ConcreteStateA handle
context.request(); // index.js: 961 ConcreteStateB handle
context.request(); // index.js: 955 ConcreteStateA handle
}
21. 訪問者模式- 訪問者模式(Visitor)是一種行為型設計模式,它允許你將算法封裝在一個或多個訪問者類中,從而讓你在不改變各個元素類接口的前提下定義作用于這些元素的新操作.
function Element() {
console.log('------------- 訪問者模式 -------------');
class Element {
accept() {
console.log('你必須實現方法句柄!');
}
}
class ConcreteElementA extends Element {
accept(visitor) {
visitor.visitConcreteElementA(this);
}
operationA() {
return 'ConcreteElementA operationA';
}
}
class ConcreteElementB extends Element {
accept(visitor) {
visitor.visitConcreteElementB(this);
}
operationB() {
return 'ConcreteElementB operationB';
}
}
class Visitor {
visitConcreteElementA(element) {
console.log('visitConcreteElementA', element.operationA());
}
visitConcreteElementB(element) {
console.log('visitConcreteElementB', element.operationB());
}
}
const elementA = new ConcreteElementA();
const elementB = new ConcreteElementB();
const visitor = new Visitor();
elementA.accept(visitor); // visitConcreteElementA ConcreteElementA operationA
elementB.accept(visitor); // visitConcreteElementB ConcreteElementB operationB
}
22. 中介者模式- 中介者模式(Mediator)是一種行為型設計模式,它允許你減少組件之間的直接依賴關系,將它們通過一個中介者對象進行交互.通過避免在組件之間顯式引用彼此,中介者可以讓你更容易地復用組件.
function Mediator() {
console.log('------------- 中介者模式 -------------');
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');
// Send event hello from Component A
// Receive event hello from Component A by Component B
// Receive event hello from Component A by Component C
}
23. 解釋器模式- 解釋器模式(Interpreter)是一種行為型設計模式,它能夠將一種語言(通常是一種編程語言)或者表達式的文法表示為解析樹,并定義一個解釋器,使用該解釋器來解釋這個語言或者表達式.
function Interpreter() {
console.log('------------- 解釋器模式 -------------');
class Context {
constructor(input) {
this.input = input;
this.output = 0;
}
}
class Expression {
interpreter(context) {
console.log('你必須實現方法句柄!');
}
}
class ThousandExpression extends Expression {
interpreter(context) {
console.log(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((el) => el.interpreter(context));
return context.output;
}
}
console.log(Interpreter.parse('CDXLVIII')); //
}
|