想分享的几种设计模式

目前模式:工厂模式,单例模式,适配器模式,装饰者模式,建造者模式

建造者模式

简介:建造者模式(builder pattern)比较简单,它属于创建型模式的一种。

白话:4个部分:有个产品,有个工厂可以造产品,有个设计师指挥造多少,有个人想买产品。

买产品的用户不介意产品制造流程,只需要产品!

function Cola() {this.sugar = '50g',this.water = '100g'
}
function Packing() { // 第一种打包方式this.createPkg = function(){console.log('创建可乐外皮')}this.pushCola = function() {console.log('可乐倒进瓶子')}this.complete = function() {var cola = new Cola()cola.complete = truereturn cola}this.init = function() {this.createPkg() // 创建外皮this.pushCola() // 倒进瓶子//还可以增加其他步骤return this.complete() // 制作完成}
}
function greenPacking() { //绿皮可乐打包方式this.createPkg = function(){console.log('创建green可乐外皮')}this.pushCola = function() {console.log('可乐倒进green瓶子')}this.complete = function() {var cola = new Cola()cola.complete = truereturn cola}this.init = function() {this.createPkg() // 创建外皮this.pushCola() // 倒进瓶子//还可以增加其他步骤return this.complete() // 制作完成}
}
function Boss() {this.createCola = function(packType) {const pack = new window[packType]this.product = pack.init() //完整产品产出}this.getCola = function(packType) {this.createCola(packType);return this.product}
}
const boss = new Boss()
var UserCola = boss.getCola('greenPacking') // UserCola.complete === true

其他东西都不要,只要最后生产好的Cola,有sugar,有water。

关键在于Boss 函数中,担任一个整合的职责

同样的Boss函数,我可以通过更换Packing函数,打包方式,获得不同样式的Cola。

通过给getCola函数传入不同想要的参数,获得不同的最终产品。实现了可插拔的函数结构。

装饰者模式

装饰者提供比继承更有弹性的替代方案。 装饰者用用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数)。

装饰者用于通过重载方法的形式添加新功能,该模式可以在被装饰者前面或者后面加上自己的行为以达到特定的目的。

好处:

装饰者是一种实现继承的替代方案。当脚本运行时,在子类中增加行为会影响原有类所有的实例,而装饰者却不然。取而代之的是它能给不同对象各自添加新行为。参考 前端手写面试题详细解答

function iwatch () {this.battery = 100;this.getBattery = function() {console.log(this.battery)}
}iwatch.prototype.getNewPart = function(part) {this[part].prototype = this; //把this对象上的属性 指向 新对象的prototypereturn new this[part]; //返回一个新对象,不修改原对象,新增了新对象的属性
}iwatch.prototype.addNetwork = function() {this.network = function() {console.log('network')}
}iwatch.prototype.addSwim = function() {this.swim = function() {console.log('swim')}
}var watch = new iwatch();
watch.getBattery(); // 100watch = watch.getNewPart('addNetwork'); // 添加新行为,network()
watch = watch.getNewPart('addSwim'); // 既有network方法,也有swim方法

在 ES7 中引入了@decorator 修饰器的提案,参考阮一峰的文章。

@testable
class MyTestableClass {// ...
}function testable(target) {target.isTestable = true;
}MyTestableClass.isTestable // true

直接可以使用,装饰器行为

@decorator
class A {}// 等同于class A {}
A = decorator(A) || A;

工厂模式

一个工厂能生产好多不同的产品,最常见的工厂函数就是jQ的$()函数,每一个函数的结果都是一个需要的产品。

function Product(name) {this.name = name;
}
Product.prototype.init = function () {console.log('init');
}
Product.prototype.go = function () {console.log('go');
}function Factory () {}
Factory.prototype.add = function(name) {return new Product(name);
}//use
let f = new Factory();
let a = f.add('a');console.log(a.name);
a.init();
a.go();

适配器模式

Adapter,将一个类(对象)的接口(方法或者属性)转化为另一个接口,以满足用户需求,使类(对象)之间接口的不兼容问题通过适配器得以解决

