JavaScript设计模式

一、 设计模式

一个模式就是一个可重用的方案;

有效的解决方法易重用善于表达该解决方案;

未通过“模式特性”测试的模式称为模式原型

三规则:适用性有用性可用性

三个分类:

创建型设计模式

构造器模式(Constructor)、工厂模式(Factory)、抽象工厂模式(Abstract)、

原型模式(Prototype)、单例模式(Singleton)、建造者模式(Builder)

结构设计模式

装饰模式、外观模式、适配器模式、代理模式

行为设计模式

迭代模式、中介者模式、观察者模式、访问者模式

二、 JavaScript设计模式

构造器模式

function Car(model, year, miles) {

this.model = model;

this.year = year;

this.miles = miles;

}

Car.prototype.toString = function() {

return this.model + “ has done ” + this.miles + “ miles”;

}

var sampleCar = new Car(“Honda”, 2009, 20000);

模块化模式

在一个单一对象中包含共有/私有的方法和变量,全局范围中屏蔽特定部分,减少与其他脚本区域定义的函数名称冲突。

私有信息:闭包实现 → 函数域模拟公有和私有概念

var myNamespace = (function() {

var counter = 0;

return {

increamentCounter: function() {

return counter++;

},

resetCounter: function () {

counter = 0;

}

}

} ) ();

myNamespace.incrementCounter();

myNamespace.resetCounter();

缺点:当想要改变某些成员可见性时,需要在所有使用该成员地方修改代码

暴露式模块模式

var myRevealingModule = function() {

var privateCounter = 0;

function privateFunction() {

privateCounter++;

}

function publicFunction() {

publicIncrement();

}

function publicIncrement() {

privateFunction();

}

function publicGetCount() {

return privateCounter;

}

return {

start: publicFunction,

increment: publicIncrement,

count: publicGetcount

};

} ();

myRevealingModule.start();

单例模式

一个类只有一个实例化对象;

实现方式:创建一个类,这个类包含一个方法。在没有对象存在时,该方法创建一个新的实例对象;对象存在时,返回该对象的引用;

每个类只有一个实例,该实例必须通过一个接口,才允许访问;

子类如果要扩展这个唯一实例,可不用修改代码就能使用扩展后的实例;

var mySingleton = (function() {

var instance;

function init() {

function privateMethod() {

console.log(“ I am private”);

}

var privateVariable = “I am also private”;

var privateRandomNumber = Math.random();

return {

publicMethod: function() {

console.log(“ The public can see me !”);

},

publicProperty: “I am also public”,

getRandomNumber: function() {

return privateRandomNumber;

}

};

};

return {

getInstance: function() {

if( ! instance) {

instance = init();

}

return instance;

}

};

}) ();

观察者模式

被观察者:提供用于增加和删除观察者的方法

观察者:提供一个接口,当被观察者状态变化时,得到通知

 

被观察者:

fuction ObserverList() {

this.observerList = [];

}

ObserverList.prototype.Add = function(obj) {

return this.observerList.push(obj);

}

ObserverList.prototype.Empty = function() {

this.observerList = [];

}

ObserverList.prototype.Count = function() {

return this.observerList.length;

}

ObserverList.prototype.Get = function(index) {

if( index > -1 && index < this.observerList.length) {

return this.observerList[index];

}

}

ObserverList.prototype.Insert = function(obj, index) {

var pointer = -1;

if(index === 0) {

this.observerList.unshift(obj);

pointer = index;

} else if(index === this.observerList.length) {

this.observerList.push(obj);

pointer = index;

}

return pointer;

}

ObserverList.prototype.IndexOf = function(obj, startIndex) {

var i = startIndex,

pointer = -1 ;

while(i < this.observerList.length) {

if(obj == observerList[i]) {

pointer = i;

break;

}

i++

}

return pointer;

}

ObserverList.prototype.RemoveAt = function(index) {

if(index ===0) {

this.observeList.shift();

} else if( index === this.observerList.length - 1) {

this.observerList.pop();

}

}

function extend(extension, obj) {

for(var key in extension) {

obj[key] = extension[key];

}

}

观察者:

function Subject() {

this.observes = new ObserverList();

}

Subject.prototype.AddObserver = fuction(observer) {

this.observers.Add(observer);

}

Subject.prototype.RemoveObserver = function(observer) {

this.observers.RemoveAt(this.observers.IndexOf(observer,0));

}

Subject.prototype.Notify = function(context) {

var observerCount = this.observers.Count();

for(var i = 0; i < observerCount; i++) {

this.observers.Get(i).Update(context);

}

}

