python设计模式面试_[面试专题]JS设计模式

JS设计模式

发布订阅模式:

这种设计模式可以大大降低程序模块之间的耦合度,便于更加灵活的扩展和维护。

// 一个播放器类

class Player {

constructor() {

// 初始化观察者列表

this.watchers = {}

// 模拟2秒后发布一个'play'事件

setTimeout(() => {

this._publish('play', true)

}, 2000)

// 模拟4秒后发布一个'pause'事件

setTimeout(() => {

this._publish('pause', true)

}, 4000)

}

// 发布事件

_publish(event, data) {

if (this.watchers[event] && this.watchers[event].length) {

this.watchers[event].forEach(callback => callback.bind(this)(data))

}

}

// 订阅事件

subscribe(event, callback) {

this.watchers[event] = this.watchers[event] || []

this.watchers[event].push(callback)

}

// 退订事件

unsubscribe(event = null, callback = null) {

// 如果传入指定事件函数,则仅退订此事件函数

if (callback&&event) {

if (this.watchers[event] && this.watchers[event].length) {

this.watchers[event].splice(this.watchers[event].findIndex(cb => Object.is(cb, callback)), 1)

}

// 如果仅传入事件名称,则退订此事件对应的所有的事件函数

} else if (event) {

this.watchers[event] = []

// 如果未传入任何参数,则退订所有事件

} else {

this.watchers = {}

}

}

}

// 实例化播放器

const player = new Player()

console.log(player)

// 播放事件回调函数1

const onPlayerPlay1 = function(data) {

console.log('1: Player is play, the `this` context is current player', this, data)

}

// 播放事件回调函数2

const onPlayerPlay2 = data => {

console.log('2: Player is play', data)

}

// 暂停事件回调函数

const onPlayerPause = data => {

console.log('Player is pause', data)

}

// 加载事件回调函数

const onPlayerLoaded = data => {

console.log('Player is loaded', data)

}

// 可订阅多个不同事件

player.subscribe('play', onPlayerPlay1)

player.subscribe('play', onPlayerPlay2)

player.subscribe('pause', onPlayerPause)

player.subscribe('loaded', onPlayerLoaded)

// 可以退订指定订阅事件

player.unsubscribe('play', onPlayerPlay2)

// 退订指定事件名称下的所有订阅事件

player.unsubscribe('play')

// 退订所有订阅事件

player.unsubscribe()

// 可以在外部手动发出事件(真实生产场景中,发布特性一般为类内部私有方法)

player._publish('loaded', true)

中介者模式 Mediator Pattern:

观察者模式通过维护一堆列表来管理对象间的多对多关系,中介者模式通过统一接口来维护一对多关系,且通信者之间不需要知道彼此之间的关系,只需要约定好API即可。

// 汽车

class Bus {

constructor() {

// 初始化所有乘客

this.passengers = {}

}

// 发布广播

broadcast(passenger, message = passenger) {

// 如果车上有乘客

if (Object.keys(this.passengers).length) {

// 如果是针对某个乘客发的,就单独给他听

if (passenger.id && passenger.listen) {

// 乘客他爱听不听

if (this.passengers[passenger.id]) {

this.passengers[passenger.id].listen(message)

}

// 不然就广播给所有乘客

} else {

Object.keys(this.passengers).forEach(passenger => {

if (this.passengers[passenger].listen) {

this.passengers[passenger].listen(message)

}

})

}

}

}

// 乘客上车

aboard(passenger) {

this.passengers[passenger.id] = passenger

}

// 乘客下车

debus(passenger) {

this.passengers[passenger.id] = null

delete this.passengers[passenger.id]

console.log(`乘客${passenger.id}下车`)

}

// 开车

start() {

this.broadcast({ type: 1, content: '前方无障碍,开车!Over'})

}

// 停车

end() {

this.broadcast({ type: 2, content: '老司机翻车,停车!Over'})

}

}

// 乘客

class Passenger {

constructor(id) {

this.id = id

}

// 听广播

listen(message) {

console.log(`乘客${this.id}收到消息`, message)

// 乘客发现停车了,于是自己下车

if (Object.is(message.type, 2)) {

this.debus()

}

}

// 下车

debus() {

console.log(`我是乘客${this.id},我现在要下车`, bus)

bus.debus(this)

}

}

// 创建一辆汽车

const bus = new Bus()

// 创建两个乘客

const passenger1 = new Passenger(1)

const passenger2 = new Passenger(2)

// 俩乘客分别上车

bus.aboard(passenger1)

bus.aboard(passenger2)

// 2秒后开车

setTimeout(bus.start.bind(bus), 2000)

// 3秒时司机发现2号乘客没买票,2号乘客被驱逐下车

setTimeout(() => {

bus.broadcast(passenger2, { type: 3, content: '同志你好,你没买票,请下车!' })

bus.debus(passenger2)

}, 3000)

// 4秒后到站停车

setTimeout(bus.end.bind(bus), 3600)

