工厂模式
工厂模式就是使用函数创建对象 返回对象
避免多次创建对象
只需要传递一个合法的参数,就可以获取到你想要的对象,而无需知道创建的具体的细节
例如直接创建一个对象,将属性和方法全部放在这个对象里面
function Factory(name,sex,age,job){
//创建一个对象
var obj={};
obj.name=name;
obj.sex=sex;
obj.age=age;
obj.job=job;
obj.eat=function (){
return this.name+"吃饭!";
}
return obj;
}
console.log(Factory("张三","男",18,"学生"));
console.log(Factory("李四","男",22,"厨子"));
构造函数模式
1、构造函数模式就是把多个程序抽象成方法
2、使用构造函数的方法,既解决了重复实例化的问题,又解决了对象识别的问题。
原型模式
原型模式,原型对象上的属性和方法是共享的
空对象获取属性时 自身没有该属性 则原型对象上的属性充当默认值
设置空对象时 是给自己设置属性 不会修改原型对象的属性,因为原型对象上的属性是共享的
缺点:是原型对象属性方法的共享
function Person() {
}
Person.prototype = {
constructor: Person,
name: "默认值",
sex: '',
sleep: function (m) {
return this.name + "睡觉" + m;
}
}
//创建人
var c1 = new Person();
c1.name = "张三"
console.log(c1.sleep("打呼噜"));
var c2 = new Person();
console.log(c2.sleep("不踏实"));
单例模式
单例模式 一个类提供一个实例,并且暴漏出一个全局访问点(闭包)
保证一个类只有一个实例,一般先判断实例是否存在,如果存在直接返回,不存在则先创建再返回,这样就可以保证一个类只有一个实例对象。
作用: (1)、保证某个类的对象的唯一性; (2)、模块间通信; (3)、防止变量污染
// 简单的单例
function Person(name) {
this.name = name;
}
//给上面的方法添加原型属性或方法
Person.prototype.getName = function () {
return this.name;
}
//自执行 执行函数 返回闭包的对象
//就是一个单例方法
var getObject = (function () {
var instance = null;
return function (name) {
if (!instance) {
instance = new Person(name);
}
//该函数的返回值对象 返回一个单独的对象
return instance;
}
})();
//调用单例模式
console.log(getObject("张三").getName());//张三
console.log(getObject("李四").getName());//张三
console.log(getObject("王五").getName());//张三
/*
* 设置多个类对象 将单例的方法 抽象为一个共享方法
*
* callback 为回调函数
*
* 这个共享方法 不适用自执行
* */
var getInstance = function (callback) {
var instance = null;
return function () {
if (!instance) {
//实例化对象
//apply 替换函数内部的this指针 执行前面的函数
//this 指向window 可以可不写
//console.log(this);
instance = callback.apply(null, arguments);
}
return instance;
}
};
console.log(getInstance(function () {
console.log(arguments);
var per = new Person("李四");
return per;
})().getName());
console.log(getInstance(function () {
var per = new Person("王五");
return per;
})().getName());
function Animale(name,age){
this.name=name;
this.age=age;
}
Animale.prototype.getName=function (){
return this.name;
}
console.log(getInstance(function () {
var name = arguments[0];
var age = arguments[1];
var cat = new Animale(name, age);
return cat;
})("猫咪", 2).getName());
策略模式
策略模式属于对象行为型模式,主要针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响 到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用
优点: 1、避免使用大量的if-else语句,使代码块简洁,易读。
2、符合设计原则中的开放-封闭原则,面向扩展开放,面向修改关闭。
3、复用性高
缺点:增加了许多策略类或者策略对象
例如转盘抽奖
var Sq = {
gg: [],
basePro: [],
g: null,
proindex: null,
randominfo: function () {
this.g = Math.random();
for (var i = this.gg.length - 1; i >= 0; i--) {
if (this.g <= this.gg[i]) {
this.proindex = i;
}
}
}
}
var Rotate = {
baseRotate: 1500,
index: null,
rotate: null,
random: function () {
Sq.randominfo();
this.index = Sq.proindex;
},
rotateInfo: function () {
this.rotate = this.index * 72 + Math.random() * 72;
},
allRotate: function () {
this.random();
this.rotateInfo();
return this.baseRotate + this.rotate;
}
}
function addPro(pro) {
for (var key in pro) {
Sq.basePro.push(key);
Sq.gg.push(pro[key]);
}
}
addPro({
A: 0.1,
B: 0.3,
C: 0.5,
D: 0.7,
E: 1,
});
//重新随机
console.log(Rotate.allRotate());
发布-订阅模式
发布订阅模式又叫观察者模式,定义对象间的一种一对多的关系,当一个对象的状态发生改变时,所有依赖它的对象都将的到通知
优点:对象之间的解耦
异步编程中,可以更松耦合的代码编写
缺点:创建订阅者本身要消耗一定的时间和内存
虽然可以弱化对象之间的联系,多个订阅者和发布者嵌套在一起的时候,程序难以跟踪和维护
var observer = {
subscribes: [],//订阅集合
//订阅的方法
subscribe: function (types, fn) {
//检测types有没有订阅
if (!this.subscribes[types]) {
//创建订阅
this.subscribes[types] = [];
}
//处理订阅的fn
/*if(typeof fn=="function")
{
this.subscribes[types].push(fn);
}*/
typeof fn == "function" && this.subscribes[types].push(fn);
},
//执行订阅
publish: function () {
//检测当前的订阅是否存在
var types = [].shift.call(arguments);//获取订阅着
var fns = this.subscribes[types];
//var name = [].shift.call(arguments).name;//获取订阅函数名称
if (!fns || fns.length == 0) {
return;
}
//开始执行
var args = arguments;
fns.forEach(function (handle) {
console.log(handle.name);
//handle.name 获取当前函数名称
/* handle.name == name &&*/ handle.apply(this, args);
});
/* for (var i = 0; i < fns.length; i++) {
fns[i].apply(this, arguments);
}*/
},
//删除订阅
remove: function (types, fn) {
//检测types 不存在 直接全部订阅移除
if (!types) {
this.subscribes = [];
return;
}
//获取当前的订阅集合
var fns = this.subscribes[types];
if (!fns || fns.length == 0) {
return;
}
//检测fn
if (typeof fn !== "function") {
return;
}
//删除订阅
fns.forEach(function (handle, index) {
if (handle == fn) {
fns.splice(index, 1);
}
});
}
}
/*
* 模拟 maodou 定飞机票 火车票
* */
function getPiao(res) {
console.log("订购:", res);
}
function getHose(res) {
console.log("订:", res, "酒店");
}
observer.subscribe("maodou", getPiao);
observer.subscribe("maodou", getHose);
observer.subscribe("maodou", function () {
console.log("先去吃饭!");
});