引用:(23条消息) 《Javascript设计模式与开发实践》关于设计模式典型代码的整理(下):模板方法模式、享元模式、职责链模式、中介者模式、装饰模式、状态模式、适配器模式_QQsilhonette的博客-CSDN博客

8、模板方法模式:一种基于继承的设计模式。

// 模板方法模式
var Beverage = function (param) {

var boilWater = function () {
console.log('把水煮沸');
};

var brew = param.brew || function () {
throw new Error('必须传递brew方法');
};

var pourInCup = param.pourInCup || function () {
throw new Error( '必须传递 pourInCup 方法' );
};
var addCondiments = param.addCondiments || function () {
throw new Error( '必须传递 addCondiments 方法' );
};

var F = function(){};
F.prototype.init = function(){ boilWater();
brew();
pourInCup();
addCondiments();
};
return F;
};

var Coffee = Beverage({ brew: function(){
console.log( '用沸水冲泡咖啡' ); },
pourInCup: function(){
console.log( '把咖啡倒进杯子' );
},
addCondiments: function(){
console.log( '加糖和牛奶' ); }
});

var Tea = Beverage({
brew: function(){
console.log( '用沸水浸泡茶叶' ); },
pourInCup: function(){
console.log( '把茶倒进杯子' );
},
addCondiments: function(){
console.log( '加柠檬' );
}
});
// 测试
var coffee = new Coffee();
coffee.init();

var tea = new Tea();
tea.init();
9、享元模式:运用共享技术来有效支持大量细粒度的对象。

内部状态与外部状态:
 内部状态存储于对象内部。
 内部状态可以被一些对象共享。
 内部状态独立于具体的场景,通常不会改变。
 外部状态取决于具体的场景,并根据场景而变化,外部状态不能被共享。

// 享元模式
var Model = function (sex) {
this.sex = sex; // 性别为内部状态
};

Model.prototype.takePhoto = function () {
console.log('sex=' + this.sex + ' underwear=' + this.underwear); // 内衣为外部状态
};
// 测试
var maleModel = new Model('male');
femaleModel = new Model('female');

for (var i = 1; i <= 50; i++) {
maleModel.underwear = 'underwear' + i;
maleModel.takePhoto();
};

for ( var j = 1; j <= 50; j++ ){
femaleModel.underwear = 'underwear' + j;
femaleModel.takePhoto();
};

10、职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

