Javascript 部分设计模式的个人理解

9 单例模式(确保自己使用的资源都是全局的)

1)普通单体(字面量初始化对象)

var person = {
name : ‘zhangsan‘,
age : 12,
getAge : function(){
return this.age ;
}
}
person.height = 185 ;

这种单体在实际开发中常用在两个地方,其一就是 匿名对象,其二就是 划分命名空间!

2 )具有局部变量的单体(动态加载数据,初始化属性,返回一个对象实例)

 var UserInfo = (function(){           //同闭包的原
  var name = "";         //利用闭包是单体有自己的私有局部变量
  var code = "";
  Ajax.request("url",function(n,c){
   name = n;
   code = c;
  })
  return {
   name:name,
   code:code
  }
 })()

3)惰性单体(用一个私有变量代替第二种方法返回的实例)

var UserInfo = (function(){
  var userInfo = "";      //私有变量
  function init(){        //利用闭包是单体有自己的私有局部变量 
   var name = "";
   var code = "";
   Ajax.request("url",function(n,c){ 
    name = n;
    code = c;
   })
   return {
    name:name,
    code:code
 } 
  }
  return {
   getInstance : function(){
    if(userInfo){
     return userInfo;
    }else{
     userInfo = init();
     return userInfo;
    }
   }
  }
 })()

4 ) 分支单体(这种方法就是通过判断返回一个什么样的实例,也就是分支,是上面方法的结合使用)

10 工厂模式

1)简单工厂(简单的说就是一个接口以及他的多个实现类,通过一个单例工厂类来根据客户的需求new 出对应接口实现类的对象,这种方式其实就是类似于java里面的静态工厂模式,没有多大意义。原因就是没有动态效果,如果新增一个实现类又要改变if语句,又要修改工厂类的源码,没意义!)

2)工厂模式(他与工厂模式的区别就在于它是给人误解为动态的,他的整个个原理是这样的:在简单工厂模式的基础下,把工厂类定义为抽象类,那么具体工厂类的实现类就是我们通过使用if语句来判断new出什么对象的一个类,那么它会根据不同的情况有各种各样的工厂实现类,那么接口有新的实现类时没必要改变所有的工厂实现类,只需改变其中需要的那个就可以了,所以这也不是动态的)

11 桥梁模式

1)目的:将抽象类与其实现类隔离开来,以便二者独立开来,互不干扰的开发!

2)思想:比如我们任意写一个了服务类,很多客户端都要调用这个类的服务,那么我就可以在客户端与服务类之间新建一个桥梁,用来处理二者的相互调用,这样就能把二者分离开来!当然这个确实有点类似于门面模式或适配器模式,然而意义是不一样的。

A 对于适配器模式来说:他的目的是在服务类并不能直接被客户端所用(不兼容)的情况下,要在中间设置一个适配器来改造服务类的调用,但又不修改服务类本身。

B 对于桥梁模式来说:他的目的是在客户端调用服务类时,用一个桥梁把二者隔离开来,从而达到二者互不干扰的目的。而且桥梁模式还有一个很重要的作用就是在桥梁中能够处理多个不同服务类的之间的相互调用!

C 对于门面模式来说:他的目的是为服务类创建一个中间便利类,把复杂接口改造成一个简单易用的接口,他与以上两种设计模式的差异就在于门面模式并不是强调服务类被某个或某些特定的客户端容易调用,而是为服务类编写一个容易被调用的接口门面类。所以,对于浏览器不兼容的服务类我们就应该使用门面模式来封装,比如事件注册,XMLHttpRequest封装

12 门面模式

1)作用:简化类的接口,同时消除服务类与使用它的客户端之间的耦合,还能够完成与与桥接模式类似的功能就是多个类的相互调用在门面类中。

2)思想:比如我们写了一个服务类,他的接口很复杂,然而我们就可以为这个服务类创建一个门面类,这个门面类的目的就是为了简化服务类接口的调用。这里完全没有牵连到客户端的东西,原因就是门面模式是为服务类服务的,适配器模式是为了服务类与客户端兼容的,桥梁模式是为了服务类与客户类分离的。

3)所谓的一些封装或者脚本库如Jquery等都是采用门面模式的原理。

13 适配器模式

1)概念:适配器模式可用来在现有接口和不兼容的类之间进行适配,其实也就是包装模式,因为是在用一个新的接口包装成另一个对象,许多情况下,许多服务类接口并不能直接被客户端所使用,这时我们借助于适配器模式,你不用直接修改这些服务类,而是借助一个适配器来改造他的接口,从而达到客户端的可调用性。

