一、七大设计原则
“高内聚、低耦合”
原则名称 | 解释 | 使用情况 |
---|---|---|
单一职责原则 | 一个类只负责一项职责 | 当功能较为复杂就拆分,使每个部分保持独立 |
开放封闭原则 | 对拓展开放,对修改封闭 | 增加新需求氏,扩展新代码,而非修改已有代码 |
里氏置换原则 | 子类能覆盖父类,父类能出现的地方子类也能 | 继承时,在子类中尽量不要重写父类的方法 |
接口独立原则 | 保持接口的单一独立,避免出现“胖接口” | 依赖某个接口,就应该实现里面所有抽象方法 |
依赖导致原则 | 面向接口编程,依赖于抽象而不依赖于具体 | JS中使用较少(没有接口&弱类型) |
合成复用原则 | 尽量使用组合/聚合的方式,而不是继承 | 减少耦合 |
依赖导致原则 | 一个对象应该对其他对象保持最少的了解 | 用某个方法,只需了解这个方法,其他保持透明 |
二、常见的设计模式
1、单例模式
原理:保证一个类仅有一个实例,并提供一个访问它的全局访问点
实现:先判断实例是否存在;存在则直接返回,不返回就创建一个实例再返回;确保只有一个实例
适用场景:一个单一对象,如弹窗
缺点:不适用动态扩展对象,或需创建多个相似对象的场景
2、装饰者模式
原理:在不改变对象自身的基础上,在程序运行期间给对象动态地添加方法
适用场景:原因方法维持不变,在原有方法上再挂载其他方法来满足现有要求;
var horribleCode = function(){
console.log(’我是一堆你看不懂的老逻辑')
}
var _horribleCode = horribleCode
horribleCode = function() {
_horribleCode()
console.log('我是新的逻辑')
}
horribleCode()
3、构造器模式
当新建对象的内存被分配后,用来初始化对象的特殊函数,就叫做构造器;在JavaScript中,我们使用构造函数去初始化对象,就是应用了构造器模式
4、工厂模式
将创建对象的过程单独封装
应用场景:有构造函数的地方、写了大量构造函数、调用了大量的 new的情况下
function Carnivore (name,age) {
this.name = name
this.age = age
this.favorite = 'meat'
this.food = [beef, pork]
}
function Vegetarian(name,age) {
this.name = name
this.age = age
this.favorite = 'fruit'
this.food = [apple, banaba]
}
//工厂模式创建实例,根据favorite的不同创建不同的实例
function Factory(name, age, favorite) {
switch(career) {
case 'fruit':
return new Vegetarian(name, age)
break
case 'meat':
return new Carnivore(name, age)
break
...
}
5、适配器模式
作用:解决两个软件实体键的接口不兼容的问题;使用适配器后,原本由于接口不兼容而不能工作的两个软件实体可以一起工作
比如:京东和淘宝商品价格的属性名不一样
class Taobao() {
getTbPice() {
console.log('在淘宝上商品的价格')
return {tbPrice:xx}
}
}
class Jingdong() {
getJdPice() {
console.log('在京东上商品的价格')
return {jdPrice:xx}
}
}
class TabobaoAdapter() {
getPrice () {
const t = new Taobao()
return { price:t.tbrice}
}
}
class JingdongAdapter() {
getPrice () {
const j = new Jingdong()
return { price:j.jdPrice}
}
}
//通过适配器拿到的数据格式都是统一的 {price:xx},入参也可以在适配器中统一处理
6、代理模式
定义:为其他对象提供一种代理以控制对这个对象的访问;代理模式使得代理对象控制具体对象的引用;代理可以使任何对象
// 先声明美女对象
var girl = function (name) {
this.name = name;
};
// 这是dudu
var dudu = function (girl) {
this.girl = girl;
this.sendGift = function (gift) {
alert("Hi " + girl.name + ", dudu送你一个礼物:" + gift);
}
};
// 大叔是代理
var proxyTom = function (girl) {
this.girl = girl;
this.sendGift = function (gift) {
(new dudu(girl)).sendGift(gift); // 替dudu送花咯
}
};
//使用
var proxy = new proxyTom(new girl("一个美女"));
proxy.sendGift("999朵玫瑰");