// 职责链模式
var order500 = function( orderType, pay, stock ){
if ( orderType === 1 && pay === true ){
console.log( '500 元定金预购,得到 100 优惠券' );
}else{
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};

var order200 = function( orderType, pay, stock ){
if ( orderType === 2 && pay === true ){
console.log( '200 元定金预购,得到 50 优惠券' );
}else{
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};

var orderNormal = function( orderType, pay, stock ){
if ( stock > 0 ){
console.log( '普通购买,无优惠券' );
}else{
console.log( '手机库存不足' );
}
};
// Chain.prototype.setNextSuccessor 指定在链中的下一个节点
// Chain.prototype.passRequest 传递请求给某个节点
var Chain = function (fn) {
this.fn = fn;
this.successor = null;
};

Chain.prototype.setNextSuccessor = function (successor) {
return this.successor = successor;
};

Chain.prototype.passRequest = function () {
var ret = this.fn.apply(this, arguments);

if(ret === 'nextSuccessor') {
return this.successor && this.successor.passRequest.apply(this.successor, arguments);
}

return ret;
};
// 测试
var chainOrder500 = new Chain( order500 );
var chainOrder200 = new Chain( order200 );
var chainOrderNormal = new Chain( orderNormal );

chainOrder500.setNextSuccessor( chainOrder200 );
chainOrder200.setNextSuccessor( chainOrderNormal);

chainOrder500.passRequest( 1, true, 500 );
chainOrder500.passRequest( 2, true, 500 );
chainOrder500.passRequest( 3, true, 500 );
chainOrder500.passRequest( 1, false, 0 );

11、中介者模式:增加一个中介者对象后,所有的相关对象都通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。

// 中介者模式
var goods = { // 手机库存
"red|32G": 3,
"red|16G": 0,
"blue|32G": 1,
"blue|16G": 6
};

var mediator = (function(){
var colorSelect = document.getElementById( 'colorSelect' ),
memorySelect = document.getElementById( 'memorySelect' ),
numberInput = document.getElementById( 'numberInput' ),
colorInfo = document.getElementById( 'colorInfo' ),
memoryInfo = document.getElementById( 'memoryInfo' ),
numberInfo = document.getElementById( 'numberInfo' ),
nextBtn = document.getElementById( 'nextBtn' );
return {
changed: function( obj ){
var color = colorSelect.value, // 颜色
memory = memorySelect.value,// 内存
number = numberInput.value, // 数量
stock = goods[ color + '|' + memory ]; // 颜色和内存对应的手机库存数量
if ( obj === colorSelect ){ // 如果改变的是选择颜色下拉框
colorInfo.innerHTML = color;
}else if ( obj === memorySelect ){
memoryInfo.innerHTML = memory;
}else if ( obj === numberInput ){
numberInfo.innerHTML = number;
}
if ( !color ){
nextBtn.disabled = true; nextBtn.innerHTML = '请选择手机颜色'; return;
}
if ( !memory ){
nextBtn.disabled = true; nextBtn.innerHTML = '请选择内存大小'; return;
}
if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 输入购买数量是否为正整数
nextBtn.disabled = true;
nextBtn.innerHTML = '请输入正确的购买数量'; return;
}
nextBtn.disabled = false;
nextBtn.innerHTML = '放入购物车';
}
}
})();

// 事件函数:
colorSelect.onchange = function(){
mediator.changed( this );
};
memorySelect.onchange = function(){
mediator.changed( this );
};
numberInput.oninput = function(){
mediator.changed( this );
};

12、装饰者模式:在不改变对象自身的基础上,在程序运行期间给对象动态地添加职责。

装饰者模式和代理模式:装饰者模式是实实在在的为对象增加新的职责和行为,而代理做的事情还是跟本体 一样。
// 用AOP装饰模式
Function.prototype.before = function(beforefn) {
var _self = this; // 保存原函数的引用
return function () {
beforefn.apply(this, arguments);
return _self.apply(this, arguments);
}
}

Function.prototype.after = function (afterfn) {
var _self = this;
return function () {
var ret = _self.apply(this, arguments);
afterfn.apply(this, arguments);
return ret;
}
}

13、状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

// 状态模式
var delegate = function (client, delegation) {
return {
buttonWasPressed: function () {
return delegation.buttonWasPressed.apply(client, arguments);
}
}
};

var FSM = {
off: {
buttonWasPressed: function() {
console.log('关灯');
this.button.innerHTML = '下一次按我是开灯';
this.currState = this.onState;
}
},
on: {
buttonWasPressed: function(){
console.log( '开灯' );
this.button.innerHTML = '下一次按我是关灯';
this.currState = this.offState;
}
}
};

var Light = function () {
this.offState = delegate(this, FSM.off);
this.onState = delegate(this, FSM.on);
this.currState = this.offState;
this.button = null;
};

Light.prototype.init = function () {
var button = document.createElement('button');
self = this;
button.innerHTML = '已关灯';
this.button = document.body.appendChild(button);
this.button.onclick = function () {
self.currState.buttonWasPressed();
}
};
// 测试
var light = new Light();
light.init();

14、适配器模式:解决两个软件实体间的接口不兼容的问题。

// 适配器模式
var renderMap = function( map ){
if ( map.show instanceof Function ){
map.show();
}
};

var googleMap = {
show: function(){
console.log( '开始渲染谷歌地图' );
}
};
var baiduMap = {
display: function(){
console.log( '开始渲染百度地图' );
}
};
var baiduMapAdapter = {
show: function(){
return baiduMap.display();
}
};
renderMap( googleMap ); // 输出:开始渲染谷歌地图
renderMap( baiduMapAdapter ); // 输出:开始渲染百度地图

QQsilhonette
关注
————————————————
版权声明:本文为CSDN博主「QQsilhonette」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/QQsilhonette/article/details/84954376

js设计模式(下)的更多相关文章

  1. JS设计模式(一)

    刚入职时,看过一段时间的设计模式,似懂非懂.不知不觉过去七个月了,对JS的理解更深刻了,数据结构与算法的基础也基本上算是过了一遍了,接下来要把设计模式搞定,然后不再深层次研究JS了,而是学习前端自动化 ...

  2. js设计模式(12)---职责链模式

    0.前言 老实讲,看设计模式真得很痛苦,一则阅读过的代码太少:二则从来或者从没意识到使用过这些东西.所以我采用了看书(<js设计模式>)和阅读博客(大叔.alloyteam.聂微东)相结合 ...

  3. JS设计模式——5.单体模式

    JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html   单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...

  4. js设计模式总结1

    js设计模式有很多种,知道不代表会用,更不代表理解,为了更好的理解每个设计模式,对每个设计模式进行总结,以后只要看到总结,就能知道该设计模式的作用,以及模式存在的优缺点,使用范围. 本文主要参考张容铭 ...

  5. js设计模式——4.迭代器模式

    js设计模式——4.迭代器模式 代码演示 /*js设计模式——迭代器模式*/ class Iterator { constructor(container) { this.list = contain ...

  6. js设计模式——1.代理模式

    js设计模式——1.代理模式 以下是代码示例 /*js设计模式——代理模式*/ class ReadImg { constructor(fileName) { this.fileName = file ...

  7. 《2016ThoughtWorks技术雷达峰会----js爆炸下的技术选型》

    JS爆炸下的技术选型  刘尚奇    ThoughtWorks, 高级咨询师 JS每6个星期出现一个新框架,那么如何进行JS的选型.以下从四个方面来分析. 1.工具 NPM for all the t ...

  8. Js获取下拉框选定项的值和文本

    Js获取下拉框的值和文本网上提供了2种方法:但有些人很不负责任,他们根本没考虑到浏览器之间的差异导致的错误,导致很多新手琢磨了半天找不出错误! 下面我总结下Firefox和IE下获取下拉框选定项的值和 ...

  9. js 设计模式-接口

    js模拟java接口检测函数:确保子类实现接口中的方法:(出自js设计模式) 上代码: <script type="text/javascript" > <%-- ...

  10. 前端笔记之JavaScript面向对象(三)初识ES6&underscore.js&EChart.js&设计模式&贪吃蛇开发

    一.ES6语法 ES6中对数组新增了几个函数:map().filter().reduce() ES5新增的forEach(). 都是一些语法糖. 1.1 forEach()遍历数组 forEach() ...

随机推荐

  1. 提升源代码安全性的C#和Java深度混淆工具——IpaGuard

    提升源代码安全性的C#和Java深度混淆工具--IpaGuard 摘要 Ipa Guard是一款功能强大的IPA混淆工具,通过对iOS IPA文件进行混淆加密,保护其代码.资源和配置文件,降低破解反编 ...

  2. 火山引擎 DataTester:0 代码也能实施 A/B 测试的实验平台

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 近日,火山引擎 DataTester 对 A/B 实验"可视化编辑器"进行了升级,可视化编辑器功能让用 ...

  3. Hugging News #0113:DreamBooth 编程马拉松活动保姆级视频教程来了!

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  4. ChatGPT插件权限给Plus用户放开了

    大家好,我是章北海mlpy ChatGPT插件权限给Plus用户放开了 我稍微测试了俩,感觉还行,后续我会对一些热门插件深入测测,敬请期待. 官方对插件的介绍如下: 1.插件由非由OpenAI控制的第 ...

  5. #3038:How Many Answers Are Wrong (带权并查集)

    HDU 3038 第一次接触带权并查集 //带权并查集 更新父节点的同时更新权值 #include<bits/stdc++.h> using namespace std; const in ...

  6. Codeforces Round #667 (Div. 3) A - D题题解

    Codeforces Round #667 (Div. 3) A - D Problem A - Yet Another Two Integers Problem https://codeforces ...

  7. linux下jdk1.7、1.8版本的安装

    -----1.7------        (1)解压安装包         tar -zxvf jdk-7u80-linux-x64.tar.gz    (2)移动到安装目录             ...

  8. 使用JSEncrypt加密解密

    最近项目中使用非对称加密JSEncrypt. uni-app中先安装第三方npm包jsencrypt util文件夹下新建一个jsencrypt.js文件 1 import JSEncrypt fro ...

  9. java进阶(12)--8种数据包装类型、Integer、常用方法

    一.基本数据类型与包装类型 8种基本数据类型,对应的包装类,父类 1.byte-->java.lang.Byte-->Number 2.short-->java.lang.Short ...

  10. zookeeper分布式锁原理及使用 curator 实现分布式锁

    本文为博主原创,未经允许不得转载: 1. zookeeper 分布式锁应用场景及特点分析 2. zookeeper 分布式原理 3. curator 实现分布式锁 1. zookeeper 分布式锁: ...