目前模式:工厂模式,单例模式,适配器模式,装饰者模式,建造者模式javascript
简介:建造者模式(builder pattern)比较简单,它属于建立型模式的一种。html
白话:4个部分:有个产品,有个工厂能够造产品,有个设计师指挥造多少,有我的想买产品。vue
买产品的用户不介意产品制造流程,只须要产品!java
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 = true
return 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 = true
return 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。es6
关键在于Boss 函数中,担任一个整合的职责typescript
一样的Boss函数,我能够经过更换Packing函数,打包方式,得到不一样样式的Cola。segmentfault
经过给getCola函数传入不一样想要的参数,得到不一样的最终产品。实现了可插拔的函数结构。后端
装饰者提供比继承更有弹性的替代方案。 装饰者用用于包装同接口的对象,不只容许你向方法添加行为,并且还能够将方法设置成原始对象调用(例如装饰者的构造函数)。设计模式
装饰者用于经过重载方法的形式添加新功能,该模式能够在被装饰者前面或者后面加上本身的行为以达到特定的目的。闭包
好处:
装饰者是一种实现继承的替代方案。当脚本运行时,在子类中增长行为会影响原有类全部的实例,而装饰者却否则。取而代之的是它能给不一样对象各自添加新行为。
function iwatch () {
this.battery = 100;
this.getBattery = function() {
console.log(this.battery)
}
}
iwatch.prototype.getNewPart = function(part) {
this[part].prototype = this; //把this对象上的属性 指向 新对象的prototype
return 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(); // 100
watch = watch.getNewPart('addNetwork'); // 添加新行为,network()
watch = watch.getNewPart('addSwim'); // 既有network方法,也有swim方法
复制代码
具体例子: typescript装饰器
在 ES7 中引入了@decorator 修饰器的提案,参考阮一峰的文章。
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
复制代码
直接可使用,装饰器行为
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
复制代码
更多的详见:阮一峰博客
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();
复制代码
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 ins
return function(name){
if (!ins) {
ins = new Simple(name)
}
return ins
}
})()
let a = Simple.getInstance('a') // name: a
let b = Simple.getInstance('b') // name: a
b===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种设计模式,可能有的设计模式不必定在实际敲码中使用,学了没坏处,总能用得上嗷!
网上对于设计模式的文章,书籍层出不尽,但看得再多,不如本身理解,而且实际使用。不少时候是几种设计模式融合在一块儿使用,若是不是本身去写一遍,理解一遍,可能常见的设计模式都理解不了。这样就太惋惜了,发现干净整洁的代码,都说不出哪里好,就是看着舒服,顺眼,运行速度快...