第二十章 常见的设计模式

本文详细介绍了设计模式中的单例、工厂、抽象工厂、适配器、观察者、代理、策略、MVC和组合模式,阐述了它们的原理、应用实例和优势,为IT开发者提供代码设计的参考框架。
摘要由CSDN通过智能技术生成

一、设计模式

  1. 什么是设计模式
    • 设计模式是一种固定的解决问题的方式
    • 是一套经过代码设计经验总结优化之后的固定的方式
    • 是软件工程的基础,是代码的基石脉络
    • 是一套经过反复使用、多人知晓的、经过分类的、代码设计经验的总结
    • 为了代码的可重用性、让代码更容易被他人理解、保证代码的可靠性。设计模式使代码的编写真正的工程化;设计模式是软件工程的基石脉络,如同大厦的结构
  2. 设计模式的分类(W3C平台)
    • 构造器模式,模块化模式,暴露模块模式,单例模式,中介者模式,原型模式,命令模式,外观模式,工厂模式,Mixin模式,装饰模式,亨元(Flyweight)模式,MVC模式,MVP模式,MVVM模式,组合模式,适配器模式,外观模式,观察者模式,迭代器模式,惰性初始模式,代理模式,建造者模式,…

二、单例模式

  • 单个实例,多次操作只操作(产生)一个实例
    • 应用:
      • 一个项目中所有的信息提示框只需要有一个即可
        • 改内容,改样式
      • 贪吃蛇中的食物对象
        • 优势:节省性能,提升执行速度
    • 语法:
      1. const obj1 = {};
      2. const obj2 = new Object();
      3. const obj3 = new Fn();
        • 对构造函数进行改造
function Fn(){
    if(!Fn.__qfobj__){
        Fn.__qfobj__ = {};
    }
    Fn.__qfobj__.name = "admin";
    return Fn.__qfobj__;
}
  • 作业:利用构造函数的形式实现单例模式的弹出框↑↑↑

三、工厂模式

  • 流水线,多次创建多个具有相同属性名相同方法功能的不同对象
  • 工厂模式的标志:原料(创建基础对象),加工(给基础对象添加属性或方法),出厂(将基础对象返回到外部)
  • 相互独立,分别控制,互不干扰
// 构造自定义函数(内置工厂)
function Fn(name, age){
  this.name = name;
  this.age = age
}
const f1 = new Fn("admin", 18)
const f2 = new Fn("root", 19)
console.log(f1 === f2); 		// false

// ES6新增的工厂模式(类)
class Fun(){
  constructor(name, age){
    this.name = name;
    this.age = age
  }
  show(){
    console.log(this.name, this.age)
  }
}
const fun1 = new Fun("张三"18)
const fun2 = new Fun("李四"20)
console.log(fun1 === fun2); 		// false

四、抽象工厂模式

  • 在工厂模式的基础上进行二次封装,将相同的属性值再次封装
// 造车厂
function CreateCart(brand, color, type){
	this.brand = brand;
  this.color = color;
  this.type = type;
}

// 专门用来生产比亚迪的生产线
function BYDCart(color, type){
  return new CreateCart("比亚迪", color, type);
}

const c1 = new BYDCart("白色", "SUV");
const c2 = new BYDCart("红色", "轿车");

// 专门用来生产大众的生产线
function WCart(color, type){
  return new CreateCart("大众", color, type);
}

五、适配器模式

  • 适配器,用来将不符合功能要求的数据,包装成符合功能要求的数据
  • 需求:
    • 已知功能A,要接受类型a的数据
    • 现有类型b的数据
    • 怎么办?
      • 改造功能A,能接受类型b的数据
      • 改造类型b的数据,改造成类型a的数据
      • 创建一个适配器,让类型b的数据看起来像类型a的数据
// 电子厂:手机(打电话,玩游戏),电脑(玩游戏),一套测试模块:打电话,玩游戏
function CreatePhone(){
  this.name = "手机"
  this.call = function(){
    console.log("打电话")
  }
  this.game = function(){
    console.log("玩游戏")
  }
}
function CreateComputer(){
  this.name = "电脑"
  this.game = function(){
    console.log("玩游戏")
  }
}

function test(obj){
  obj.call();
  obj.game();
}

const p = new CreatePhone()
const c = new CreateComputer()

function Adapter(obj){
  if(!obj.call){
    obj.call = function(){
      console.log("这是" + obj.name + "没有打电话功能")
    }
  }
  return obj;
}

test(p);
test( Adapter(c) );

console.log(p)
console.log(c)