2)适配器模式很想买门面模式,他们都要对别的对象进行包装并改变其呈现的接口,二者的差异在于:他们是如何改变接口的,门面模式展现的是一个简化的接口,他并不提供额外的选择,而且有时为了方便完成常见的任务他还会做出一些假设。适配器则要把一个接口转换为另一个接口,他并不会滤除某些能力,也不会简化接口,如果客户系统期待的API不可用,那就需要用到适配器。

14 组合模式

1)一种专为创建Web上的动态用户界面而量身定制模式,使用这种模式,可以用一条命令在多个对象上激发复杂的或递归的行为。

2)思想:就是类似于文件夹,一个组合类中有组合类同时还会有叶子类,这种模式我个人觉得用在的场合和特殊,只能是这种包含于被包含而且是在叶子节点和组合节点有相同特征的情况下使用。所以我们的组合类和叶子类都必须实现相同的接口,而且组合类中应该保存叶子类的引用和组合类的引用。

15 装饰模式

1)概念:可用来透明的把对象包装在具有同样接口的另一对象之中,通过在另一个对象中添加对应的实现功能完成原始对象的装饰。目的就是减少子类。

2)思想:对于一个服务类,需要在这个服务类的某个接口上新增一些功能,而且服务类是不能修改的,那么我们可能会选择新建一个子类来重写这个方法,这样当然可以实现,但是如果对每添加一个功能都要创建一个新类的话,会产生大量的子类,所以就有装饰模式,装饰类与服务类实现同一个接口,而且装饰类里面具有服务类的引用,所谓装饰就是在装饰类重写方法的时候调用了服务类的同名方法,于此同时还添加了自己的功能。

3)对比:代理模式也是在为服务类的某个接口改变一些功能,注意是改变不一定就是新增功能,所以这就是代理模式的本质区别,装饰模式是说在调用服务类的方法同时能够新增一些功能,那么在装饰模式中服务类的接口是一定会被调用的,然而代理模式则不是,使不使用服务类的接口那是代理类本身来决定的。但是代理模式和装饰模式的实现几乎相同,因为代理模式也是这样实现的,代理类与被代理类都实现了相同的接口,同时代理类中有被代理类的引用。

4)对比:装饰模式和组合模式之间有许多共同点,装饰者对象和组合对象都是用来包装别的对象,他们都与所包装的对象实现同样的接口并且会把任何方法调用传递给这些对象。组合模式是一种结构模式,用于把众多子对象组织为一个整体,当程序员与大批对象打交道时可以将他们当做一个对象来对待,并将他们组织为层次性的树。通常他们并不修改方法调用,而只是将其沿组合对象与子对象的链向下传递,直到到达被落实在叶对象上。装饰模式也是一种结构模式,他并非用于组织对象,而是用于在不修改现有对象或从其派生子类的前提下为其增添职责,创建装饰者的目的就在于对方法进行修改。

5)扩展:如果你觉得装饰模式就只是改变方法那点功能的话,那你就太肤浅了,原因是我们还可以在装饰类中新增一些接口之外的方法,那么这些方法就是新增的功能,这个就是java中IO使用的装饰模式。

16 代理模式

1)概念:代理模式最基本的形式是对访问进行控制,代理对象和被代理对象实现同一个接口,客户端只与代理对象打交道,调用的是代理对象的接口,然而实际上工作的是被代理对象(本体)工作,本体才是负责执行所分派的任务那个对象。代理对象所做的不外乎控制本体的访问,注意:代理对象并不会在另一个对象的基础上添加方法或修改其方法(这是与装饰模式的区别),也不会简化那个对象的接口(这是与门面模式的区别)。代理对象与本体实现同一个接口,客户端对代理的调用都会被传到本体对应的接口中。

2)分类:虚拟代理,远程代理,保护代理

A 虚拟代理:代理模式一开始是把本体实例化放在代理对象实例化的同时实例的(代理类的构造函数中实例化本体对象),如果使用虚拟代理的话就是在实现接口的所有方法中做一个判断,如果本体对象为空的就实例。也就是说吧本体实例化的过程放在了等需要调用到本体时才实例化。

B 远程代理:用户访问另一个环境中的对象,javascript中很少使用或实现。

C 保护代理:根据用户身份来控制代理对本体的访问,这个在javascript中很难做到,一般是在java中实现。

3)对比:

17 亨元模式

1)概念:亨元模式用于减少应用程序所需要对象的数量,这是通过将对象的内部状态划分为内在数据和外在数据两类实现的。内在数据是指类的内部方法所需要的信息,没有这种数据的话类就不能正常运作,换句话说内部数据就是这个类必须拥有的属性,所以所有的对象基本上都拥有这些属性,而且属性的值也都是固定的那么一些值,从而我们可以把这些值分别创建对象用来外部共享,也就是享元对象。外在数据则是可以从类身上剥离并存储在其外部的信息,换句话说外部信息其实是这个对象并不是很紧密的一些属性,但同时却是这个对象独一无二用以区别其他对象的属性。

