一 什么是设计模式

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

二 设计原则

要学会设计模式,首先要了解设计模式所依托的设计原则:

(1)单一职责原则(SRP原则):一个对象(方法)只做一件事情。
运用的设计模式:代理模式,单例模式,装饰者模式等。

(2)最少知识原则(LKP原则):一个软件实体应当尽可能少地与其他实体发生相互作用。软件实体是一个广义的概念,不仅包括对象,还包括系统,类,模块,函数,变量等。
最少知识原则要求我们在设计程序时,应当尽量减少对象之间的交互,一个对象应尽可能少的了解其他对象。

运用的设计模式:中介者模式,外观模式等

(3)开闭原则(开放-封闭原则/OCP原则):软件实体(类,模块,函数)等应该是可以扩展的,但是不可修改。

运用的设计模式:发布-订阅模式,模板方法模式,策略模式,代理模式,职责链模式等。

(4)里氏转换原则:子类继承父类,单独掉完全可以

(5)依赖倒转原则:引用一个对象,如果它有底层对象,直接调用底层。

(6)合成/聚合复用原则:新的对象应尽可能使用一些已有的对象,使之成为新对象的一部分

(7) 接口隔离原则。不应该强迫客户依赖没有使用的接口。有个问题是,JS中没有显式的接口,不过我们有方法绕过。

SOLID设计原则请参考: http://www.infoq.com/cn/news/2014/01/solid-principles-javascript

三 常用设计模式

(1)单体(Singleton)模式(单例模式): 绝对是JavaScript中最基本最有用的模式。

单例概念:保证一个类只有一个实例

实现的方法:先判断实例存在与否,存在直接返回,不存在就创建了再返回,这确保一个类只有一个实例对象。

用途:
a.用来划分命名空间,从全局命名空间里提供一个唯一的访问点来访问该对象。
b.实现模块内部保护,模块之间通信
  
优点:可以减少网页中全局变量的数量(在网页中使用全局变量有风险);可以在多人开发时避免代码的冲突(使用合理的命名空间)等。

使用注意事项:

a.this的使用
b.闭包容易造成内存泄漏,不需要赶快处理掉
c.注意new的成本(继承)

实例:

<script>//top模块(与下面的banner模块是独立的命名空间,互不干扰(自己保护自己),相互可以通信)var top = {init: function () {//先绑定dom元素this.render();//再为dom元素绑定事件this.bind();},a: 4, //想传递的量//render 把所有的dom元素放在这里边render: function () {var me = this;me.btn_a = $('#a');},//bind 给元素绑定事件bind: function(){var me = this;me.btn_a.click(function(){//业务逻辑,定义在下边me.test();});},test: function(){a = 5;}};//banner模块var banner = {init: function () {//先绑定dom元素this.render();//再为dom元素绑定事件this.bind();},a: 4, //想传递的量//render 把所有的dom元素放在这里边render: function () {var me = this;me.btn_a = $('#a');},//bind 给元素绑定事件bind: function(){var me = this;me.btn_a.click(function(){//业务逻辑,定义在下边me.test();});},test: function(){//a = 6;top.a = 6;//直接调用模块 top. ... 实现和top的通信}};//初始化各模块top.init();banner.init();</script>

详细请参考:http://www.cnblogs.com/TomXu/archive/2012/02/20/2352817.html

(2)工厂模式

概念:定义一个用于创建对象的接口,该接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。

用途:

适用于:
a.对象的构建较复杂时的场景
b.需要依赖具体的环境创建不同实例。
c.处理大量具有相同属性的小对象。

注意事项:
a.不要滥用工厂模式,如果只是为了生产很好的几个对象,创建工厂只会增加代码复杂度。(会生产大量小对象才适合建工厂流水线)

优点:消除对象之间的耦合(何为耦合?就是相互影响)。通过使用工厂方法而不是new关键字及具体类,可以把所有实例化的代码都集中在一个位置,有助于创建模块化的代码

<script>//工厂是一个单体(单例模块)var myFactory = {};//不同的工厂流水线myFactory.product_shoes = function(){this.workers = 100;alert('生产鞋子');};myFactory.product_clothes = function(){this.workers = 500;alert('生产衣服');};//定义一个类,它的实例化延迟到了下面的子类里myFactory.manager = function(para){return new myFactory[para]();}//子类,进行实例化,决定生产哪种和哪样的东西var somebody = myFactory.manager('product_shoes');//alert(somebody.workers);</script>

另一个非常有名的一个示例 - XHR工厂:

var XMLHttpFactory =function(){};      //这是一个简单工厂模式XMLHttpFactory.createXMLHttp =function(){var XMLHttp = null;if (window.XMLHttpRequest){XMLHttp = new XMLHttpRequest()}elseif (window.ActiveXObject){XMLHttp = new ActiveXObject("Microsoft.XMLHTTP")}return XMLHttp;}//XMLHttpFactory.createXMLHttp()这个方法根据当前环境的具体情况返回一个XHR对象。var AjaxHander =function(){var XMLHttp = XMLHttpFactory.createXMLHttp();...}

