封装的好处:封装的优势在于定义只可以在类内部进行对属性的操作,外部无法指手画脚。 要想修改,也只能通过你定义的封装方法。
一、设计原则
-
单一职责原则:就一个类而言,只有一个引起它变化的原因。
-
开放封闭原则:核心的思想是软件实体(类、模块、函数等)是可扩展的、但不可修改的。 即对扩展是开放的,对修改是封闭的。
工厂模式
工厂模式是将逻辑封装在一个函数中不暴露创建对象的具体逻辑。
class Person {
constructor(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
sayName(){
console.log(`我叫 ${this.name},性别 ${this.sex},今年 ${this.age}`);
}
}
const p1 = new Person('jsliang', 25, '男');
const p2 = new Person('靓女', 25, '女');
p1.sayName(); // 我叫 jsliang,性别 男,今年 25
p2.sayName(); // 我叫 靓女,性别 女,今年 25
小结
工厂模式是为了解决对个类似对象声明的问题,也就是为了解决实例化对象产生重复的问题。
工厂模式的优缺点:
-
优点:能解决对个相似的问题。
-
缺点:对象的类型不知道。
单例模式
单例模式即一个类只能构造出唯一实例,单例模式的意义在于共享、唯一。 Redux/Vuex 中的 Store、jQuery 的 $ 或者业务场景中的购物车、登录框都是单例模式的应用。
class SingletonLogin {
constructor(name, password) {
this.name = name;
this.password = password;
}
static getInstance(name, password) {
// 判断对象是否已经被创建,若创建则返回旧对象
if (!this.instance) {
this.instance = new SingletonLogin(name, password);
}
return this.instance;
}
}
let obj1 = SingletonLogin.getInstance('jsliang', '123456')
let obj2 = SingletonLogin.getInstance('zhazhaliang', '654321')
console.log(obj1 === obj2) // true
console.log(obj1) // SingletonLogin { name: 'jsliang', password: '123456' }
console.log(obj2) // SingletonLogin { name: 'jsliang', password: '123456' }
代理模式和中介者模式
代理模式适用场景:
代理模式的适用场景是图片的预加载,在预加载过程中,图片未加载完毕之前,用一个 loading 作为图片的占位符,等待加载完毕之后再进行赋值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>代理模式</title>
</head>
<body>
<div class="animation">动画元素</div>
<script>
window.onload = function () {
var myImage = (function () {
var imgNode = document.createElement("img");
document.body.appendChild(imgNode);
return {
setSrc: function (src) {
imgNode.src = src;
}
}
})();
// 代理模式
var ProxyImage = (function () {
var img = new Image();
img.onload = function () {
myImage.setSrc(this.src);
};
return {
setSrc: function (src) {
myImage.setSrc("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603709264332&di=f6f8e48c1c88bf640aac9899df98a97c&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fq_mini%2Cc_zoom%2Cw_640%2Fimages%2F20171107%2F643ceb1031394c5887d3509b31878c52.gif");
setTimeout(() => {
img.src = src;
}, 3000);
}
}
})();
// 调用方式
ProxyImage.setSrc("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3592308877,3684082784&fm=26&gp=0.jpg");
};
</script>
</body>
</html>
发布订阅模式(观察这模式)
当一个对象发生改变时,所有依赖于它的对象都将得到通知。 发布-订阅模式的优缺点:
- 优点
- 支持简单的广播通信。当对象状态发生改变时,会自动通知已经订阅过的对象。
2 . 发布者与订阅者的耦合性降低。我是卖家我并不关心有多少人订阅了, 我只要到货的时候,将货物数量更改下就行了。
- 缺点
- 耗时耗内存。创建订阅者需要消耗一定的时间和内存
- 过度使用不好维护。
举个代码小例子,然后讲讲 Vue 中的 Object.defineProperty 和 Proxy 使用。
那么,为什么 Vue 3.0 要换成 Proxy 呢?
Object.defineProperty 缺点:
-
不能监听数组变化
-
必须遍历对象每个属性 而 Proxy 的目标是对象,这样就省去了属性的遍历。