求知若饥,虚心若愚。
今天开始讲解JavaScript设计模式,作为以前学Java的我在设计模式上或多或少接触过,可能自己理解程度有限,望大家多多见谅。
我准备讲20种设计模式,分别有:
- 01.单例模式
- 02.工厂模式
- 03.桥接模式
- 04.装饰者模式
- 05.组合模式
- 06.外观模式
- 07.适配器模式
- 08.代理模式
- 09.观察者模式
- 10.享元模式
- 11.状态模式
- 12.命令模式
- 13.职责链模式
- 14.构造函数模式
- 15.建造者模式
- 16.策略模式
- 17.迭代器模式
- 18.中介者模式
- 19.模板方法模式
- 20.原型模式
尽管讲解的模式很多,但是也不需要一一去记。因为学设计模式的目的并不是为了记住它的模式叫什么名,而是记住每个模式的代码为什么这样写,这样写的好处是什么。
当自己以后在看js插件源码或项目代码时,你能看出整个项目的架构,方便自己理解,那么JavaScript设计模式对你来说就非常有用。
我会把每个模式按照平时使用程度进行星级划分,星级低的不代表不重要,只是说在编写一般代码可能用的不多,但在编写架构代码却很常见。
1 | var channelList = { |
总结:
特点及优势:单例模式就是保证一个类只有一个实例,其目的就是为了节约资源。
适用场合:用来划分命名空间。
划分命名空间的好处有以下两点:
1.可以减少网页中全局变量的数量(即window下面的变量)
2.可以在多人开发时避免代码的冲突
Ajax模块:
1 | var XMLHttpFactory={}; |
简单工厂模式:
1 | var Page={}; |
总结:
特点及优势:工厂模式无需使用new关键字指定具体类,而是在创建对象时才确定类。有助于创建模块化的代码,方便扩展。
适用场合:a.主要用在所实例化的类的类型不能在开发期间确定,而只能在运行期间才能确定的情况下。b.想创建一些包含成员对象的类但又不想把它们紧密耦合在一起。
封装的东西:
1 | function extend(parent,child){ |
桥接模式代码:
1 | function SoftWare(){ |
1 | function System(){ |
1 | Android.run(qq); |
总结:
特点及优势:桥接模式是将抽象与其实现分离开来,以便二者独立变化。促进代码的模块化,促成更简洁的实现并提高抽象的灵活性。
桥接模式的参与者包括:抽象类、具体类、实现者、具体实现者。
适用场合:把一组类和函数连接起来。
1 | function MacBook(){ |
总结:
特点及优势:装饰者模式用于包装同接口的对象,通过重载方法的形式添加新功能。
适用场合:在为对象添加新特性时,使用了大量子类或不想改变使用该对象的代码的话,使用装饰者模式。
先创建树干:
1 | var UL=function(id){ |
再创建树叶:
1 | var Li=function(text){ |
最后实现:
1 | document.body.innerHTML=""; |
总结:
特点及优势:组合模式把一批子对象组织成树形结构,只需一条命令就可以操作树中的所有对象。
适用场合:特别适合于动态的HTML用户界面。
1 | var addEvent=function(el,ev,fn){ |
总结:
特点及优势:外观模式是几乎所有JavaScript库(如JQuery、YUI、Prototype.js)的核心原则。外观模式可以将一些复杂操作封装起来,并创建一个简单的接口用于调用。
适用场合:a.封装一些兼容浏览器的接口。b.简化重复性代码。
1 | var param={name:'ww',age:2}; |
总结:
特点及优势:适配器模式是用一个新接口对现有的接口进行封装,好处在于无需对现有代码做大改动。
使用场合:现有接口,但其方法或属性不符合你的要求。
1 | function FangDong(){ |
总结:
特点及优势:代理模式控制对创建开销很大资源的对象的访问。
比如例子中讲到的中介如果没收到房东的委托就没有出租房,只有等有房东需要让中介帮忙,才能有房子,才能有钱赚,所有创建房东就需要时间。
适用场合:包装那些需要大量计算或较长时间才能实例化的类。
1 | var PubSub={}; |
下面是用JQuery的on/off功能实现:
1 | (function($){ |
总结:
特点及优势:DOM的事件监听器(addEventListener)就是一种内置的观察者。
观察者模式的执行过程:首先订阅特定的事件,然后等待事件的发生,当事件发生时,订阅方的回调函数会得到通知并执行。
因此观察者模式包括订阅、退订、发布方法。
适用场合:用于事件监听方面的优化。使用该模式可以削减事件注册监听的次数,让可观察对象借助一个事件监听器替你处理各种行为,从而降低内存消耗和提高互动性能。
1 | $('div').bind('click', function(){ |
总结:
特点及优势:享元模式可以大幅度减少需要实例化的类的数量,提升内存的性能。
如上面例子中的代码$(this)表示生成JQuery对象,意味着每次点击都会重新创建JQuery对象,这样就显得很不科学。
适用场合: 页面存在大量资源密集型对象,对浏览器的内存和CPU占用极大的网站。
1 | var StateManager=function(){ |
总结:
特点及优势:状态模式可以把散落在世界各地的条件分支集中管理到一个类里,并且可以很容易的添加一种新的状态。
适用场合:a.一个操作中含有庞大的条件分支语句。 b.一个对象的行为取决于它的状态。
1 | var $={ |
总结:
特点及优势:命令模式将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。简单说命令模式就是对相似方法的封装。
适用场合:a.代码封装。 b.代码重构。
1 | function Handler(successor){ |
总结:
特点及优势:JavaScript内部的事件冒泡和事件捕获用到了职责链模式。
适用场合:A对象请求B对象,B对象不处理请求C对象,C对象不处理清楚D对象。对事件处理程序过多的代码解决方式就使用职责链模式。
1 | function People(name,age){ |
总结:
特点及优势:构造函数用于创建特定类型的对象。
适用场合:创建新的类。
1 | $.ajax(function(){ |
总结:
特点及优势:建造者模式可以将一个复杂对象的构建与其表示相分离。建造者模式让你只用知道结果,不用知道创建的过程。
如上面代码中ajax的回调success里面的data,你不需要知道data的创建过程,你只需要使用即可;$里面只需要传入要生成的HTML字符,而不需要关心HTML对象是如何生产的。
适用场合:代码中需要分步骤构建一个复杂的对象。
1 | var Valid=function(res){ |
总结:
特点及优势:策略模式就是定义一系列的算法,把它们一个个封装起来,并且使它们可替换删减。
适用场合:a.封装算法。 b.封装几乎任何类型的规则。
1 | var $=(function(){ |
总结:
特点及优势:迭代器模式提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该方法中的内部表示。
适用场合:遍历集合。
1 | var mode1=Mode.create(),mode2=Mode.create(); |
总结:
特点及优势:控制层便是位于表现层与模型层之间的中介者。
中介者模式的功能就是封装对象之间的交互,降低了系统对象之间的耦合性,使得对象易于独立的被复用。
适用场合:一组定义良好的对象,现在要进行复杂的通信。
1 | var Life=function(){ |
总结:
特点及优势:模板方法模式预先定义一组算法,先把算法的不变部分抽象到父类,再将另外一些可变的步骤延迟到子类去实现。
模板方法是一种代码复用的基本技术,在类库中尤为重要,因为他们提取了类库中的公共行为。
适用场合:a.代码重构 b.代码架构
1 | function extend(child,parent){ |
总结:
特点及优势:原型模式是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用场合:a.实现继承 b.声明公用方法
经历一周多的总结与编写,20种设计模式终于讲解的差不多了。能看完到最后的人都是好样的,希望对你们能有所帮助。