2)思想:将内在状态相同的所有对象替换为同一个共享对象,外在状态的属性是不可能相同的,所以就是用以区分对象的,因此外在状态必须作为某些信息被封装。因为内在状态对象被共享所以使用工厂模式来控制对象的生成。形象的例子就是:一盘围棋的所有棋子:把棋子的颜色作为内在属性,所以只可能有两个对象黑和白,然后把对象的位置作为外部属性,那就是唯一的,可以用参数保存也可以从新定义对象。

3)作用:就是减少对象,其实很复杂。

4)总结:在java中有一个抽象的亨元角色(定义了共享对象的所有接口),有多个具体的亨元角色(实现抽象亨元角色,同时定义自己的方法),有一个工厂类(根据外部判断内存中是否已经实例化过具体共享的亨元角色对象,如果有就不实例化直接返回,否则实例化在返回)。

18 命令模式

1)概念:一般情况下,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”,也就是发送命令和执行命令都是封装在一处完成。但在某些场合,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,同时将一组实现也抽象为对象,达到实现二者之间的松耦合关系。

2)思想:首先我们要定义一个抽象接口,他就是抽象命令角色,它定义了命令的基本操作,其次就是具体命令角色,我们把具体的命令抽象为一个类,这个类通过实现接口中的方法来完成命令的处理,说道命令的处理自然不是具体命令类所要做的事情,那么命令类中应该有处理命令对象的引用,那个对象就是接收者,接收者应该也要实现抽象命令角色,这样就类似于代理模式的调用。那么命令的生成又是谁来呢,那就是客户端,客户端发送一个命令(初始化一个命令对象),然后调用发送给Invoker(命令调用)对象,自然客户端要把所创建的命令对象一同给命令调用者,那么命令调用者拥有命令对象的引用,在内部调用命令对象的方法,从而就执行了整个命令的完成。

3)流程:客户端 -----》发出命令(初始化命令对象)----》传递给Invoker------》Invoker调用命令-------》命令调用行为实现者----》处理。

4)个人理解:这个不就是一个代理模式吗,只是相对代理而言,命令角色有种层层传递到最底层的感觉罢了。

19 观察者模式

1)概念:一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。此种模式通常被用来实现事件处理系统。

2)思想:首先我们定义一个观察者接口,声明观察者共有的方法。然后我们就可以编写具体观察者角色实现抽象接口。这边就是被观察者,他也是一个抽象接口,声明诸多与观察者相关的方法,比如撤销观察者,注册观察者等,然后同样编写具体的被观察者实现抽象接口,最重要的是被观察者中有一个抽象观察者的集合引用,用来存放已经注册的观察者,一旦有事情通知观察者就只需遍历集合然后调用观察者对象的方法处理。

3)javascript中的例子就是事件处理器(一个被观察者只有一个观察者)与事件监听器(一个被观察者可以拥有多个观察者),他们都是观察者模式。

20 责任链模式

1)概念:用来消除请求的发送者和接收者之间的耦合,这是通过实现一个由隐式的请求进行处理的对象组成的链而做到的。链中每个对象可以处理请求,也可以将其传给下一个对象

2)思想:一个简单的客户类就是请求的发送者,发送者的任务就是创建命令或说发出请求;其次就是接收者或者说是一个命令的处理者(链子),他就是核心,那么我们首先声明一个抽象接口,定义链子的共有的方法,然后所有的链子实现这个接口中的方法,并且每个链子都有一个该接口类型的引用,用来存放下一个链子的对象。那么命令处理就是这样的,客户端创建了一个命令,然后发送出这个命令,之后就是由链子处理,如果开头的链子能够处理那么我就返回结果给客户端,如果不能处理命令那就把命令继续传递给下一个链子,让下一个处理,直到处理完成。

3)对比:命令模式其实也是这样的一个流程,唯一二者的差异就在于处理,命令模式一直是把命令发送给最底层的来处理,然而责任链则不是,他是只要有一个链子能够处理命令就可以不用执行下面的流程了。

4)例子:javascript 中的冒泡模型就是这个原理,还有一个很突出的就是拦截器,tomcat中设置的拦截器filter就是这个原理,使用chain.doFilter();执行下一个拦截器,否则直接热return。

时间: 2024-10-07 11:39:34

Javascript 部分设计模式的个人理解的相关文章

JavaScript中的伪数组理解

看过jQuery源码的人都知道类数组对象,与我们熟知的arguments对象很像 构造一个类数组必须有两个条件 第一个条件:你必须给对象定义个splice方法,只要他是一个function就可以 第二个条件:就是赋值一个length属性,或者增加push,unshift,shift,pop其中任何一个方法,并且调用了一次. 当这两个条件同时满足那么当前的对象在控制台输出后跟数组的格式一模一样. 一般而言大部分都是这样构造一个类数组对象(jQuery就是这么干的).因为相比而言,这样更简洁,并且更

