JavaScript-其他设计模式
其他设计模式
JavaScript 中不常用
对应不到经典场景
原型模式-行为型
- clone 自己,生成一个新对象
 - java 默认有 clone 接口,不用自己实现
 
//'object.creat'用到了原型模式的思想(虽然不是java中的clone)
//基于一个原型创建一个对象
var prototype = {
  gatName: function() {
    return this.first + " " + this.last;
  },
  say: function() {
    console.log("hello");
  }
};
// 基于原型创建x
var x = Object.create(prototype);
x.first = "A";
x.last = "B";
console.log(x.gatName());
x.say();
//基于原型创建y
var y = Object.create(prototype);
y.first = "A";
y.last = "B";
console.log(y.gatName());
y.say();
- 对比 js 中的原型 prototype
- prototype 可以理解为 es6 class 的一种底层原理
 - 而 class 是实现面向对象的基础,并不是服务于某个模式
 - 若干年后 es6 普及,大家可能会忽略掉 prototype
 - 但是 Object.create 却会长久存在
 
 
桥接模式-结构型
- 用于把抽象化与现实化解耦
 - 使得二者可以独立变化
 - js 中未找到经典应用
 


class ColorShap {
  yellowCircle() {
    console.log("yellow circle");
  }
  redCircle() {
    console.log("red circle");
  }
  yellowTriangle() {
    console.log("yellow triangle");
  }
  redTriangle() {
    console.log("red triangle");
  }
}
// 测试
let cs = new ColorShap();
cs.yellowCircle();
cs.redCircle();
cs.yellowTriangle();
cs.redTriangle;
上面代码改进后
class Color {
  constructor(name) {
    this.name = name;
  }
}
class Shap {
  constructor(name, color) {
    this.name = name;
    this.color = color;
  }
  draw() {
    console.log(`${this.color.name} ${this.name}`);
  }
}
// 测试代码
let red = new Color("red");
let yellow = new Color("yellow");
let circle = new Shap("circle", red);
circle.draw();
let triabgle = new Shap("triangle", yellow);
triabgle.draw();
- 设计原则验证
- 抽象与实现分离,解耦
 - 符合开放封闭原则
 
 
组合模式-结构型
- 生成树形结构
 - 让整体和部分具有一致的操作方式
 

- js 经典应用中,未找到这吗复杂的数据结构
 - 虚拟 DOM 中的 vnode 是这种形式,但数据结构类型简单
 - 用 js 实现一个菜单,不算经典应用,与业务相关
 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <div id="div1" class="container">
      <p>123</p>
      <p>456</p>
    </div>
  </body>
</html>
<script>
  var 组合模式 = {
    tag: "div",
    attr: {
      id: "div1",
      className: "container"
    },
    children: [
      {
        tag: "p",
        attr: {},
        children: ["123"]
      },
      {
        tag: "p",
        attr: {},
        children: ["456"]
      }
    ]
  };
</script>
- 整体和单个节点的操作是一致的
 - 整体和单个节点的数据结构也一致
 
- 设计原则验证
- 将整体和单个节点的操作抽象出来
 - 符合开放封闭原则
 
 
享元模式-结构型
- 共享内存(主要考虑内存,而非效率)
 - 相同数据,共享内存
 - js 中未找到经典应用场景
 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <!-- 无限下拉列表,将事件代理到高层节点上 -->
    <!-- 如果都绑定到`<a>`标签,对内存开销太大 -->
    <div id="div1">
      <a href="#">a1</a>
      <a href="#">a2</a>
      <a href="#">a3</a>
      <a href="#">a4</a>
      <!-- 无限下拉列表 -->
    </div>
    <script>
      var div1 = document.getElementById("div1");
      div1.addEventListener("clink", function(e) {
        var target = e.target;
        if (e.nodeName === "A") {
          alert(target.innerHrml);
        }
      });
    </script>
  </body>
</html>
- 设计原则验证
- 将相同的部分抽象出来
 - 符合开封闭原则
 
 
策略模式-行为型
- 不同策略分开处理
 - 避免出现大量
if...else或者switch..case - js 中未找到经典应用场景
 
class User {
  constructor(type) {
    this.type = type;
  }
  buy() {
    if (this.type === "ordinary") {
      console.log("普通用户购买");
    } else if (this.type === "member") {
      console.log("会员购买");
    } else if (this.type === "vip") {
      console.log("vip 用户购买");
    }
  }
}
// 测试代码
var u1 = new User("ordinary");
u1.buy();
var u2 = new User("member");
u2.buy();
var u3 = new User("vip");
u3.buy();
上面代码改进后
class OridinaryUser {
  buy() {
    console.log("普通用户购买");
  }
}
class MemberUser {
  buy() {
    console.log("会员用户购买");
  }
}
class vipUser {
  buy() {
    console.log("vip用户购买");
  }
}
// 测试代码
var u1 = new OridinaryUser("ordinary");
u1.buy();
var u2 = new MemberUser("member");
u2.buy();
var u3 = new vipUser("vip");
u3.buy();
- 设计原则验证
- 不同策略,分开处理,而不是混合在一起
 - 符合开放封闭原则
 
 