function Observer() {

this.Update = function() {

……

};

}

中介者模式

……

 

原型模式

ver vehicle = {

getModel: function() {

console.log(“ The model of this vehicle is ..” + this.model);

}

};

ver car = Object.create(vehicle, {

“id”: {

value: MY_GLOBAL.nextId(),

enumerable: true

},

“model”: {

value: “Ford”,

enumerable: true

}

});

-------------------------------------------------------------------------------------------

var verclePrototype = {

init: function(carModel) {

this.model = carModel;

},

getModel: function() {

console.log(“ The model of this vehicle is ..” + this.model);

}

};

function vehicle(model) {

function F() {};

F.prototype = verclePrototype;

var f = new F();

f.init(model);

return f;

}

命令模式

将方法的调用,请求或者操作封装到一个单独对象中。

var CarManager = {

requestInfo: function(model, id) {

return “ The information for ” + model + “ with ID ” + id + “ is foobar”;

},

buyVehicle: function(model, id) {

},

arrangeViewing: function(model, id) {

}

};

CarManager.execute = function(name) {

return CarManager[name] && CarManager[name].apply( CarManager,

[].slice.call(arguments, 1)

);

};

CarManager.execute( "arrangeViewing", "Ferrari", "14523" );

CarManager.execute( "requestInfo", "Ford Mondeo", "54323" );

CarManager.execute( "requestInfo", "Ford Escort", "34232" );

CarManager.execute( "buyVehicle", "Ford Escort", "34232" );

外观模式

jQuery的$(document).ready(..),内部方法驱动bindReady()

bindReady: function() {

if(document.addEventListener) {

document.addEventLister(“DOMContentLoaded”,

DOMContentLoaded, false);

window.addEventListener(“load”, jQuery.ready, false);

} else if(document.attachEvent) {

document.attachEvent(“onreadystatechange”, DOMContentLoaded);

window.attachEvent(“onload”, jQuery.ready);

}

}

工厂模式

function Car(options) {

this.doors = options.doors|| 4;

this.state = options.state || “brand new”;

this.color = options.color || “silver”;

}

function Truck(options) {

this.state = options.state || “used”;

this.wheelSize = options.wheelSize || “large”;

this.color = options.color || “blue”;

}

function VehicleFactory() {

VehicleFactory.prototype.vehicleClass = Car;

VehicleFactory.prototype.createVehicle = function(options) {

if(options.vehicleType == “car”) {

this.vehicleClass = Car;

} else {

this.vehicleClass = Truck;

}

return new this.vehicleClass(options);

}

};

var carFactory = new VehicleFactory();

var car = carFactory.createVehicle({

vehicleType: “car”,

color: “yellow”,

doors: 6

});

应用场景:

l  当我们的对象或者组件设置涉及到高程度级别的复杂度时

l  当我们需要根据我们所在的环境方便的生成不同对象的实体时

l  当我们在许多共享同一个属性的许多小型对象或组件上工作时

l  当带有其它仅仅需要满足一种API约定的对象的组合对象工作时

Mixin模式

var Mixin = function() {};

Mixin.prototype = {

driveForward: function() {},

driveBackward: function() {},

driveSideways: function() {}

}

function augment(receivingClass, givingClass) {

if(argument[2]) {

for(var i =2, len= argument.length; i < len; i++) {

receivingClass.prototype[argument[i]]=givingClass.prototype[argument[i]];

}

} else {

for(var methodName in givingClass) {

if(!Object.hasOwnProperty(receivingClass.prototype, methodName)) {

receivingClass.prototype[methodName]= givingClass.prototype[methodName];

}

}

}

}

augment( Car, Mixin, "driveForward", "driveBackward" );

var myCar = new Car({

model: "Ford Escort",

color: "blue"

});

装饰模式

旨在提升重用性能的一种结构性设计模式;

典型的装饰器提供了向一个系统中现有的类动态添加行为的能力;

亨元模式

数据层:基于存储在内存中的大量相同对象的数据共享;

DOM层:享元模式作为事件管理中心,以避免将事件处理程序关联到我们需要相同行为父容器的所有子节点上。

三、 JavaScript MV*模式

  1. MVC模式

Models:一个业务应用的数据模型。

Views:视图是模型的可视化表现。

Controllers:控制器是模型和视图之间的中介。

当模型被改变时,它会通知观察者(视图)一些东西已经被更新了,这是MVC中最重要的关系。

  1. MVP模式

P:展示器

  1. MVVM模式

四、 模块化JavaScript设计模式

  1. AMD

异步模块定义(Asynchronous Module Definition)