function Person () {}
Person.prototype.Say = function() {throw new Error("该方法必须被重写!")
}
Person.prototype.Walk = function() {throw new Error("该方法必须被重写!")
}function Dog () {}
Dog.prototype.Walk = function() {throw new Error("该方法必须被重写!")
}
Dog.prototype.shout = function() {throw new Error("该方法必须被重写!")
}function PersonA () {Person.apply(this)
}
PersonA.prototype = new Person()
PersonA.prototype.Say = function() {console.log('Person say')
}
PersonA.prototype.Walk = function() {console.log('Person Walk')
}function DogBlack () {Dog.apply(this)
}
DogBlack.prototype = new Dog()
DogBlack.prototype.Walk = function() {console.log('Dog Walk')
}
DogBlack.prototype.shout = function() {console.log('Dog Shout')
}//现在希望Dog类也可以学会Say,并且多走几步function DogSayAdapter (DogClass) {Dog.apply(this)this.DogClass = DogClass
}
DogSayAdapter.prototype = new Dog()
DogSayAdapter.prototype.Say = function() {this.DogClass.shout()
}
DogSayAdapter.prototype.Walk = function() {this.DogClass.Walk()this.DogClass.Walk()
}var personA = new PersonA()
var dogBlack = new DogBlack()
var dogSay = new DogSayAdapter(dogBlack)personA.Say()
personA.Walk()
dogBlack.Walk()
dogBlack.shout()dogSay.Say()
dogSay.Walk()//walk * 2

适配器不只是函数接口,还有数据格式的适配

在前后端数据传递时,常用到适配器模式,也就是通俗易懂的格式化数据,format函数等等

vue的computed计算属性也是适配器模式的一种实现

const originData = [{title: 'title',age: 18,content: ['123',321],callback: function(){console.log(this)}},{title: 'title2',age: 1,content: ['1',3],callback: function(){console.log('title2')}}
]function dataAdapter(data) {return data.map(item => {return {title: item.title,content: item.content.join(','),init: item.callback}})
}var formatData = dataAdapter(originData)

e.g:原始data 的数据不满足当前的要求,通过适配器,把数据格式化成想要的格式,对原始数据没有改变

单例模式

function Simple (name) {this.name = name
}
Simple.prototype.go = function() {this.name = 'go'console.log(this.name)
}//static静态方法
Simple.getInstance = (function() {var insreturn function(name){if (!ins) {ins = new Simple(name)}return ins}
})()let a = Simple.getInstance('a') // name: a
let b = Simple.getInstance('b') // name: ab===a//true

非单例模式下,相同的new Simple()构造函数,不相等。

通过闭包只创建一次Simple实例,大家公用一个。

惰性单例模式

惰性和懒加载lazyload相似,延迟加载,或者说需要时再加载,不然一次加载过多,频繁进行操作dom影响性能

尽管上述代码有Simple.getInstance方法,可以在需要时再进行实例化,但仍然不是一个好的实现方式。

可以将惰性加载的部分提取出来。

e.g:

var simple = function(fn) {var instance;return function() {return instance || (instance = fn.apply(this, arguments));}
};
// 创建遮罩层
var createMask = function(){// 创建div元素var mask = document.createElement('div');// 设置样式mask.style.position = 'fixed';mask.style.top = '0';......document.body.appendChild(mask);// 单击隐藏遮罩层mask.onclick = function(){this.style.display = 'none';}return mask;
};// 创建登陆窗口
var createLogin = function() {// 创建div元素var login = document.createElement('div');// 设置样式login.style.position = 'fixed';login.style.top = '50%';......login.innerHTML = 'login it';document.body.appendChild(login);return login;
};document.getElementById('btn').onclick = function() {var oMask = simple(createMask)();oMask.style.display = 'block';var oLogin = simple(createLogin)();oLogin.style.display = 'block';
}

总结

对五种常见常用的设计模式进行了学习,这几种很多时候都会用到,接下来还会继续学习其他的18种设计模式,可能有的设计模式不一定在实际敲码中使用,学了没坏处,总能用得上嗷!

网上对于设计模式的文章,书籍层出不尽,但看得再多,不如自己理解,并且实际使用。很多时候是几种设计模式融合在一起使用,如果不是自己去写一遍,理解一遍,可能常见的设计模式都理解不了。这样就太可惜了,发现干净整洁的代码,都说不出哪里好,就是看着舒服,顺眼,运行速度快…