// 6秒后再开车,车上已经没乘客了

setTimeout(bus.start.bind(bus), 6666)

代理模式 Proxy Pattern:

为其他对象提供一种代理以控制对这个对象的访问。

代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西。

ES6中的Proxy对象

const target = {}

const handler = {

get(target, property) {

if (property in target) {

return target[property]

} else {

throw new ReferenceError("Property \"" + property + "\" does not exist.")

}

}

}

const p = new Proxy(target, {})

p.a = 3 // 被转发到代理的操作

console.log(p.c) //

单例模式 Singleton Pattern:

保证一个类只有一个实例,并提供一个访问它的全局访问点(调用一个类,任何时候返回的都是同一个实例)。

实现方法:使用一个变量来标志当前是否已经为某个类创建过对象,如果创建了,则在下一次获取该类的实例时,直接返回之前创建的对象,否则就创建一个对象。

// 类数实例:

class Singleton {

constructor(name) {

this.name = name

this.instance = null //

}

getName() {

alert(this.name)

}

static getInstance(name) {

if (!this.instance) {

this.instance = new Singleton(name)

}

return this.instance

}

}

const ins = new Singleton('hhhh')

const instanceA = Singleton.getInstance('seven1')

const instanceB = Singleton.getInstance('seven2')

//闭包包装实例:

const SingletonP = (function() {

let instance

return class Singleton {

constructor(name) {

if (instance) {

return instance

} else {

this.init(name)

instance = this

return this

}

}

init(name) {

this.name = name

console.log('已初始化')

}

}

})()

const instanceA = new SingletonP('seven1')

const instanceB = new SingletonP('seven2')

// ES5 iife

var SingletonTester = (function () {

function Singleton(args) {

var args = args || {};

//设置name参数

this.name = 'SingletonTester';

}

//实例容器

var instance;

return {

name: 'SingletonTester',

getInstance: function (args) {

if (instance === undefined) {

instance = new Singleton(args);

}

return instance;

}

};

})();

var singletonTest = SingletonTester.getInstance({ pointX: 5 });

console.log(singletonTest.pointX); // 输出 5

// 构造函数的属性

function Universe() {

if (typeof Universe.instance === 'object') {

return Universe.instance;

}

this.start_time = 0;

this.bang = "Big";

Universe.instance = this;

}

// 测试

var uni = new Universe();

var uni2 = new Universe();

console.log(uni === uni2); // true

// 重写构造函数

function Universe() {

var instance = this;

// 其它内容

this.start_time = 0;

this.bang = "Big";

// 重写构造函数

Universe = function () {

return instance;

};

}

// 测试

var uni = new Universe();

var uni2 = new Universe();

uni.bang = "123";

console.log(uni === uni2); // true

console.log(uni2.bang); // 123

工厂模式 Factory Pattern:

工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。

简单说:假如我们想在网页面里插入一些元素,而这些元素类型不固定,可能是图片、链接、文本,根据工厂模式的定义,在工厂模式下,工厂函数只需接受我们要创建的元素的类型,其他的工厂函数帮我们处理。

// 文本工厂

class Text {

constructor(text) {

this.text = text

}

insert(where) {

const txt = document.createTextNode(this.text)

where.appendChild(txt)

}

}

// 链接工厂

class Link {

constructor(url) {

this.url = url

}

insert(where) {

const link = document.createElement('a')

link.href = this.url

link.appendChild(document.createTextNode(this.url))

where.appendChild(link)

}

}

// 图片工厂

class Image {

constructor(url) {

this.url = url

}

insert(where) {

const img = document.createElement('img')

img.src = this.url

where.appendChild(img)

}

}

// DOM工厂

class DomFactory {

constructor(type) {

return new (this[type]())

}

// 各流水线

link() { return Link }

text() { return Text }

image() { return Image }

}

// 创建工厂

const linkFactory = new DomFactory('link')

const textFactory = new DomFactory('text')

linkFactory.url = 'https://surmon.me'

linkFactory.insert(document.body)

textFactory.text = 'HI! I am surmon.'

textFactory.insert(document.body)

装饰者模式 Decorative Pattern:

装饰者(decorator)模式能够在不改变对象自身的基础上,在程序运行期间给对像动态的添加职责(方法或属性)。与继承相比,装饰者是一种更轻便灵活的做法。

简单说:可以动态的给某个对象添加额外的职责,而不会影响从这个类中派生的其它对象。

ES7装饰器

function isAnimal(target) {

target.isAnimal = true

return target

}

// 装饰器

@isAnimal

class Cat {

// ...

}

console.log(Cat.isAnimal) // true

作用于类属性的装饰器:

function readonly(target, name, descriptor) {

discriptor.writable = false

return discriptor

}

class Cat {

@readonly

say() {

console.log("meow ~")

}

}

var kitty = new Cat()

kitty.say = function() {

console.log("woof !")

}

kitty.say() // meow ~

基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值