其他设计模式

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-其他设计模式的更多相关文章

  1. javascript事件设计模式

    JavaScript事件设计模式 http://plkong.iteye.com/blog/213543 http://www.docin.com/p-696665922.html

  2. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  3. javascript 事件设计模式

    http://plkong.iteye.com/blog/213543 1. 事件设计概述 事件机制可以是程序逻辑更加清晰可见,在JavaScript中很多对象都有自己的事件,如:button有onc ...

  4. 【JavaScript】设计模式-module模式及其改进

    写在前面 编写易于维护的代码,其中最重要的方面就是能够找到代码中重复出现的主题并优化他们,这也是设计模式最有价值的地方 说到这里...... <head first设计模式>里有一篇文章, ...

  5. 更适用于JavaScript的设计模式:面向委托的设计,了解一下?(下)

    先来看一下传统的面向类式的写法: function Foo(name) { this.name = name; } Foo.prototype.sayName = function() { conso ...

  6. Javascript事件设计模式(七)

    一:事件设计概述 事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有 onchange事件,通过这些事件可以方便编程 ...

  7. Javascript 常用设计模式

    转载自:https://blog.csdn.net/buptlyz/article/details/52018193 单例模式(模块模式):确保始终只创建一个实例的对象时使用的设计模式. 为什么需要采 ...

  8. Javascript常见设计模式解析

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.毫无疑问,设计模式于己 ...

  9. 深入理解javascript之设计模式

    设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计实用的的通用设计结构. 设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每个设计模式都聚焦于一个面向对象的设计难题或问题. ...

  10. 深入理解JavaScript的设计模式

    使用适当的设计模式可以帮助你编写更好.更易于理解的代码.这样的代码也更容易维护.但是,重要的是不要过度使用它们.在使用设计模式之前,你应该仔细考虑你的问题是否符合设计模式. 当你开始一个新的项目时,你 ...

随机推荐

  1. jenkins集成jmeter-进阶篇

    1.gitlab自动触发jenkins构建 1⃣️安装插件: 2⃣️新建工程,设置git url,build when a change is pushed auto.sh /bin/sh echo ...

  2. Python中的 if __name__ == '__main__' 是什么意思?

    最近在看Python代码的时候,因为是Python初学者,看到这个if __name__ == '__main__' 的判断,并且下面还有代码语句,看了其他地方的说明,还是没搞明白是什么意思, 在看到 ...

  3. Java 添加、读取、删除Excel形状

    本文介绍通过java程序在excel中操作形状(图形)的方法,包括: 1. 添加形状(如设置形状类型/位置/大小.形状颜色填充(单色/渐变色/纹理/图片填充).形状显示或隐藏.形状倾斜角度.添加文本到 ...

  4. hadoop_2.6.5集群安装

    安装hadoop2.6.5集群: 1.规划设计: JacK6:NameNode,jobtracker JacK7:secondnode,datenode,tasktracker JacK8:datan ...

  5. (笔记)常用Llinu命令(一)

    Linux资源 鸟哥Linux:http://linux.vbird.org/linux_basic/ Linux命令大全:https://man.linuxde.net/ 目录切换 cd usr: ...

  6. java获取本地IP地址集合包括虚拟机的ip

    public static ArrayList<String> getLocalIpAddr() { ArrayList<String> ipList = new ArrayL ...

  7. 用Java实现一个简单的DBMS(总结)

    时间:2020/1/16 写这个DBMS(说DBMS夸张了,应该是一个控制台程序)的起因是数据库实践老师布置的一个大作业,先贴上GitHub地址: https://github.com/machi12 ...

  8. HTML5的基础学习

    课前预习:HTML又被叫做超文本标记语言,它不是编程语言,是web中最微不足道的,但又是web中最微不足道的基石, 对零基础学习HTML的人员来说先认识HTML的标签和字体是必不可少的,万丈高楼平地起 ...

  9. 实验2: CDP命令操作

    基本命令 1.获设备的相邻信息:CDP CDP1.不管上层协议 能够获取的信息包括:1.设备名2.对应各协议的地址3.端口名4.角色特征5.平台 全局启用/关闭CDP:cdp run/no cdp r ...

  10. 物流跟踪API-快递单推送

    上一篇文章我们讲解了订阅服务功能.我们已经完成了如何把物流订单订阅到快递鸟,快递鸟也能接收到我们的订单信息,接下来就需要快递鸟实时的将最新的物流轨迹推送到我们服务器,我们既然要接收快递鸟的信息,就需要 ...