【面试题】 ES6 类聊 JavaScript 设计模式之行为型模式(二)_js new subject

class Subject {
constructor() {
this._observers = [];
}

subscribe(observer) {
    this._observers.push(observer);
}

unsubscribe(observer) {
    this._observers = this._observers.filter((obs) => observer !== obs);
}

fire(change) {
    this._observers.forEach((observer) => {
        observer.update(change);
    });
}

}

class Observer {
constructor(state) {
this.state = state;
this.initialState = state;
}

update(change) {
    const state = this.state;
    const handlers = {
        inc: (num) => ++num,
        dec: (num) => --num,
    };
    const changeMethod = handlers[change.toLowerCase()];
    this.state = changeMethod ? changeMethod(state) : this.initialState;
}

}

// 使用
const sub = new Subject();

const obs1 = new Observer(1);
const obs2 = new Observer(19);

sub.subscribe(obs1);
sub.subscribe(obs2);

sub.fire(“INC”);

console.log(obs1.state); // 2
console.log(obs2.state); // 20
复制代码


19. 访问者模式:Visitor


访问者模式向对象添加操作而无需修改它们。



> 
> 访问者模式是一种将算法与其操作的对象结构分离的方法。这种分离的实际结果是能够在不修改结构的情况下向现有对象结构添加新操作。—— 维基百科
> 
> 
> 


实例


将举一个数学表达式 `NumberExpression` 的例子,列出给定的算术表达式。



class NumberExpression {
constructor(value) {
this.value = value;
}

print(buffer) {
    buffer.push(this.value.toString());
}

}

class AdditionExpression {
constructor(left, right) {
this.left = left;
this.right = right;
}

print(buffer) {
    buffer.push("(");
    this.left.print(buffer);
    buffer.push("+");
    this.right.print(buffer);
    buffer.push(")");
}

}
复制代码


使用方式如下:



const e = new AdditionExpression(
new NumberExpression(6),
new AdditionExpression(new NumberExpression(2), new NumberExpression(8))
);

const buffer = [];
e.print(buffer);
console.log(buffer.join(“”));
复制代码


输出结果如下:



(6+(2+8))
复制代码


20. 策略模式:Strategy


策略模式允许在某些情况下选择其中一种算法。允许为特定任务封装替代算法。它定义了一系列算法并以这样一种方式封装它们,即它们在运行时可互换,而无需客户干预或知识。



> 
> 策略模式是一种行为软件设计模式,可以在运行时选择算法。代码不是直接实现单个算法,而是接收运行时指令,以确定要使用一系列算法中的哪一个。 —— 维基百科
> 
> 
> 


实例


将举一个例子,有一个文本处理器,将根据策略(`HTML` 或 `Markdown`)输出列表数据格式。



const OutputFormat = Object.freeze({
markdown: 0,
html: 1,
});

class ListStrategy {
start(buffer) {}
end(buffer) {}
addListItem(buffer, item) {}
}

class MarkdownListStrategy extends ListStrategy {
addListItem(buffer, item) {
buffer.push( * ${item});
}
}

class HtmlListStrategy extends ListStrategy {
start(buffer) {
buffer.push(“

  • ”);
    }
    end(buffer) {
    buffer.push(“
”);
}
addListItem(buffer, item) {
buffer.push( <li>${item}</li>);
}
}
复制代码


创建 `TextProcessor` 类



class TextProcessor {
constructor(outputFormat) {
this.buffer = [];
this.setOutputFormat(outputFormat);
}

setOutputFormat(format) {
    switch (format) {
        case OutputFormat.markdown:
            this.listStrategy = new MarkdownListStrategy();
            break;
        case OutputFormat.html:
            this.listStrategy = new HtmlListStrategy();
            break;
    }
}

appendList(items) {
    this.listStrategy.start(this.buffer);
    for (const item of items) {
        this.listStrategy.addListItem(this.buffer, item);
    }
    this.listStrategy.end(this.buffer);
}

clear() {
    this.buffer = [];
}

toString() {
    return this.buffer.join("\n");
}

}
复制代码


下面是使用方式:



console.log(“Markdown=”)
const tp = new TextProcessor();
const arrayItems = [“第一条”, “第二条”, “第三条”];
tp.setOutputFormat(OutputFormat.markdown);
tp.appendList(arrayItems);
console.log(tp.toString());

console.log(“HTML=”)
tp.clear();
tp.setOutputFormat(OutputFormat.html);
tp.appendList(arrayItems);
console.log(tp.toString());
复制代码


输出结果如下:



Markdown=

  • 第一条
  • 第二条
  • 第三条
    HTML=
  • 第一条
  • 第二条
  • 第三条
复制代码 ```
  1. 状态模式:State

状态模式允许对象根据其内部状态的变化来改变其行为。状态模式类返回的对象似乎改变了它的类。它为一组有限的对象提供特定于状态的逻辑,其中每个对象类型代表一个特定的状态。

状态模式是一种行为软件设计模式,它允许对象在其内部状态发生变化时改变其行为。这种模式接近于有限状态机的概念。 —— 维基百科

实例

将举一个电灯开关的例子,打开或关闭开关,它的状态就会改变。

class State {
    constructor() {
        if (this.constructor === State) throw new Error("abstract!");
    }

    on(sw) {
        console.log("灯已打开!");
    }

    off(sw) {
        console.log("灯已关闭!");
    }
}

class OffState extends State {
    constructor() {
        super();
        console.log("关灯");
    }

    on(sw) {
        console.log("开灯中…");
        sw.state = new OnState();
    }
}

class OnState extends State {
    constructor() {
        super();
        console.log("开灯");
    }


### 文末

从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。



个人将这段时间所学的知识,分为三个阶段:

第一阶段:HTML&CSS&JavaScript基础

![](https://img-blog.csdnimg.cn/img_convert/3e0d5b0f6a97b823cc1ef22ff1a18191.png)



第二阶段:移动端开发技术

![](https://img-blog.csdnimg.cn/img_convert/fc21db0a800494796dc6408ce1486031.png)

第三阶段:前端常用框架

![](https://img-blog.csdnimg.cn/img_convert/644efd4ddd0f8d43535f1982ec0da6e4.png)



*   推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;

*   大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。
  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值