对Javascript中原型的深入理解

  理解原型对象 在Javascript中无论什么时候,只要创建一个新的函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象(这个对象的用途是包含可以有特定类型的所有实例共享的属性和方法).如果按照字面上的意思来理解,那么原型属性就是通过调用构造函数而创建的那个对象的实例的原型对象. 在默认的情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针.如下图 function P

JavaScript 应用开发 #1:理解模型与集合

在 < Backbone 应用实例 > 这个课程里面,我们会一起用 JavaScript 做一个小应用,它可以管理任务列表,应用可以创建新任务,编辑还有删除任务等等.这个实例非常好的演示了使用 JavaScript 来开发富应用,它也能让你对 JavaScript 有一个更好的理解.所以,我们接下来会分成几天,把这个小应用的功能,分成几个部分,介绍每个小功能的细节.跟着这篇文章,或者 < Backbone 应用实例 > 这个课程,动手练习一下.效果会非常好. 在文章里面,我会把需要

《iOS「通告机制」及由其引出的对「架构模式」、「设计模式」的理解

说明:为了区别「本地通知」与「推送通知」这两种iOS中提醒用户,可见的「通知」,本文所将Notification翻译为「通告」.它们的详细区别,可参考<iOS开发系列--通知与消息机制>一文. 实践遇到的问题: 最近在维护公司的一个项目中,遇到这样一个报错:-[GlobalManager addAlbum:]: unrecognized selector sent to instance 经排查,原因如下:以前同事在利用「通告机制」在GlobalManager类中把「自己/self」注册为「观

JavaScript事件设计模式

本文章参考自:<征服Ajax Web 2.0 开发技术详解>为了自己日后查阅并与大家共享. 1. 事件设计概述 事件机制可以是程序逻辑更加清晰可见,在JavaScript中很多对象都有自己的事件,如:button有onclick事件,selcet有onchange事件.对于我们自己设计的类,是否也可以有事件机制呢?答案是肯定的.我们可以通过事件机制,将类设计为独立的模块,从而使其可以通过事件与外通信,提高程序的开发效率. 2. 不带参数的事件设计模式 最简单的一种模式是将一个类的方法成员定义为

深入理解javascript之设计模式

设计模式 设计模式是命名.抽象和识别对可重用的面向对象设计有用的的通用设计结构.设计模式确定类和他们的实体.他们的角色和协作.还有他们的责任分配. 每一个设计模式都聚焦于一个面向对象的设计难题或问题.它描述了在其它设计的约束下它能否使用,使用它后的后果和得失.因为我们必须最终实现我们的设计模式,所以每个设计模式都提供了例子,代码来对实现进行阐释. 虽然设计模式被描述为面向对象的设计,它们基于那些已经被主流面向对象语言实现过的解决方案...". 种类 设计模式可以被分成几个不同的种类.在这个部分我

JavaScript设计模式的简单理解

设计模式可以理解为一系列的代码框架,我觉得主要涉及封装的概念.把实现某一功能的代码段封装在函数中,可以方便调用,同时利于代码的复用,提高了代码的可维护性.下面简单介绍一下几种设计模式的个人感受. 1.单例模式 类似于一个类只有一个对象实例. 假设一个物品只能归属于一个人所有.. 2.构造函数模式 类似于c中的构造函数,可以创建特定类型的对象,然后对象里可以声明不同的变量及成员函数,还可以有不同的参数.就像我想做个凳子,我可以做成普通的凳子,有长宽高之类的属性及可以做的功能函数,此外我也可以做成高

Javascript事件设计模式(七)

一:事件设计概述 事件机制可以使程序逻辑更加符合现实世界,在JavaScript中很多对象都有自己的事件,例如按钮就有onclick事件,下拉列表框就有 onchange事件,通过这些事件可以方便编程.那么对于自己定义的类,是否也可以实现事件机制呢?是的,通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率. 二: 最简单的事件设计模式 最简单的一种模式是将一个类的方法成员定义为事件,这不需要任何特殊的语法,通常是一个空方法,例如:function class1(){ 

Javascript学习------设计模式(1)

由于初次看<javascript设计模式>,有太多的疑问: 1.接口:提供必需实现的方法的类,但本类不需要具体实现(C#搬过来的) 1 ///1:注释方实现接口 2 var compositeform = function () {//继承接口 3 4 } 5 compositeform.prototype.add = function () {//实现接口中的添加方法 6 7 } 8 compositeform.prototype.delete = function () {//实现接口中的