工厂有简单工厂,抽象工厂之分:

var XMLHttpFactory =function(){};      //这是一个抽象工厂模式XMLHttpFactory.prototype = {//如果真的要调用这个方法会抛出一个错误,它不能被实例化,只能用来派生子类createFactory:function(){thrownew Error('This is an abstract class');}}//派生子类,文章开始处有基础介绍那有讲解继承的模式,不明白可以去参考原理var XHRHandler =function(){XMLHttpFactory.call(this);};XHRHandler.prototype =new XMLHttpFactory();XHRHandler.prototype.constructor = XHRHandler;//重新定义createFactory 方法XHRHandler.prototype.createFactory =function(){var XMLHttp =null;if (window.XMLHttpRequest){XMLHttp =new XMLHttpRequest()}elseif (window.ActiveXObject){XMLHttp =new ActiveXObject("Microsoft.XMLHTTP")}return XMLHttp;}

区别:
简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族

以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。

简单工厂优点:客户端可以免除直接创建产品对象的责任,而仅仅是“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。
工厂方法有点:允许系统在不修改具体工厂角色的情况下引进新产品。
抽象工厂优点:向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象

抽象工厂简单工厂等的更详细区别请见:http://zyjustin9.iteye.com/blog/2094960

(3)桥接模式

概念:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

用途:最常用在事件监控上。在实现API的时候,桥接模式非常有用。在所有模式中,这种模式最容易立即付诸实施。

优点:可以用来弱化它与使用它的类和对象之间的耦合,就是将抽象与其实现隔离开来,以便二者独立变化;这种模式对于JavaScript中常见的时间驱动的编程有很大益处。桥接模式让API更加健壮,提高组件的模块化程度,促成更简洁的实现,并提高抽象的灵活性。

//错误的方式//这个API根据事件监听器回调函数的工作机制,事件对象被作为参数传递给这个函数。本例中并没有使用这个参数,而只是从this对象获取ID。addEvent(element,'click',getBeerById);function(e){var id =this.id;asyncRequest('GET','beer.url?id='+ id,function(resp){//Callback responseconsole.log('Requested Beer: '+ resp.responseText);});}//好的方式//从逻辑上分析,把id传给getBeerById函数式合情理的,且回应结果总是通过一个回调函数返回。这么理解,我们现在做的是针对接口而不是实现进行编程,用桥梁模式把抽象隔离开来。function getBeerById(id,callback){asyncRequest('GET','beer.url?id='+ id,function(resp){callback(resp.responseText)});}addEvent(element,'click',getBeerByIdBridge);function getBeerByIdBridge(e){getBeerById(this.id,function(beer){console.log('Requested Beer: '+ beer);});}

(4)装饰者(Decorator)模式

目的:为对象增加功能(或方法)。

概念:动态地给一个对象添加一些额外的职责。就扩展功能而言,它比生成子类方式更为灵活。

装饰者模式和组合模式有很多共同点,它们都与所包装的对象实现统一的接口并且会把任何方法条用传递给这些对象。可是组合模式用于把众多子对象组织为一个整体,而装饰者模式用于在不修改现有对象或从派生子类的前提下为其添加方法。

装饰者的运作过程是透明的,这就是说你可以用它包装其他对象,然后继续按之前使用那么对象的方法来使用。

(5)组合(Composite)模式

概念:将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。

组合模式是一种专为创建Web上的动态用户界面而量身定制的模式。使用这种模式,可以用一条命令在多个对象上激发复杂的或递归的行为。组合模式擅长于对大批对象进行操作。

优点:1.程序员可以用同样的方法处理对象的集合与其中的特定子对象;2.它可以用来把一批子对象组织成树形结构,并且使整棵树都可被便利。

适用范围:1.存在一批组织成某处层次体系的对象(具体结构可能在开发期间无法知道);2.希望对这批对象或其中的一部分对象实话一个操作。

其实组合模式就是将一系列相似或相近的对象组合在一个大的对象,由这个大对象提供一些常用的接口来对这些小对象进行操作,代码可重用,对外操作简单。例如:对form内的元素,不考虑页面设计的情况下,一般就剩下input了,对于这些input都有name和value的属性,因此可以将这些input元素作为form对象的成员组合起来,form对象提供对外的接口,便可以实现一些简单的操作,比如设置某个input的value,添加/删除某个input等等。

(6)门面(facade)模式

概念:
门面模式是几乎所有JavaScript库的核心原则
子系统中的一组接口提供一个一致的界面,门面模式定义了一个高层接口,这个接口使得这一子系统更加容易使用,简单的说这是一种组织性的模式,它可以用来修改类和对象的接口,使其更便于使用。

作用:1.简化类的接口;2.消除类与使用它的客户代码之间的耦合。

比如计算机桌面上的那些快捷方式图标,它们就是在扮演一个把用户引导至某个地方的接口的角色,每次操作都是间接的执行一些幕后的命令。

四 扩展与深入