异步方式加载模块,模块的加载不影响它后面语句的运行。

var math = require(‘math’);

math.add(2, 3);

浏览器端,因为模块都放在服务器端吗,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于假死状态。

因此,浏览器端的模块,不能采用同步加载,只能采用异步加载。

require([modele], callback);

require([‘math’], function(math) {

math.add(2, 3);

});

math.add()与math模块加载不是同步的;

JavaScript设计模式 -- 读书笔记的更多相关文章

  1. JavaScript设计模式:读书笔记(未完)

    该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...

  2. JavaScript设计模式读书笔记之一:接口

    接口 在JavaScrip中模仿接口 用注释描述接口 用属性检查模仿接口 用鸭式辨型模仿接口 依赖于接口的设计模式 工厂模式 组合模式 装饰者模式 命令模式 接口 在JavaScrip中模仿接口 用注 ...

  3. 《你不知道的javascript》读书笔记2

    概述 放假读完了<你不知道的javascript>上篇,学到了很多东西,记录下来,供以后开发时参考,相信对其他人也有用. 这篇笔记是这本书的下半部分,上半部分请见<你不知道的java ...

  4. HeadFirst设计模式读书笔记--目录

    HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...

  5. 《编写可维护的javascript》读书笔记(中)——编程实践

    上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...

  6. Javascript & JQuery读书笔记

    Hi All, 分享一下我学JS & JQuery的读书笔记: JS的3个不足:复杂的文档对象模型(DOM),不一致的浏览器的实现和便捷的开发,调试工具的缺乏. Jquery的选择器 a. 基 ...

  7. JavaScript设计模式系列学习笔记目录

    说明 本系列笔记参考书籍<JavaScript设计模式>.<JavaScript高级程序设计3> 参考博客:汤姆大叔博客:http://www.cnblogs.com/TomX ...

  8. JavaScript设计模式学习笔记

    1 JavaScript设计模式深入分析 私有属性和方法:函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量. 特权属性和方法:创建属 ...

  9. Head First 设计模式读书笔记(1)-策略模式

    一.策略模式的定义 策略模式定义了算法族,分别封装起来,让它们之间可以互换替换,此模式让算法的变化独立使用算法的客户. 二.使用策略模式的一个例子 2.1引出问题 某公司做了一套模拟鸭子的游戏:该游戏 ...

随机推荐

  1. 一天一个Java基础——通过异常处理错误

    <Thinking in Java>上对这章的讲解不少,可见重要性,学习和总结一些主要的记录下来. 一.创建自定义异常 package Exception; class SimpleExc ...

  2. HBase 系统架构

    HBase是Apache Hadoop的数据库,能够对大型数据提供随机.实时的读写访问.HBase的目标是存储并处理大型的数据.HBase是一个开源的,分布式的,多版本的,面向列的存储模型.它存储的是 ...

  3. Android 高仿豌豆荚 一键安装app 功能 实现

    以往我们那些应用市场 帮我们安装app的时候  我们都得点确定,当然你如果 root 以后 不用点确定 也能自动安装了,后来豌豆荚 推出了一个功能 非root的手机也能不点确定 直接帮你安装好.(如果 ...

  4. unity, surface shader access world position and localposition

    一,surface shader中访问worldposition 在surface shader中访问世界坐标,只需在Input结构体中声明float3 worldPos即可,如下:  struct  ...

  5. Optional优雅的使用null

    在我们学习和使用Guava的Optional之前,我们需要来了解一下Java中null.因为,只有我们深入的了解了null的相关知识,我们才能更加深入体会领悟到Guava的Optional设计和使用上 ...

  6. C++ STL算法系列5---equal() , mismatch()

    equal和mismatch算法的功能是比较容器中的两个区间内的元素.这两个算法各有3个参数first1,last1和first2.如果对 于区间[first1,last1)内所有的first1+i, ...

  7. redhat 下Redis安装

    Redis 官网:http://redis.io/  下载地址: http://redis.io/download 安装方法:   cd opt wget http://download.redis. ...

  8. XML序列化成对象

    这个是和ALM上传测试结果结合使用的//把xml序列化成对象以及把对象序列化成xml using System; using System.Data; using System.Configurati ...

  9. <转>如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    原文链接:http://www.vaikan.com/use-multiple-cpu-cores-with-your-linux-commands/ 你是否曾经有过要计算一个非常大的数据(几百GB) ...

  10. python程序中自启动appium服务

    普通启动Appium服务方法:      打开cmd,运行命令: #>appium -a 127.0.0.1 -p 4723 当程序输出如上图信息的时候,表示appium启动成功,此时便可以运行 ...