这是我参与更文挑战的第18天,活动详情查看:更文挑战
设计模式的简介
设计模式就是一套编目分明,广为人知,可复用的代码经验的总结
工具库:它是一些方法的集合体,比如jquery, underscore,它们里面的方法通常是没有联系的
框架: 一套半成品代码, 它里面也支持一些方法,这些方法之间通常是有联系的
架构: 它是一套大型项目的设计思路
分类
所有的设计模式基本上可以分为三类创建型设计模式,结构型设计模式,行为型设计模式
作用
创建型设计模式的作用: 解决了创建对象时候的问题
结构型设计模式的作用: 解决了对象和类组合在一起时候的问题
行为型设计模式的作用:解决了对象和类偶合,职责之间的关系
历史
设计模式最初是由外国的一个叫做GOF (Gang of Four), 设计模式一共有23种, 设计模式发展至今,已经远远超过23种。
简单工厂模式
举例:
function person(name, age, sex, job) {
var person = {
name: name,
age: age,
sex: sex,
job: job
}
return person;
}
此时,person就是一个“简单工厂”, 每次放入不同的“原料”, 就可以得到不同的"产品"
执行代码:
var p = person("老王", 40, "男", "厨师");
var p1 = person("老张", 41, "男", "IT");
输出结果:
寄生增强工厂
举例:
// 定义新的工厂
function StrongPerson(name, age, sex) {
// 这是一个工厂
// 初始化People
var p = new People(name, age, sex);
// 对象p添加属性和方法
p.title = "nihao";
p.sayNihao = function() {
console.log("你好");
}
return p;
}
执行代码:
// 创建对象
var people = new StrongPerson("小刚", 12, "男");
people.sayHello();
people.sayNihao();
输出结果:
工厂方法
定义: 管理多个类,可以返回多个产品
// 工厂方法: 定义一个工厂, 内部包含多个实例的创建
// 定义构造函数
function Dog() {
this.type = "dog";
}
// 定义构造函数
function Cat() {
this.type = "cat";
}
// 定义构造函数
function Pig() {
this.type = "pig";
}
// 定义新的工厂
function FactoryMethod(type) {
if (type === "dog") {
return new Dog();
} else if (type === "cat") {
return new Cat();
} else if (type === "pig") {
return new Pig();
}
}
var dog = FactoryMethod("dog");
var cat = FactoryMethod("cat");
var pig = FactoryMethod("pig");
原型与继承
原型:
// 原型, 是构造函数的一个属性,值是一个对象
// 定义构造函数
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 方法要写在原型上
People.prototype.sayHello = function() {
console.log("大家好, 我的名字叫做" + this.name + ",我的年龄是" + this.age + ",我是一个" + this.sex + "孩子");
}
继承:
// 定义父类
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 父类的方法
People.prototype.sayHello = function() {
console.log("大家好, 我的名字叫做" + this.name + ",我的年龄是" + this.age + ",我是一个" + this.sex + "孩子");
}
// 定义子类
function Student(name, age, sex, grade) {
// 构造函数式继承
People.apply(this, arguments);
// 子类独有属性
this.grade = grade;
}
// 继承
// 使用类式继承
// Student.prototype = new People();
// 这种继承方式会丢失子类的原型对象
// 另外,这种继承方式会在子类的原型上多出几个无用的属性
// 我们可以使用ES5提供的Object.create方法
Student.prototype = Object.create(People.prototype);
// 补回
Student.prototype.constructor = Student;
// 子类的方法
Student.prototype.intro = function() {
console.log("大家好, 我的名字叫做" + this.name + ",我的年龄是" + this.age + ",我是一个" + this.sex + "孩子" + "我今年上" + this.grade + "年级了");
}
执行代码:
// 初始化Student
var s = new Student("小明", 12, "男", 6);
// 调用父类的方法
s.sayHello();
// 调用子类自己的方法
s.intro();
// 检测student是否是Student的实例
console.log(s instanceof Student)
// 检测student是否是People的实例
console.log(s instanceof People);
输出结果:
安全工厂
举例:
// 改造
function People(name, age, sex) {
// 判断this指向谁, 从而决定代码如何执行
if (this instanceof People) {
// 说明使用new来调用, 那么一起照常执行
this.name = name;
this.age = age;
this.sex = sex;
} else {
// 说明没有是用new 来调用, 也就是说当做普通函数来调用了, 如果普通函数想要返回一些内容要人为的return
return new People(name, age, sex);
}
}
// 测试
// 使用new 来调用构造函数
var p = new People("小明", 12, "男");
console.log(p);
// 不使用new 执行函数
var p1 = People("小强", 11, "男");
console.log(p1);
结果:
闭包类
简单来说就是将类放入闭包中
举例:
// 一个闭包
(function() {})();
// 一个类
function People() {
}
// 闭包类
(function() {
function People() {
}
})();
// 如果将类放在全局中, 别人也可以访问到, 想怎么初始化就怎么初始化
// 如果在类放在闭包中,别人就无法操作了。
单例模式
举例:
var single = (function() {
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 此时确实将People类放入闭包中, 别人也就无法来操作People了
// 但是,我们自己也无法操作
// 我们要向外暴露一个接口,让外部可以访问内部的People类
// 定义变量 用来保存单例
var instance = null;
// 返回接口函数
return function(name, age, sex) {
// 判断单例是否存在
if (!instance) {
return instance = new People(name, age, sex);
}
// 如果单例已经存在, 直接返回
return instance;
}
})();
// 外面无论如何调用, 只能返回一个实例化对象
var p = single("小明", 12, "男");
var p1 = single("小红", 11, "女");
结果:
普通单例
举例:
// 普通单例: 在定义的时候就执行的单例
var single = (function() {
// 定义类
function People(name, age, sex) {
console.log("普通单例");
this.name = name;
this.age = age;
this.sex = sex;
}
// 定义变量保存单例
var instance = new People("小明", 12, "男");
// 定义接口
return function() {
// 因为已经实例化过了, 所以就不需要再次判断了
return instance;
}
})()
惰性单例
举例:
var single = (function() {
// 定义类
function People(name, age, sex) {
console.log("惰性单例");
this.name = name;
this.age = age;
this.sex = sex;
}
// 定义变量保存单例
var instance = null;
// 定义接口函数
return function(name, age, sex) {
// 判断单例是否存在
if (!instance) {
return instance = new People(name, age, sex);
}
// 如果单例存在, 直接返回
return instance;
}
})();