六、观察者模式

  • 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
    • 发布者,被观察者
    • 订阅者,观察者
  • 发布者发布或更新信息,订阅者接收信息,并根据新的变化做出相应的处理
  • 使用观察者模式的好处:
    • 支持简单的广播通信,自动通知所有已经订阅过的对象。
    • 页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性。
    • 目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。
  • 案例:自定义事件监听系统

七、代理模式

  • 代理模式分成两个部分,一个部分是本体:即为你想要实现的功能;另一部分为代理;代理可以代替本体实例化;
  • 代理一般使用在非常耗时的数据上,也会用在体积十分庞大的本体上
  • 劫持系统功能,拦截数据或执行动作或执行时机,完成其他功能或数据的使用
  • 应用:
    • 事件委托
    • 服务器代理解决跨域
      • 客户端a,请求服务器B的数据,跨域了,被阻止
      • 搭建一个服务器A,由服务器A,请求服务器B,获取到服务器B的数据
      • 客户端a,请求自己搭建的服务器A,服务器A将请求到的服务器B的数据给客户端a
    • setter和getter的使用

八、策略模式

  • 策略,计划,规划,可能执行的功能
  • 策略模式的核心,就是分支选择
  • 根据程序执行过程中可能会产生的变化或状态选择执行不同的功能
  • 应用:
    • 状态的变化:单个按钮,多个功能。烟花对象的区分。
    • 数据的变化:所有的函数的参数的默认值处理
  • 不使用分支语句实现策略模式
    • 配合对象
// 根据状态获取数据
// 状态为:type
// 状态值为:goods,商品数据
// 状态值为:user,用户数据
// 状态值为:cart,购物车数据

// 常规写法:
// if( type === "cart" ){}

// 高级写法:
const api = {
  goods(){
    return "获取商品数据"
  },
  user(){
    return "获取用户数据"
  },
  cart(){
    return "获取购物车数据"
  },
  order(){
    return "获取订单数据"
  }
}

let type = "abc";

// 配合异常捕获语法,捕获可能出现的报错
try{
  api[type]();
}catch(err){
  console.log(err)
}

九、MVC模式

  • MVC模式,全名:Model View Controller,模型、视图、控制器
    • M:模型:按照要求来取出数据
    • V:视图:用户直观看到的页面
    • C:控制器:向系统发出指令的工具
  • 工作流程:
    1. 浏览器,调用控制器,对他发出指令
    2. 控制器,按指令选取一个合适的模型
    3. 模型,按控制器指令取出相应的数据
    4. 控制器,按指令取出相应的视图
    5. 把第三步取到的数据按照用户想要的样子在视图显示出来
  • 优势:
    • 耦合低,复用性高
  • 如:轮播图
    • 模型:图片数据
    • 视图:轮播图如何切换(左右,上下,淡入淡出)
    • 控制器:核心功能(绑定事件,切换索引,调取数据,调取视图)
function Model(){
  this.m1 = function(){
    return "hello"
  }
  this.m2 = function(){
    return "world"
  }
  this.m3 = function(){
    return "123"
  }
  this.m4 = function(){
    return "hahaha"
  }
}
function View(){
  this.v1 = function(d){
    console.log(d);
  }
  this.v2 = function(d){
    alert(d)
  }
  this.v3 = function(d){
    document.write(d)
  }
}
function Control(){
  const m = new Model()
  const v = new View()
  this.c1 = function(){
    const d = m.m1();
    v.v2(d);
  }
  this.c2 = function(){
    const d = m.m4();
    v.v1(d);
  }
  this.c3 = function(){
    const d = m.m2();
    v.v3(d);
  }
  this.c4 = function(){
    const d = m.m2();
    v.v1(d);
  }
}

const c = new Control();
c.c1();
c.c2();

十、组合模式

  1. 组合模式:把多个对象组成树状结构来表示局部与整体,使得用户可以同时操作单个对象或对象的组合。
  2. 对于创建动态用户界面来说,组合模式可以算是为其量身定做的,因为HTML结构正好符合组合模式适用场景的结构。
  3. 组合模式擅长对大批量对象进行操作,转为组织这类对象把操作从一个层次向下一个层次传递设计,借此可以弱化对象间的耦合关系并且可以互换使用一些类或者实例,使代码模块化程度更高,维护更容易。
  4. 简单的说,组合模式是将一批子对象组织为树形结构,一条顶层的命令会操作树中所有的下属子对象。提高了代码的模块化程度,对于动态的HTML界面具有很强的适用性。
  5. 要想使用组合模式,得先具备组合器
  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨树林er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值