#本文来源于《javascript设计模式核心原理与实战》观后感,仅用于记录个人理解,如有问题请大佬指出。 其实设计模式并不是什么玄奥的东西,我们都学过勾股定理吧,当我们计算三角形时,会直接拿来用,而不是先推演得出勾股定理,设计模式就是如此,遇到适合场景时,直接拿过来用。学习此节不仅可以理解设计模式,还可以更加深入了解对象,函数,构造函数添加属性,把原本的函数封装进对象,再用实例去调用,更加深入理解面向对象的过程。
核心思想:分离变与不变,让固定的东西稳固,让变的东西灵活,方便后续添加
##工厂模式,场景:遇到需要创建很多类的情况
`原来的需求:录入员工信息,就需要我们根据职位创建多个类
function Coder(name, age) {
this.name = name
this.age = age
this.career = 'coder'
this.work = ['写代码', '写系分', '修Bug']
}
function ProductManager(name, age) {
this.name = name
this.age = age
this.career = 'product manager'
this.work = ['订会议室', '写PRD', '催更']
}
function Factory(name, age, career) {
switch (career) {
case 'coder':
return new Coder(name, age)
break
case 'product manager':
return new ProductManager(name, age)
break ...
}`
使用工厂模式,我们先封装不变的东西,再封装改变的东西
`//首先封装不变
class Factory {
constructor(name,age,career,work) {
this.name = name;
this.age = age;
this.career = career;
this.work = work;
}
}
//再封装后面随时可能变更的需要加入的诉求
function change(name,age,career){
var work;
switch(career){
case "coder" :
work = ['写代码', '写系分', '修Bug']
break
case "product manager" :
work = ['订会议室', '写PRD', '催更']
break
default :
alert("I don't know such work")
}
return new Factory(name,age,career,work)
}`
##单例模式:创建唯一(这个模式就更像一个工具了) `
//使用闭包
function Onlyy() {
this.test = function () {
console.log('---')
}
arguments.callee.prototype.tt = 33
}
//使用闭包,创建一个只有本函数可以访问的私有变量,不会发生下面的问题
let getOnlyInstance = (function(){
let instance = null;
return function (){
if(!instance){
return instance = new Onlyy()
}
return instance
}
})()
let one = getOnlyInstance()
let two = getOnlyInstance()
console.log(one === two)
//下面用的是全局变量tt,但是全局变量有可能会被污染,被其他地方误使用,所以用闭包比较好
// let tt = null;
// function getOnlyInstance() {
// if (!tt) {
// return tt = new Onlyy()
// }
// return tt
// }
// let one = getOnlyInstance()
// let two = getOnlyInstance()
// console.log(one === two)`
`//使用es6的类,其中有静态方法static
class Only {
constructor() {
this.test = function () {
console.log('---')
}
}
static getInstance() {
//构造函数.instance,因为构造函数也是对象,可以添加私有的属性,
//同时new之后还无法访问到此属性(这里需要你理解new的过程)
if (!Only.instance) {
Only.instance = new Only()
}
return Only.instance
}
}
Only.getInstance() //就可以创建唯一实例了`
##装饰器模式:“在不改变原对象的基础上,通过对其进行包装拓展,使原有对象可以满足用户的更复杂需求”。 对它已有的功能做个拓展,只关心拓展出来的那部分新功能如何实现
`//举个例子
document.getElementById('btn').addEventListener("click",function (){
// 原来的逻辑代码封装到一个函数中
beforeFn()
nowFn()
})`
##适配器模式:把一个类的接口变换成客户端所期待的另一种接口
`//例如我们之前用的ajax,现在想用封装好的axios、fech了,
//但是老业务盘根错节,传入的参数不好改变,我们不改变之前的传参方式,只需要用一个函数适配就可以了
//下面是草图
function demo(old1,old2,old3,...old4){
//下面加以甄别,如何选用新的方式
if(xxx){
axios.get(yyy)
}
}`
##工厂模式-抽象工厂:这个模式对于简单业务可能没有啥实质帮助,也确实很抽象,(我都不好去形容它)但是 抽象工厂, 极大的体现着设计模式的核心思想:对拓展开放,对修改封闭。同时也可以更好的体会面向对象。
`//上代码
//抽象工厂,下面范例:假如我们想要做一款手机,但目前啥也不知道,我只知道做手机得需要系统和硬件
//硬件hardware,系统os
//抽象类只用于限制,约束,创建抽象根类
class Phone{
createOs(){
throw new Error("我只是用来限制的,你得创建具体系统")
}
createHardware(){
throw new Error("我只是用来限制的,你得创建具体硬件")
}
}
//终于,我想好了,我要做安卓手机
class Factory extends Phone{
createOs(){
return new AndroidOs()
}
createHardware(){
return new AndroidHardware()
}
}
//创建具体产品功能的抽象类,也起约束作用
class Os{
androidOs(){
throw new Error("我只是用来限制的,你得创建具体安卓系统")
}
appleOs(){
throw new Error("我只是用来限制的,你得创建具体苹果系统")
}
}
//创建具体产品的具体类
class AndroidOs extends Os{
androidOs(){
console.log("安卓操作系统去操作")
}
}
//也会有苹果等具体系统类,此处就省略不写了
//创建抽象的硬件类
class Hardware{
andriodHardware(){
throw new Error("我只是用来限制的,你得创建具体安卓硬件")
}
appleHardware(){
throw new Error("我只是用来限制的,你得创建具体苹果硬件")
}
}
//创建具体硬件类
class AndroidHardware extends Hardware{
andriodHardware(){
console.log("用安卓硬件去运行")
}
}
//////////////////////////////
//需要使用时,只需要调用具体类
//1.我要造手机
var fetruePhone = new Factory()
//造安卓手机
var ananOs = feture.createOs()
var ananHardware = feture.createHardware()
//运行起来
ananOs.androidOs()
ananHardware.andriodHardware()`
##还有比较重要的观察者模式,那个在我的vue响应式原理里面有记录。