常用的设计模式

设计模式是软件开发中的经验总结,本文详细介绍了10种常见设计模式:构造器、原型、工厂、抽象工厂、建造者、单例、装饰器、适配器、策略和代理模式。通过实例和优缺点分析,帮助开发者更好地理解和运用这些模式,提升代码的可维护性和扩展性。
摘要由CSDN通过智能技术生成
  • 设计模式是我们在解决问题的时候,针对特定问题给出的优化处理方案
  • 在JS设计模式中,最核心的思想:封装变化
  • 将变与不变分离,确保变化的部分灵活,不变的部分稳定

常用设计模式:单例、工厂、抽象工厂、发布-订阅、代理、适配器等等
以下讲了10种:

  1. 构造器模式
  2. 原型模式
  3. 工厂模式
  4. 抽象工厂模式
  5. 建造者模式
  6. 单例模式
  7. 装饰器模式
  8. 适配器模式
  9. 策略模式
  10. 代理模式

1、构造器模式

var employee = {
  name:'李雷',
  age:18
}
var employee2 = {
  name:'韩梅梅',
  age:19
}

以上写法,如果数据量变多,代码重复且臃肿。

function Employee(name,age){
  this.name = name;
  this.age = age;
  this.say = function(){
    console.log(this.name+'--'+this.age)
  }
}

new Employee('唐三',18)
new Employee('小舞',16)

缺点: say方法都是一样的,每次创建都会重新创建。通过原型解决

2、原型模式

function Employee(name,age){
  this.name = name;
  this.age = age;
}
Employee.prototype.say = function(){
  console.log(this.name+'--'+this.age)
}

new Employee('唐三',18)
new Employee('小舞',16)

用类的方式实现:

class Employee{
  constructor(name,age){
    this.name = name;
    this.age = age;
  }
  say(){
    console.log(this.name+'--'+this.age)
  }
}

const employee = new Employee('商璃',17)
employee.say()

一个示例(Tab切换):

function Tabs(selector){ // 参数:CSS选择器
  this.selector = document.querySelector(selector)
  this.headerItems = this.selector.querySelectorAll('.header li')
  this.boxItems = this.selector.querySelectorAll('.box li')
}
Tabs.prototype.change = function(){
  for(let i = 0;i<this.headerItems.length;i++){
    this.headerItems[i].onClick = ()=>{
    	for(let m = 0;m<this.headerItems.length;m++){
         this.headerItems[m].classList.remove('active')
         this.boxItems[m].classList.remove('active')
      }
      this.headerItems[i].classList.add('active')
      this.boxItems[i].classList.add('active')
    }
  }
}
new Tabs('.container')

3、工厂模式

由一个工厂对象决定创建某一种产品对象的实例。主要用来创建同一类对象。

function UserFactory(role){
  function User(role,pages){
    this.role = role
    this.pages = pages
  }
  switch(role){
    case "superadmin":
      return new User('superadmin',['home','user-manage','right-manage','news-manage'])
    case "admin":
      return new User('admin',['home','right-manage','news-manage'])
    case "editor":
      return new User('editor',['home','news-manage'])
    default:
      throw new Error('参数错误')
  }
}

简单工厂的优点在于:只需一个正确的参数就可以获取到需要的对象,而无需知道其创建的具体细节。
但是,在函数内包含了所有对象的创建、判断逻辑,每增加新的构造函数还需要修改判断逻辑代码。
当对象变得更多时,这个函数就会成为庞大的超级函数,变得难以维护。
所以,简单工厂只能作用于:创建的对象数量较少、对象创建逻辑不复杂的时候。

4、抽象工厂模式

抽象工厂模式并不直接生成实例,而是用于对产品类的创建

class User{
  constructor(name,role,pages){
    this.name = name
    this.role = role
    this.pages = pages
  }
  welcome(){
    console.log('欢迎回来',this.name)
  }
  dataShow(){
    throw new Error('抽象方法不允许直接调用')
  }
}

class SuperAdmin extends User{
  constructor(name){
    super(name,'superadmin',['home','user-manage','right-manage','news-manage'])
  }
  dataShow(){
    console.log('superadmin-datashow')
  }
  addRight(){
    ...
  }
}

class Admin extends User{
  constructor(name){
    super(name,'admin',['home','right-manage','news-manage'])
  }
  dataShow(){
    console.log('admin-datashow')
  }
  addRight(){
    ...
  }
}
class Editor extends User{
  constructor(name){
    super(name,'editor',['home','news-manage'])
  }
  dataShow(){
    console.log('editor-datashow')
  }
  addNews(){
    ...
  }
}

