提到设计模式,相信知道的同学都会脱口而出,五大基本原则(SOLID)和 23 种设计模式。SOLID 所指的五大基本原则分别是:单一功能原则、开放封闭原则、里式替换原则、接口隔离原则和依赖反转原则。逐字逐句诠释这五大基本原则违背了写这篇文章的初衷,引用社区大佬的理解,SOLID 可以简单概括为六个字,即“高内聚,低耦合”:
高 层模块不依赖底层模块,即为依赖反转原则。
内 部修改关闭,外部扩展开放,即为开放封闭原则。
聚 合单一功能,即为单一功能原则。
低 知识要求,对外接口简单,即为迪米特法则。
耦 合多个接口,不如独立拆分,即为接口隔离原则。
合 成复用,子类继承可替换父类,即为里式替换原则。
23种设计模式分为“创建型”、“行为型”和“结构型”。具体类型如下图:
设计模式说白了就是“封装变化”。比如“创建型”封装了创建对象的变化过程,“结构型”将对象之间组合的变化封装,“行为型”则是抽离对象的变化行为。接下来,本文将以“单一功能”和“开放封闭”这两大原则为主线,分别介绍“创建型”、“结构型”和“行为型”中最具代表性的几大设计模式。
创建型
工厂模式
工厂模式根据抽象程度可分为三种,分别为简单工厂、工厂方法和抽象工厂。其核心在于将创建对象的过程封装其他,然后通过同一个接口创建新的对象。 简单工厂模式又叫静态工厂方法,用来创建某一种产品对象的实例,用来创建单一对象。
// 简单工厂
class Factory {
constructor (username, pwd, role) {
this.username = username;
this.pwd = pwd;
this.role = role;
}
}
class CreateRoleFactory {
static create (username, pwd, role) {
return new Factory(username, pwd, role);
}
}
const admin = CreateRoleFactory.create('张三', '222', 'admin');
复制代码
在实际工作中,各用户角色所具备的能力是不同的,因此简单工厂是无法满足的,这时候就可以考虑使用工厂方法来代替。工厂方法的本意是将实际创建对象的工作推迟到子类中。
class User {
constructor (name, menuAuth) {
if (new.target === User) throw new Error('User 不能被实例化');
this.name = name;
this.menuAuth = menuAuth;
}
}
class UserFactory extends User {
constructor (...props) {
super(...props);
}
static create (role) {
const roleCollection = new Map([
['admin', () => new UserFactory('管理员', ['首页', '个人中心'])],
['user', () => new UserFactory('普通用户', ['首页'])]
])
return roleCollection.get(role)();
}
}
const admin = UserFactory.create('admin');
console.log(admin); // {name: "管理员", menuAuth: Array(2)}
const user = UserFactory.create('user');
console.log(user); // {name: "普通用户", menuAuth: Array(1)}
复制代码
随着业务形态的变化,一个用户可能在多个平台上同时存在,显然工厂方法也不再满足了,这时候就要用到抽象工厂。抽象工厂模式是对类的工厂抽象用来创建产品类簇,不负责创建某一类产品的实例。
class User {
constructor (hospital) {
if (new.target === User) throw new Error('抽象类不能实例化!');
this.hospital = hospital;
}
}
// 浙一
class ZheYiUser extends User {
constructor(name, departmentsAuth) {
super('zheyi_hospital')