设计模式
设计模式 ---> 解决问题的套路
-
在开发中总结的一套方法,专门用来解决一类问题
-
要求:设计一套系统需要设计模式(架构师)
-
来源: 建筑行业-设计模式的四人帮
-
常见的设计模式: 单粒(例)模式, 代理委托模式,观察者模式,中介模式
-
推荐书籍: 《设计模式》《大话设计模式》《大话数据结构》
-
编程就是: 数据结构 + 算法
工厂模式
工厂模式:用来创建对象的一种最常用的设计模式。区分为简单工厂模式、工厂方法模式、抽象工厂模式
简单工厂模式
- 核心步骤:
- 1.提供一个父构造函数(开了一家工厂)
- 2.设置父构造函数的原型对象(产品公共的一些东西)
- 3.在父构造函数上提供一个静态的工厂方法(生产产品)
- 4.定制合作伙伴
- 5.使用父构造函数的静态工厂方法创建对象
- 实现
// 1.提供一个父构造函数(开了一家工厂)
function PhoneMake (){
}
// 2.设置父构造函数的原型对象(产品公共的一些东西)
PhoneMake.prototype.logDes = function (){
}
// 3.在父构造函数上提供一个静态的工厂方法(生产产品)
PhoneMake.factory = function (){
console.log(this.des)
}
// 4.定制合作伙伴
PhoneMake.iphone = function(){
this.des = ''
}
PhoneMake.vivo = function(){
this.des = ''
PhoneMake.oppo = function(){
this.des = ''
}
// 5.使用父构造函数的静态工厂方法创建对象
var iphone = PhoneMake.factory('iPhone');
iphone.logDes();
var vivo = PhoneMake.factory('vivo');
vivo.logDes();
var oppo = PhoneMake.factory('oppo');
oppo.logDes();
var meizu = PhoneMake.factory('meizu');
meizu.logDes();
单粒(例)模式
一个类创建出来的对象都是同一个对象
单例模式使用的场景
比如线程池、全局缓存等。我们所熟知的浏览器的window对象就是一个单例,在JavaScript开发中,对于这种只需要一个的对象,我们的实现往往使用单例。
单粒实现方式01(全局变量)
- 步骤
-
- 提供一个全局变量(instance)
- 2.提供一个构造函数
- 3.判断instance是否有值,有值就直接返回
- 4.没有就把this赋值给instance
- 5.设置属性和方法
-
// 1.提供一个全局变量
var instance;
// 2.提供一个构造函数
function Person(){
// 3.判断全局变量是否有值,如果有值就直接返回
if(instance){ //第二次以上
return instance;
}
// 第一个创建对象
// 4,如果没有值,就把this赋值给instance
instance = this;
// 5.设置属性和方法
this.name = '默认';
}
var p1 = new Person();
var p2 = new Person();
instance = 'demo'
var p3 = new Person();
console.log(p1 === p2); // true
console.log(p3); // Person{} 新创建的对象
注意:return 的值如果不是引用类型的数据,那么return返回的是默认创建的对象
缺点:全局变量在整一个作用域都可以被访问或者修改,一旦被修改,创建出来的对象就不再是之前的单粒对象
单粒实现方式02(静态属性)
// 1.提供一个构造函数
function Person(){
// 2.判断构造函数静态属性instance是否有值,如果有值就直接返回
if(Person.instance){ //第二次以上
return Person.instance;
}
// 第一个创建对象
// 3,如果没有值,就把this赋值给instance
Person.instance = this;
// 4.设置属性和方法
this.name = '默认';
}
var p1 = new Person();
var p2 = new Person();
console.log(p1 == p2);// true
Person.instance = 'demo';
var p4 = new Person();
console.log(p4); // person{}
好处:instance 不是全局变量,不容易被修改
缺点:静态属性仍然能被修改
单粒实现方式03(惰性函数)
- 步骤:
- 1.提供一个构造函数
- 2.提供一个封闭作用域的私有变量
- 3.利用惰性函数定义更新函数
- 4.把this赋值给instance
- 5.设置属性和方法
// 1.提供一个构造函数
function Person(){
// 2.提供一个封闭作用域的私有变量
var instance;
// 3.利用惰性函数定义更新函数
Person = function (){
return instance;
}
// 第一个创建对象
// 4.把this赋值给instance
instance = this;
// 5.设置属性和方法
this.name = '默认';
}
//var p1 = new Person();
//var p2 = new Person();
//console.log(p1 == p2);// true
Person.prototype.des = 'des';
var p3 = new Person();
Person.prototype.hi = 'hi';
var p4 = new Person();
console.log(p3.des); // des
console.log(p4.des); // des
console.log(p3.hi); // undefined
console.log(p4.hi); // undefined
console.log(p3.constructor == Person);// false
- 问题:
- 1.创建对象之后设置的原型对象和单粒对象的原型对象,不是同一个对象
- (广义理解: 第一个对象创建出后,其后的原型对象是新创建的Person,不是旧的)
- 2.单粒对象的构造器属性执行指向旧的构造函数
- 1.创建对象之后设置的原型对象和单粒对象的原型对象,不是同一个对象
惰性函数实现单粒改进 04
- 步骤
- 1.提供一个构造函数
- 2.在构造函数内部声明一个私有变量instance
- 3.利用惰性函数更新构造函数
- 4.设置新构造函数的原型对象是旧构造函数的原型对象(原型式继承)
- 4*.设置新构造函数的原型对象是旧构造函数的实例对象(原型链继承better)
- 5.利用新构造函数创建对象并赋值给instance
- 6.修正构造器属性
- 7.通过instance设置属性或方法
- 8.返回instance
// 1.提供一个构造函数
function Person(){
// 2.在构造函数内部声明一个私有变量instance
var instance;
// 3.利用惰性函数更新构造函数
Person = function(){
return instance;
}
// 4.设置新构造函数的原型对象是旧构造函数的原型对象(原型式继承)
// Person.prototype = this.__proto__;
// *4.更优原型链继承
Person.prototype = this;
// 5.利用新构造函数创建对象并赋值给instance
instance = new Person();
// 6.修正构造器属性
instance.constructor = Person ;
// 7.通过instance设置属性或方法
instance.name = '默认';
// 8.返回instance
return instance;
}
//var p1 = new Person();
//var p2 = new Person();
//console.log(p1==p2); // true
Person.prototype.des = 'des';
var p3 = new Person();
Person.prototype.hi = 'hi';
var p4 = new Person();
console.log(p3.des); // des
console.log(p4.des); // des
console.log(p3.hi); // hi
console.log(p4.hi); // hi
console.log(p3.constructor == Person);// true
图解

参照文献:工厂模式 juejin.cn/post/684490…