function getAstractUserFactory(role){
  switch(role){
    case "superadmin":
      return SuperAdmin
    case "admin":
      return Admin
    case "editor":
      return Editor
    default:
      throw new Error('参数错误')
  }
}
let UserClass = getAstractUserFactory('editor')
let user = new UserClass('Lili')

5、建造者模式

建造者模式(builder pattern)属于创建型模式的一种,提供一种创建复杂对象的方式。
它将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一步一步地创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要指定内部的具体构造细节。

class Navbar{
  init(){
    console.log("navbar-init")
  }
  getData(){
    return new Promise((resolve)=>{
      setTimeout(()=>{
        resolve();
         console.log("navbar-getdata")
      },1000)
    })
  }
  render(){
    console.log('navbar-rendar')
  }
}
class Creator{
	async startBuild(builder){
	    await builder.init()
	    await builder.getData()
	    await builder.render()
	  }
}

const op = new Creator()
op.startBuild(new Navbar())

建造者模式将一个复杂对象的构建层与其表示层相互分离。
工厂模式主要是为了创建对象实例或者类簇(抽象工厂),关心的是最终产出的是什么,而不关系创建的过程。
建造者模式关心的是创建这个对象的整个过程,甚至于创建对象的每一个细节。

6、单例模式

  • 保证一个类仅有一个实例,并提供一个访问它的全局访问点
  • 主要解决一个全局使用的类频繁地创建和销毁,占用内存

闭包的方式

var Singleton = (function(){
  var instance
  function User(name,age){
    this.name = name;
    this.age = age
  }
  return function(){
    if(!instance){
      // 创建实例
      instance = new User('lili',20)
    }
    return instance
  }
})()

class的方式

class Singleton{
  constructor(name,age){
    if(!Singleton.instance){
      this.name = name
      this.age = age
      Singleton.instance = this
    }
    return Singletom.instance
  }
}
const singleton = new Singleton('lili',20)

一个示例(Modal 弹窗)

const Modal = (function(){
  let instance = null;
  return function(){
    if(!instance){
      instance = document.createElement("div")
      instance.innerHTML = '对话框'
      instance.className = 'cx'
      instance.style.display = 'none'
      document.body.appendChild(instance)
    }
    return instance
  }
})()

7、装饰器模式

装饰器模式能够很友好的对已有功能进行拓展,这样不会更改原有的代码、对其他的业务产生影响,方便在较少的改动下对软件功能进行拓展。

Function.prototype.before = function(beforeFn){
  var _this = this;
  return function(){
    beforeFn.apply(this,arguments)
    return _this.apply(this,arguments)
  }
}

Function.prototype.after = function(afterFn){
  var _this = this;
  return function(){
    const res =  _this.apply(this,arguments)
    afterFn.apply(this,arguments)
    return res
  }
}
function test (){
  console.log('test')
}

var test1 = test.before(()=>{
   console.log('before test')
}).after(()=>{
   console.log('after test')
})
test1()

8、适配器模式

将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。

class TencentMap{
  show(){
    console.log('开始渲染。。。')
  }
}
class BaiduMap{
  display(){
    console.log('开始渲染Baidu')
  }
}

class BaiduMapAdapter extends BaiduMap{
  constructor(){
    super()
  }
  show(){
    this.display()
  }
}

function renderMap(map){
  map.show()
}

renderMap(new TencentMap())
renderMap(new BaiduMap())

9、策略模式

策略模式定义了一些列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的客户。
策略模式属于对象行为模式,他通过对算法进行封装,把使用算法的责任和算法的实现分隔开,并委派给不同的对象对这些算法进行管理。
该模式主要解决在有多种算法相似的情况下,使用if…else所带来的复杂和难以维护。
它的优点是算法可以自由切换,同时可以避免多重if…else判断,且具有良好的扩展性。

let strategry = {
  "A":(salary)=>{
    return salary * 4
  },
  "B":(salary)=>{
    return salary * 3
  },
  "C":(salary)=>{
    return salary * 2
  }
}

function calBonus(level,salary){
  return strategry[level](salary)
}
calBonus("A",10000)
calBonus("C",8000)

10、代理模式

代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。
代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件、资源、内存中的对象或者一些难以复制的东西。

let obj = {}
let proxy = new Proxy(obj,{
  get(target,key){
    console.log('get',target[key])
    return target[key]
  },
  set(target,key,value){
    if(key==='data'){
      box.innerHTML = value
    }
    target[key]= value
  }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值