服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

你肯定用过这八种设计模式,面试官问起不要没话讲啦!

日期: 来源:前端之神收集编辑:林三心不学挖掘机
 

模拟面试、简历指导可私信找我,最低的价格收获最高的指导~

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。

设计模式是什么?

设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

大白话就是,在合适的场景使用合适的设计模式:

  • 代码比较稳定
  • 代码比较高效
  • 代码维护性强
  • 代码比较规范

面试官喜欢问?

确实,现在面试官贼喜欢问设计模式,他们会问你:你在开发过程中使用过什么设计模式

然后你就懵逼了,你可能都不知道设计模式是啥。。。

或者说,其实你在项目中用过,但是你不知道那就是设计模式

接下来我就介绍几种大家大概率在项目中使用过的设计模式吧~

工厂模式

工厂模式通俗点说就是:更方便地去创建实例

大家开发中应该使用过 axios.create 这个方法吧?这其实就是工厂模式的实践之一

我简单分析一下 axios.create 的原理(不一定跟源码一模一样)

** axios.create() **每次返回的都是一个全新的实例~

原理部分
class Axios {}
class A {
  create() {
    return new Axios()
  }
}

const axios = new A()

export default axios

使用部分

import axios from 'axios'

// 创建很多实例
const httpRequest1 = axios.create()
const httpRequest2 = axios.create()
const httpRequest3 = axios.create()
const httpRequest4 = axios.create()
const httpRequest5 = axios.create()
 

这就是工厂模式~

单例模式

单例模式通俗点说就是:定义一个类,生成一个实例,并且整个项目仅此这一个实例

相信大家在项目中都封装使用过Axios

我们会先定义封装一个请求的实例然后暴露出去

utils/request.ts

// 定义一个类
class HttpRequest {
  instance: AxiosInstance;
  constructor(options: CreateAxiosOptions) {
    this.instance = axios.create(options)
  }

  setHeader() {...}
  get() {...}
  post() {...}
  put() {...}
  delete() {...}
}
// 生成一个实例
const request = new HttpRequest({})

// 全局仅用这么一个请求实例
export default request

然后在项目中各处去使用这一个请求实例

import request '@/utils/request'

const fetchData = (url) => {
  return request.get(url)
}
 

这就是单例模式~

策略模式

策略模式通俗点说就是:根据不同的策略去做不同的事情

比如我需要根据不同的年龄去做不同的处理

const doSomething = (age: number) => {
  if (age === 20) {
    // do something
  }
  if (age === 30) {
    // do something
  }
  if (age === 40) {
    // do something
  }
}

但其实这样做有很多坏处:

  • 可读性一般(实际代码比这更复杂)
  • 可维护性差,如果以后多一种age判断,又要修改这个doSomething函数,规范的话是不建议去过多修改函数本身的
  • 可拓展性差,多一种age判断只能修改原函数体

所以我们可以这么做