还有很多设计模式的详细介绍请参考tom大叔的深入理解javascript系列博客,哪里对很多设计模式都进行了很详细的讲解:
http://www.cnblogs.com/TomXu/category/338104.html

前端学习总结(十四)javascript设计模式相关推荐

  1. web前端学习第十四~十八天

    这五天学习了如何布置一个电商的平台,花了一些时间,前面在磋磨的怎么布局,后面顺手就快了点,但还是花了很多时间. 项目的注意事项: 项目准备好目录文件,样式与结构相分离. 产品的图片,项目的固定的图片, ...

  2. JavaScript学习(十四)—元素节点关系和特殊节点

    JavaScript学习(十四)-元素节点关系和特殊节点 一.元素节点 (1).parentElement: 获取某元素的父元素,它和parentNode的区别是parentElement获取到的值时 ...

  3. JavaScript高级程序设计第四版学习--第二十四章

    title: JavaScript高级程序设计第四版学习–第二十四章 date: 2021-5-31 10:46:01 author: Xilong88 tags: JavaScript 本章内容: ...

  4. akka学习教程(十四) akka分布式实战

    akka系列文章目录 akka学习教程(十四) akka分布式实战 akka学习教程(十三) akka分布式 akka学习教程(十二) Spring与Akka的集成 akka学习教程(十一) akka ...

  5. 华为鸿蒙系统HarmonyOS学习之十四:方舟编译器

    华为鸿蒙系统HarmonyOS学习之十四:方舟编译器 方舟编译器是华为自研的一个支持多种编程语言,多种芯片平台的联合编译编程平台,而经过方舟编译器编译适配后的APP,运行效率会大大提高,拥有更为流畅的 ...

  6. 前端的第二十四天(jQuery入门、常用API)

    前端的第二十四天(jQuery入门.常用API) 一.jQuery入门 1.jQuery 概述 2.jQuery 的基本使用 官网地址:点我跳转 各个版本的下载:点我跳转 二.jQuery常用API ...

  7. OpenCV学习(二十四 ):角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack()

    OpenCV学习(二十四 ):角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack() 参考博客: Harris角点检测原理详解 Harri ...

  8. 吴恩达《机器学习》学习笔记十四——应用机器学习的建议实现一个机器学习模型的改进

    吴恩达<机器学习>学习笔记十四--应用机器学习的建议实现一个机器学习模型的改进 一.任务介绍 二.代码实现 1.准备数据 2.代价函数 3.梯度计算 4.带有正则化的代价函数和梯度计算 5 ...

  9. python学习[第十四篇] 文件的输入与输出

    python学习[第十四篇] 文件的输入与输出 标准文件类型 一般来说只要程序一执行,就会访问3个文件: 标准输入(键盘) stdin 标准输出(显示器缓冲区) stdout 默认输出到屏幕 标准错误 ...

  10. 花书+吴恩达深度学习(十四)卷积神经网络 CNN 之经典案例(LetNet-5, AlexNet, VGG-16, ResNet, Inception Network)

    目录 0. 前言 1. LeNet-5 2. AlexNet 3. VGG-16 4. ResNet 残差网络 5. Inception Network 如果这篇文章对你有一点小小的帮助,请给个关注, ...

最新文章

  1. 枚举类型(C# 编程指南)
  2. 如何使用CDR智能填充工具
  3. java接口那一节是哪的知识_Java中的接口知识汇总
  4. Spring框架(二) ---- bean的歧义性
  5. 所选元素非联通_非固化橡胶沥青防水涂料与耐根穿刺防水卷材(沥青基)施工要点...
  6. 为什么微服务化、数据仓库都不是中台?
  7. TPYBoard开发板带你轻松玩转MicroPython
  8. SSH农产品销售系统设计与实现答辩PPT免费下载
  9. dnsmasq-2.48没有ipset特性,安装dnsmasq-2.71来支持ipset
  10. 阳光长跑(阳光体育服务平台)
  11. selenium浏览器驱动下载地址
  12. No provider available from registry 192.168.126.129:2181 for service com.jt.service.DubboUserServic
  13. “恶意版”俄罗斯方块游戏火了
  14. Win11机械硬盘磁盘碎片整理方法
  15. 校招(含实习生春招)指南
  16. 0pyqt获取textEdit控件的文本
  17. 什么是API,开发人员该如何使用它们?
  18. java会导致蓝屏么_原来有这么多原因会导致电脑蓝屏啊
  19. 2018年全国多校算法寒假训练赛
  20. 计算机学院青年教师讲课,计算机学院第六届青年教师讲课比赛成功举行

热门文章

  1. linux ffmpeg自动推流,ffmpeg推流下载
  2. java web 的bin哪去了? 头脑风暴
  3. 随机生成图片API大全
  4. NOJ 1042 电子老鼠闯迷宫
  5. 10个前端开发常用的速查网站
  6. 培训完软件测试后,真的可以找到工作吗?
  7. C3P0连接池jar包下载
  8. C++extern用法
  9. 深入理解深度学习——Transformer:解码器(Decoder)部分
  10. DuiVision开发教程(3)-XML资源文件定义介绍