工厂模式
就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。比如,一台咖啡机就可以理解为一个工厂模式,你只需要按下想喝的咖啡品类的按钮(摩卡或拿铁),它就会给你生产一杯相应的咖啡,你不需要管它内部的具体实现,只要告诉它你的需求即可。
优点:有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例
缺点:不易拓展,一旦添加新的产品类型,就不得不修改工厂的创建逻辑
简单的工厂模式可以理解为解决多个相似的问题
function CreatePerson(name,age,sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function(){
return this.name;
}
return obj;
}
var p1 = new CreatePerson("longen", 28 , 男 );
var p2 = new CreatePerson("tugenhua", 27 , 女 );
console.log(p1.name); // longen
console.log(p1.age); // 28
console.log(p1.sex); // 男
console.log(p1.sayName()); // longen
console.log(p2.name); // tugenhua
console.log(p2.age); // 27
console.log(p2.sex); // 女
console.log(p2.sayName()); // tugenhua
单例模式
是一种常用的软件设计模式,在应用这个模式时,单例对象的类必须保证只有一个实例存在,整个系统只能使用一个对象实例。
优点:不会频繁地创建和销毁对象,浪费系统资源。
使用场景:IO 、数据库连接、Redis 连接等。
// 单体模式
var Singleton = function(name){
this.name = name;
};
Singleton.prototype.getName = function(){
return this.name;
}
// 获取实例对象
var getInstance = (function() {
var instance = null;
return function(name) {
if(!instance) {//相当于一个一次性阀门,只能实例化一次
instance = new Singleton(name);
}
return instance;
}
})();
// 测试单体模式的实例,所以a===b
var a = getInstance("aa");
var b = getInstance("bb");
沙箱模式
将一些函数放到自执行函数里面,但要用闭包暴露接口,用变量接收暴露的接口,再调用里面的值,否则无法使用里面的值
let sandboxModel=(function(){
function sayName(){};
function sayAge(){};
return{
sayName:sayName,
sayAge:sayAge
}
})()
发布者订阅模式
-----观察者模式
定义对象间的一种一对多依赖关系。
观察者模式又叫做发布-订阅模式
优点:以实现表示层和数据逻辑层的分离
缺点:如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
就例如如我们关注了某一个公众号,然后他对应的有新的消息就会给你推送通知所有的订阅者: 发布者触发时依次执行缓存列表里所有的订阅者回调
//发布者与订阅模式
var shoeObj = {}; // 定义对象
shoeObj.list = []; // 缓存列表 存放订阅者回调函数
// 增加订阅者
shoeObj.listen = function(fn) {
shoeObj.list.push(fn); // 订阅消息添加到缓存列表
}
// 发布消息
shoeObj.trigger = function() {
// 当事件触发的时候(状态发生变化),依次执行回调函数
for (var i = 0, fn; fn = this.list[i++];) {
fn.apply(this, arguments);//第一个参数只是改变fn的this,
}
}
// 小红订阅如下消息
shoeObj.listen(function(color, size) {
console.log("颜色是:" + color);
console.log("尺码是:" + size);
});
// 小花订阅如下消息
shoeObj.listen(function(color, size) {
console.log("再次打印颜色是:" + color);
console.log("再次打印尺码是:" + size);
});
shoeObj.trigger("红色", 40);
shoeObj.trigger("黑色", 42);
通知指定的订阅者(多个订阅者):
//发布者与订阅模式
var shoeObj = {}; // 定义对象
shoeObj.list = []; // 缓存列表 存放订阅者回调函数
// ['xiaohong88':[],'xiaohua88':[]]
// 增加订阅者
shoeObj.listen = function(key,fn) {
if(!this.list[key]){
this.list[key] = []
}
this.list[key].push(fn); // 订阅消息添加到缓存列表
}
// 发布消息
shoeObj.trigger = function() {
var key = Array.prototype.shift.call(arguments),
fns = this.list[key]
// 当事件触发的时候(状态发生变化),依次执行回调函数
for (var i = 0, fn; i < fns.length; i++) {
fns[i].apply(this, arguments);//第一个参数只是改变fn的this,
}
}
// 小红订阅如下消息
shoeObj.listen('xiaohong88',function(color, size) {
console.log("颜色是:" + color);
console.log("尺码是:" + size);
});
shoeObj.listen('xiaohong88',function(color, size) {
console.log("再次打印颜色是:" + color);
console.log("再次打印尺码是:" + size);
});
shoeObj.trigger('xiaohong88',"红色", 40);
// shoeObj.trigger("黑色", 42);
抽离成一个对象
//发布者与订阅模式
var Event = {
list:[], // 缓存列表 存放订阅者回调函数
// 增加订阅者
listen:function(key,fn) {
if(!this.list[key]){
this.list[key] = []
}
this.list[key].push(fn); // 订阅消息添加到缓存列表
},
// 发布消息
trigger(){
var key = Array.prototype.shift.call(arguments),
fns = this.list[key]
// 当事件触发的时候(状态发生变化),依次执行回调函数
for (var i = 0, fn; i < fns.length; i++) {
fns[i].apply(this, arguments);//第一个参数只是改变fn的this,
}
}
}
function installEvent(target,Source){
return Object.assign(target,Source)
}
var shoeObj= installEvent(shoeObj = {},Event)
// 小红订阅如下消息
shoeObj.listen('xiaohong88',function(color, size) {
console.log("颜色是:" + color);
console.log("尺码是:" + size);
});
shoeObj.listen('xiaohong88',function(color, size) {
console.log("再次打印颜色是:" + color);
console.log("再次打印尺码是:" + size);
});
shoeObj.trigger('xiaohong88',"红色", 40);
// shoeObj.trigger("黑色", 42);