模板方法模式-行为型
class Action {
  handle() {
    handle1();
    handle2();
    handle3();
  }
  handle1() {
    console.log("1");
  }
  handle2() {
    console.log("2");
  }
  handle3() {
    console.log("3");
  }
}
职责连接模式-行为型
- 一步操作可能分为多个职责角色来完成
 - 把这些角色都分开,然后用一个链串起来
 - 将发起者和各个处理者隔离
 
class Action {
  constructor(name) {
    this.name = name;
    this.nextAction = null;
  }
  setNextAction(action) {
    this.nextAction = action;
  }
  handle() {
    console.log(`${this.name} 审批`);
    if (this.nextAction != null) {
      this.nextAction.handle();
    }
  }
}
let a1 = new Action("组长");
let a2 = new Action("经理");
let a3 = new Action("总监");
a1.setNextAction(a2);
a2.setNextAction(a3);
a1.handle();
js 中的链式操作
- 职责链模式和业务结合较多,js 中能联想到链式操作
 - jQuery 的链式操作,promise.then 的链式操作
 
设计原则验证
- 发起者与各个处理者隔离
 - 符合开放封闭原则
 
命令模式-行为型
- 执行命令时,发布者和执行者分开
 - 中间加入命令对象,作为中转站

 
class Receive {
  exec() {
    console.log("执行");
  }
}
class Command {
  constructor(recever) {
    this.receive = recever;
  }
  cmd() {
    console.log("触发命令");
    this.receive.exec();
  }
}
class Invoker {
  constructor(command) {
    this.command = command;
  }
  invoke() {
    console.log("开始");
    this.command.cmd();
  }
}
//士兵
let solider = new Receive();
//小号手
let trumpter = new Command(solider);
//将军
let general = new Invoker(trumpter);
general.invoke();
js 中的应用
- 网页富文本编辑器操作,浏览器封装了一个命令对象
 document.exeCommand('bold')document.exeCommand('undo')
设计原则验证
- 命令对象与执行对象分开,解耦
 - 符合开放封闭原则
 
备忘录模式-行为型
- 随时记录一个对象的状态变化
 - 随时可以恢复之前的某个状态(如撤销功能)
 - 未找到 js 中经典应用,除了一些工具(编辑器)
 
// 状态备忘
class Memento {
  constructor(content) {
    this.content = content;
  }
  getContent() {
    return this.content;
  }
}
// 备忘列表
class CareTaker {
  constructor() {
    this.list = [];
  }
  add(memento) {
    this.list.push(memento);
  }
  get(index) {
    return this.list[index];
  }
}
//编辑器
class Editor {
  constructor() {
    this.content = null;
  }
  setContent(content) {
    this.content = content;
  }
  getContent() {
    return this.content;
  }
  saveContentToMemento() {
    return new Memento(this.content);
  }
  getContentFromMemento(memento) {
    this.content = memento.getContent();
  }
}
//测试代码
let editor = new Editor();
let careTaker = new CareTaker();
editor.setContent("111");
editor.setContent("222");
careTaker.add(editor.saveContentToMemento()); //存储备忘录
editor.setContent("333");
careTaker.add(editor.saveContentToMemento()); //存储备忘录
editor.setContent("444");
console.log(editor.getContent());
editor.getContentFromMemento(careTaker.get(1)); //撤销
console.log(editor.getContent());
editor.getContentFromMemento(careTaker.get(0)); //撤销
console.log(editor.getContent());
- 设计原则验证
- 状态对象与使用者分开,解耦
 - 符合开放封闭原则
 
 
中介者模式-行为型

class Mediator {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
  setA() {
    let number = this.b.number;
    this.a.setNumber(number * 100);
  }
  setB() {
    let number = this.a.number;
    this.b.setNumber(number / 100);
  }
}
class A {
  constructor() {
    this.number = 0;
  }
  setNumber(num, m) {
    this.number = num;
    if (m) {
      m.setB();
    }
  }
}
class B {
  constructor() {
    this.number = 0;
  }
  setNumber(num, m) {
    this.number = num;
    if (m) {
      m.setA();
    }
  }
}
let a = new A();
let b = new B();
let m = new Mediator(a, b);
a.setNumber(100);
console.log(a.number, b.number); //100 1
b.setNumber(100);
console.log(a.number, b.number); //10000 100
- 设计原则验证
- 将各个关联对象通过中介者隔离
 - 符合开放封闭原则
 
 