手写JavaScript常见5种设计模式相关推荐

  1. Design-patterns-JS:用JavaScript实现23种设计模式

    Design-patterns-JS:用JavaScript实现23种设计模式 github:https://github.com/fbeline/design-patterns-JS gitee:  ...

  2. javascript的几种设计模式

    <Practical Common Lisp>的作者 Peter Seibel 曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通 ...

  3. android 手写字体识别,一种基于Android系统的手写数学公式识别及生成MathML的方法...

    专利名称:一种基于Android系统的手写数学公式识别及生成MathML的方法 技术领域: 本发明属于模式识别技术领域,涉及数学公式中字符间的空间结构分析,具体涉及一种基于Android系统的手写数学 ...

  4. python常见几种设计模式

    文章目录 1. 创建型模式 1.1. 工厂模式 1.2. 抽象工厂模式 1.3. 建造者模式 1.4. 原型模式 2. 结构型模式 2.1. 外观模式 2.2. 装饰器模式 2.3. 代理模式 2.4 ...

  5. 手写JavaScript

    导出TXT文件 <!DOCTYPE html> <html><head><meta charset="utf-8"><titl ...

  6. matlab手写字母识别,一种基于MATLAB的手写字母的神经网络识别方法

    文章编号 :1009 - 671X(2001) 10 - 0028 - 03 一种基于 MATLAB 的手写字母的神经网络识别方法 邓铭辉 ,孙 枫 ,张 志(哈尔滨工程大学 自动化学院 ,黑龙江 哈 ...

  7. 苹果键盘怎么手写_支持9种外语语音识别,新增4款外语键盘,搜狗输入法10.8版本上线丨18周新闻...

    搜狗AI合成主播雅妮 为您带来搜狗本周新闻播报 新 闻 原 文 .01. 搜狗输入法率先适配新款iPhone SE 4月24日,搜狗输入法发布适配新款iPhoneSE #AI智慧输入#,以AI输入引擎 ...

  8. PHP常见三种设计模式:单例、工厂、观察者

    1.单例模式 目的:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 应用场景:数据库连接.缓存操作.分布式存储. /*** 设计模式之单例模式* $_instance必须声明为静态的私有变量* ...

  9. 编程的常见28种设计模式(如若不全敬请谅解)

    1 写代码要考虑到如何让代码更加简练,更加容易维护,容易扩展和复用,如果觉得前面的内容太多,可以之间看30总结(最下方). 2 策略模式: 定义了算法家族,分别封装起来,让他们可以互相替换,此模式让算 ...

最新文章

  1. tomcat的部署及session绑定反代
  2. 二叉树的前中后序遍历之迭代法(统一风格迭代方式)
  3. 安装VS2008新挫折
  4. C++Primer学习笔记:第5章 语句
  5. python查看电脑配置_怎么查看电脑配置(教你如何查看电脑配置信息和型号)
  6. ASP.NET 控制页和内容页中的事件
  7. Python:下载安装包
  8. 博弈论的经典入门课程和资料
  9. 使用phpStudy显示3306端口被占用,该怎么办?
  10. openwrt 中 Luci 的简单使用
  11. org.dom4j.DocumentException: 1 字节的 UTF-8 序列的字节 1 无效。
  12. Xposed模块开发
  13. 改Android app字体,Android 开发之修改 app 的字体大小
  14. python手机编译器怎么编写程序_怎么用手机编写Python程序?
  15. win10系统镜像Hash值验证
  16. 用sklearn判断ins内容是否能上热门
  17. python从字符串中提取指定内容
  18. linux录音跳过无效数据,录音器点击“开始录制”没有反应怎么解决?
  19. U872新品上市 全面支持企业渡过寒冬
  20. 大疆教父李泽湘创办的固高科技过会:拟募资4.5亿 联想是股东

热门文章

  1. JWT之token机制与双token详解
  2. 第24章 让唯美的雪花飘扬——三维粒子系统的实现
  3. 搜苹果ipad版_优秀的文本笔记工具 Keep It 苹果软件破解版
  4. 《程序员的呐喊》一一1.1 作者手记:巴别塔
  5. 如何屏蔽chrome浏览器内自带广告
  6. NOIP 2008 普及组初赛试题 解题报告、题解及选择题思路,高质量
  7. 22-08-06 西安 尚医通(03)EasyExcel; Spring Cache 、Redis做缓存
  8. 格林纳达常驻WTO大使孙宇晨受邀出席美驻新大使的闭门午宴
  9. php实现通讯录按字母分组,通讯录首字母检索功能实现
  10. 程序员中的“芳心纵火犯”, 这就是面向对象编程吗?