// map存储,好拓展
const doMap: Record<number, Function> = {
  20: () => { // do something },
  30: () => { // do something },
  40: () => { // do something },
}

const doSomething = (age: number) => {
  doMap[age]?.()
}
 

这就是策略模式模式~

适配器模式

适配器模式通俗点说就是:将一种格式适配成你所需要的格式

比如有一个场景:后端给你返回了三种数据格式,但是你需要把这三种格式转成你前端所需要的格式

// 格式1
const data1 = [{age1:20,name1:'林三心'}]
// 格式2
const data2 = [{age2:20,name2:'林三心'}]
// 格式3
const data3 = [{age3:20,name3:'林三心'}]

这个时候你需要定义几个适配器类

class Adapter1 {
  data: { age1: number; name1: string }[]
  constructor(data) {
    this.data = data
  }
  transform() {
    return this.data.map(({ age1, name1 }) => ({
      age: age1,
      name: name1
    }))
  }
}

class Adapter2 { 
  // 同理
}

class Adapter3 {
  // 同理
}

当你需要转换成你需要的数据时,调用这些类就行

const adapter1 = new Adapter1(data1)
// 适配成功
const data = adapter1.transform()
 

这就是适配器模式模式~

装饰器模式

装饰器模式通俗点说就是:定义一个类,在不改这个类的前提下,给这个类拓展功能

前端

场景:普通人变成超人

class Man {
  say() {
    console.log('我是普通人')
  }
}
class Man2SuperMan {
  man: Man
  constructor(man) {
    this.man = man
  }
  say() {
    this.man.say()
    console.log('我变成超人啦!')
  }
}

const man = new Man()
const superMan = new Man2SuperMan(man)
man.say()
// 我是普通人
superMan.man()
// 我是普通人
// 我变成超人啦!

后端

其实装饰器在后端语言中应用很多,在 Nodejs 中同样也有很多应用

比如下面的,我们看起来是发送POST api-duplicate请求,然后会执行下面的duplicate函数

但是大家有没有想过实现原理是什么呢?

其实就是装饰器的作用,拓展了duplicate这个函数,使它具备了匹配POST api-duplicate后执行的能力

  @Post('api-duplicate') // 装饰器
  async duplicate() {
  }
 

这就是装饰器模式~

代理模式

代理模式通俗易懂点说就是:为对象提供一种代理,便以控制对这个对象的访问,不能直接访问目标对象

最好的实践场景就是ES6 Proxy

const handler = {
    get: function(obj, prop) {
        return prop in obj ? obj[prop] : 7;
    }
};

const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b);      // 1, undefined
console.log('c' in p, p.c); // false, 37
 

这就是代理模式~

观察者模式

观察者模式通俗点讲就是:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知

我们平时使用的框架Vue,它的响应式就是基于观察者模式去做的,下面是简单展示一下它的原理

class Subject {
  count: number
  observers: any[]
  constructor() {
    this.count = 0
    this.observers = []
  }
  getCount() {
    return this.count
  }
  setCount(count: number) {
    // 设置值之后通知更新
    this.count = count
    this.notify()
  }
  notify() {
    this.observers.forEach((o) => {
      o.update()
    })
  }
  push(o) {
    this.observers.push(o)
  }
}

class Observer {
  constructor(name: string, sub: Subject) {
    this.name = name
    this.subject = sub
    this.subject.push(this)
  }
  update() {
    console.log(
      `${this.name} 变了 ${this.subject.getCount()}`
    )
  }
}


const sub = new Subject()
// 观察一号
const observer1 = new Observer('一号', sub)
// 观察二号
const observer2 = new Observer('二号', sub)

sub.setCount(1)
// 一号 变了 1
// 二号 变了 1
 

这就是观察者模式~

发布订阅模式

发布订阅模式观察者模式很像,他们其实都有发布者订阅者,但是他们是有区别的

  • 观察者模式发布订阅是互相依赖的
  • 发布订阅模式发布订阅是不互相依赖的,因为有一个统一调度中心

为了更好区分这两种设计模式,我举一个现实中的生活例子吧!

例子一:A想转手一部手机,B想买,于是两个人互加联系方式,B买了手机后,每次有手机系统更新时,都需要A去联系B进行升级教学

例子二:A想转手一部手机,所以挂在了某平台转卖,B在平台看到手机并买下,每次有手机系统更新时,A只需要跟平台反馈并提供升级教程,平台自然会通知B进行升级教学

我们Vue EventBus就是用了发布订阅模式

class EventEmitter {
    constructor() {
        this.cache = {}
    }

    on(name, fn) {
        const tasks = this.cache[name]
        if (tasks) {
            this.cache[name].push(fn)
        } else {
            this.cache[name] = [fn]
        }
    }

    off(name, fn) {
        const tasks = this.cache[name]
        if (task) {
            const index = tasks.findIndex(item => item === fn)
            if (index >= 0) {
                this.cache[name].splice(index, 1)
            }
        }
    }

    emit(name, ...args) {
        // 复制一份。防止回调里继续on,导致死循环
        const tasks = this.cache[name].slice()
        if (tasks) {
            for (let fn of tasks) {
                fn(...args)
            }
        }
    }

    once(name, cb) {
        function fn(...args) {
            cb(args)
            this.off(name, fn)
        }
        this.on(name, fn)
    }
}

const eventBus = new EventEmitter()
// 组件一
eventBus.on('event', (val) => {
  console.log(val)
})
// 组件二
eventBus.emit('event', 'params')
 

这就是发布订阅模式~

结语

我是林三心,一个热心的前端菜鸟程序员。如果你上进,喜欢前端,想学习前端,那咱们可以交朋友,一起摸鱼哈哈,摸鱼群,关注我,拉你进群,有5000多名前端小伙伴在等着一起学习哦 -->

 

模拟面试、简历指导可私信找我,价格超级实惠~

相关阅读

  • 在欧美TikTok赔了钱,我“逃”回了东南亚

  • 出品|虎嗅商业消费组作者|周月明编辑|苗正卿题图|视觉中国 “TikTok用一年的时间,走完了抖音5年的商业化之路。”近日,TikTok宣布在东南亚推出TikTok商城,再次印证了业内流传的这
  • 掌握这8个要点,看懂「深色模式」UI设计

  • 关注▲Clip设计夹后台回复“进群”加入设计成长群 设计夹的第137篇文章分享 Halo,这里是设计夹,今天为大家分享的是「深色UI设计」。深色UI设计又被称为深色模式,强调深色背景
  • 抓好备春耕 筑牢压舱石|“4090”模式种玉米

  • “我家跟着村里用‘4090’模式种玉米3年了,每亩地能增产120多斤,听说今年要在我们村尝试燕麦玉米套种,这好事可不能把我落下。”黑龙江省安达市羊草镇五撮村村民李大姐去年就整
  • 99%的复盘会议都无效?因为领导“动口不动手”

  • 职场大胆开麦:在工作中,我们不难发现:有些人能触类旁通、举一反三,而有些人始终只会就事论事、一事一议;有些人是“能说会练真把式”,而有些人是“光说不练假把式”;还有些人是“光
  • 直播微视评:这就是规矩,懂吗?

  • 不讲规矩的人有多可恨,公共场所抽烟,高铁霸座,遛狗不系绳,其实最可恨的还不仅于此,而是这些人不仅不接受劝阻,反而强词夺理,一副你能把我怎么着的嚣张态度。极度令人畅快的一幕来了
  • 新学期 “心”导航

  • 从悠闲舒适的假期模式转换成紧张忙碌的学习模式是不是已经感受到有“一点点”焦虑了? 这里为大家准备了一份开学心理调适指南希望安大人更从容地开启新学期!积极面对脚踏实地

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • “幸福吆喝”里看消费企稳回暖

  • 本报记者 王 蕾 通讯员 丁慧敏 郭凯时隔4个多月,北疆最大的活畜交易市场“黄公巴扎”重新开市了!放眼望去,成群的马、牛、羊或惬意休憩,或在圈内散着步,熙攘的人群川流不息,来打
  • 广州投靠入户和随迁入户有什么区别?

  • ✦今日问答✦是我们推出的互动栏目我们会从网友们提的问题里选出典型的、大家常问的问题进行解答关于车牌、入户、社保、玩乐等问题都可以问哦!只需要在这篇文章底部留言就可
  • 广州最新放假安排!

  • 要说肥秋最喜欢写什么文?那一定是放!假!通!知!放假不积极,思想有问题!今天小编就来给大家盘点一下广州的假期大家可以期待一下即将到来的假期可不是周末也不是清明节而是↓↓↓妇女