访问者模式-行为型
- 将数据操作和数据结构进行分离
 - 使用场景不多
 
解释器模式-行为型
- 描述语言语法如何定义,如何解释和编译
 - 用于专业场景
 
JavaScript-其他设计模式的更多相关文章
- javascript事件设计模式
		
JavaScript事件设计模式 http://plkong.iteye.com/blog/213543 http://www.docin.com/p-696665922.html
 - 7 种 Javascript 常用设计模式学习笔记
		
7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...
 - javascript 事件设计模式
		
http://plkong.iteye.com/blog/213543 1. 事件设计概述 事件机制可以是程序逻辑更加清晰可见,在JavaScript中很多对象都有自己的事件,如:button有onc ...
 - 【JavaScript】设计模式-module模式及其改进
		
写在前面 编写易于维护的代码,其中最重要的方面就是能够找到代码中重复出现的主题并优化他们,这也是设计模式最有价值的地方 说到这里...... <head first设计模式>里有一篇文章, ...
 - 更适用于JavaScript的设计模式:面向委托的设计,了解一下?(下)
		
先来看一下传统的面向类式的写法: function Foo(name) { this.name = name; } Foo.prototype.sayName = function() { conso ...
 - Javascript事件设计模式(七)
		
一:事件设计概述 事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有 onchange事件,通过这些事件可以方便编程 ...
 - Javascript 常用设计模式
		
转载自:https://blog.csdn.net/buptlyz/article/details/52018193 单例模式(模块模式):确保始终只创建一个实例的对象时使用的设计模式. 为什么需要采 ...
 - Javascript常见设计模式解析
		
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.毫无疑问,设计模式于己 ...
 - 深入理解javascript之设计模式
		
设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计实用的的通用设计结构. 设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每个设计模式都聚焦于一个面向对象的设计难题或问题. ...
 - 深入理解JavaScript的设计模式
		
使用适当的设计模式可以帮助你编写更好.更易于理解的代码.这样的代码也更容易维护.但是,重要的是不要过度使用它们.在使用设计模式之前,你应该仔细考虑你的问题是否符合设计模式. 当你开始一个新的项目时,你 ...
 
随机推荐
- B-Tree 和 B+Tree 结构及应用,InnoDB 引擎, MyISAM 引擎
			
1.什么是B-Tree 和 B+Tree,他们是做什么用的? B-Tree是为了磁盘或其它存储设备而设计的一种多叉平衡查找树,B-Tree 和 B+Tree 广泛应用于文件存储系统以及数据库系统中. ...
 - 西柚考勤系统——alpha2
			
这个作业属于哪个课程 http://edu.cnblogs.com/campus/xnsy/GeographicInformationScience 这个作业的要求在哪里 https://www.cn ...
 - 【WPF学习】第二十五章 日期控件
			
WPF包含两个日期控件:Calender和DatePicker.这两个控件都被设计为允许用户选择日期. Calendar控件显示日期,在与Windows操作系统中看到的日历(例如,当配置系统日期时看到 ...
 - BERT模型总结
			
BERT模型总结 前言  BERT是在Google论文<BERT: Pre-training of Deep Bidirectional Transformers for Language U ...
 - ios--->特定构造方法NS_DESIGNATED_INITIALIZER
			
特定构造方法 1> 后面带有NS_DESIGNATED_INITIALIZER的方法,就是特定构造方法 2> 子类如果重写了父类的[特定构造方法],那么必须用super调用父类的[特定构造 ...
 - Spring-data-Jpa项目搭建
			
传送门:Spring Data 学习 Spring Data 开发环境搭建 Spring-data-jpa详解 简介 Spring Data是什么 Spring Data是一个用于简化数 ...
 - Linux下启动/关闭Oracle
			
一.Linux下启动Oracle Linux下启动Oracle分为两步: 1)启动监听: 2)启动数据库实例: 1.登录服务器,切换到oracle用户,或者以oracle用户登录 [admin@dat ...
 - 三、Django学习之单表查询接口
			
查询接口 all() 查询所有结果,结果是queryset类型 filter(**kwargs) and条件关系:参数用逗号分割表示and关系 models.Student.objects.filte ...
 - Android之SimpleAdapter简单实例和SimpleAdapter参数说明
			
SimpleAdapter基本上认知了其参数含义 用起来就简单多了 SimpleAdapter的参数说明 第一个参数 表示访问整个android应用程序接口,基本上所有的组件都需要 第二个参数表示生 ...
 - ubuntu 14.04 安装wordpress
			
转者注:若没有Apache + PHP + MySQL环境,请参考我的这篇博客 (1)首先下载wordpress, sudo wget http://wordpress.org/latest.tar. ...