创建型设计模式
单例模式
class Person {
constructor(name, age) {
if (!Person.instance) {
this.name = name
this.age = age
Person.instance = this
}
return Person.instance
}
}
const p1 = new Person('张三', 18)
const p2 = new Person('李四', 20)
// Person { name: '张三', age: 18 } Person { name: '张三', age: 18 }
console.log(p1, p2)
原型模式
// 通过Object.create克隆一个一模一样的新对象
class Person {
constructor(name) {
this.name = name
}
say() {
return `I am ${this.name}`
}
}
const p = new Person('大p')
const p1 = Object.create(new Person())
// Person { name: '大p' } Person { name: '小p', age: 18 } I am 小p
p1.name = '小p'
p1.age = 18
console.log(p, p1, p1.say())
简单工厂模式
class Iphone {
showname() {
return 'i am iphone'
}
}
class Huawei {
showname() {
return 'i am huawei'
}
}
class PhoneFactory {
static createPhone(type) {
switch (type) {
case 'iphone':
return new iphone()
case 'huawei':
return new huawei()
default:
throw new Error('no this type')
}
}
}
// i am iphone i am huawei
const iphone1 = PhoneFactory.createPhone('Iphone')
const huawei1 = PhoneFactory.createPhone('Huawei')
console.log(iphone1.showname(), ' ', huawei1.showname())
工厂方法模式
class Factory {
constructor(phone) {
if (this instanceof Factory && this[phone]) {
return new this[phone]()
} else {
return console.log(`没有${phone}这个手机`)
}
}
}
Factory.prototype.ipone = class {
showname() {
return 'i am iphone'
}
}
// i am iphone
const iphone = new Factory('ipone')
console.log(iphone.showname())
策略模式
// 避免过多的if...else
// function validator(value) {
// if (!/\d+/.test(value)) {
// console.log("请输入数字");
// } else if (value === || !value) (
// console.log("不可为空"");
// // else if...
const myRule = {
isNumber: val => typeof val === 'number',
notNull: val => val !== '' && val !== null
}
const validator = (value, rules) => rules.every(rule => myRule[rule](value))
// false
console.log(validator('111', ['notNull', 'isNumber']))
建造者模式
// 使用建造者模式构建复杂对象
// 产品(Product)
class Car {
constructor() {
this.parts = []
}
addPart(part) {
this.parts.push(part)
}
showInfo() {
return this.parts.join(',')
}
}
// 建造者(Builder)
class CarBuilder {
constructor() {
this.car = new Car()
}
addFrame() {
this.car.addPart('frame')
return this
}
addEngine() {
this.car.addPart('engine')
return this
}
addWheel() {
this.car.addPart('wheel')
return this
}
getCar() {
return this.car
}
}
// 指挥者(Director)
class Director {
constructor(builder) {
this.builder = builder
}
build() {
return this.builder.addFrame().addEngine().addWheel().getCar()
}
}
const car = new Director(new CarBuilder()).build()
// frame,engine,wheel
console.log(car.showInfo())
结构型设计模式
桥接模式
class Toast {
constructor(ani) {
this.ani = ani
}
show() {
this.ani.show()
}
hide() {
this.ani.hide()
}
}
class Message {
constructor(ani) {
this.ani = ani
}
show() {
this.ani.show()
}
hide() {
this.ani.hide()
}
}
const animation = {
bounce: {
show() {
console.log('bounce show')
},
hide() {
console.log('bounce hide')
}
},
side: {
show() {
console.log('side show')
},
hide() {
console.log('side hide')
}
}
}
const toast1 = new Toast(animation.side)
const message1 = new Message(animation.bounce)
toast1.show()
toast1.hide()
message1.show()
message1.hide()
外观模式
const drawCircle = () => console.log('drawCircle')
const drawRect = () => console.log('drawRect')
const drawTriangle = () => console.log('drawTriangle')
class ShapeMaker {
constructor() {
this.drawCircle = drawCircle
this.drawRect = drawRect
this.drawTriangle = drawTriangle
}
}
const maker = new ShapeMaker()
maker.drawCircle()
maker.drawRect()
maker.drawTriangle()
享元模式
// 享元
class Icon {
constructor(type) {
this.type = type
}
draw(x, y) {
console.log(`绘制${this.type}图标,坐标为(${x}, ${y})`)
}
}
// 享元工厂
class IconFactory {
constructor() {
this.icons = {}
}
createIcon(type) {
if (!this.icons[type]) {
this.icons[type] = new Icon(type)
}
return this.icons[type]
}
getIconCount() {
return Object.keys(this.icons).length
}
}
// 绘制多个图标
const iconFactory = new IconFactory()
iconFactory.createIcon('heart').draw(10, 10)
iconFactory.createIcon('star').draw(20, 20)
iconFactory.createIcon('heart').draw(30, 30)
iconFactory.createIcon('star').draw(40, 40)
console.log(iconFactory.getIconCount())
适配器模式
const sqare = x => x * x
// 适配器, 以适配sqare方法
const sqareString = x => {
const num = parseInt(x)
return sqare(num)
}
console.log(sqareString('16'))
组合模式
// 允许将对象组合成树形结构
// 以统一的方式处理单个对象和对象的组合
class Component {
constructor(name) {
this.name = name
this.children = []
}
addChildren(component) {
this.children.push(component)
}
}
const processTree = component => {
console.log(component.name)
component.children.forEach(child => {
processTree(child)
})
}
const root = new Component('root')
const child1 = new Component('child1')
const child2 = new Component('child2')
const child3 = new Component('child3')
root.addChildren(child1)
root.addChildren(child2)
child2.addChildren(child3)
processTree(root)
装饰模式
// 在不改变对象结构的情况下,动态的为对象添加额外功能
const op = x => x * 2
const decorate = fn => {
return x => {
const res = fn(x)
return res + 10
}
}
const fn = decorate(op)
console.log(fn(5)) // 20
发布订阅模式
const eventBus = {
topics: {},
subscribe: function (topic, listener) {
if (!this.topics[topic]) {
this.topics[topic] = []
}
this.topics[topic].push(listener)
},
publish: function (topic, data) {
if (this.topics[topic]) {
this.topics[topic].forEach(listener => {
listener(data)
})
}
}
}
const subscribe1 = eventBus.subscribe('topic1', data => {
console.log('subscribe1', data)
})
const subscribe2 = eventBus.subscribe('topic2', data => {
console.log('subscribe2', data)
})
eventBus.publish('topic1', 'hello topic1')
eventBus.publish('topic2', 'hello topic2')
迭代器设计模式
// 将遍历操作抽离出来
const eachFn = (arr, fn) => {
for (let i = 0; i < arr.length; i++) {
fn(arr[i])
}
}
let sum = 0
let count = 0
eachFn([1, 2, 3, 4, 5], item => {
sum += item
count++
})
console.log(sum)
console.log(count)
模板方法模式
// 将公共部分抽取到父类
class BasicInfo {
setSize() {}
setColor() {}
showInfo() {
this.setSize()
this.setColor()
}
}
class Phone extends BasicInfo {
constructor() {
super()
this.size = 5
this.color = 'red'
}
setSize() {
console.log(`size: ${this.size}`)
}
setColor() {
console.log(`color: ${this.color}`)
}
}
const phone = new Phone()
phone.showInfo()
状态模式
// 将不同的状态封装成独立的类
// 并定义一个公共接口来统一他们的行为
class LightState {
constructor(light) {
this.light = light
}
pressSwitch() {
throw new Error('子类需要重写pressSwitch方法')
}
}
class OnLightState extends LightState {
constructor(light) {
super(light)
}
pressSwitch() {
console.log('关灯')
this.light.setState(this.light.offLightState)
}
}
class OffLightState extends LightState {
constructor(light) {
super(light)
}
pressSwitch() {
console.log('开灯')
this.light.setState(this.light.onLightState)
}
}
class Light {
constructor() {
this.onLightState = new OnLightState(this)
this.offLightState = new OffLightState(this)
this.currentState = this.offLightState
}
setState(state) {
this.currentState = state
}
pressSwitch() {
this.currentState.pressSwitch()
}
}
const light = new Light()
light.pressSwitch()
light.pressSwitch()
light.pressSwitch()
命令模式
// 将请求或操作封装成独立的对象,降低耦合度
class Light {
on() {
console.log('light on')
}
off() {
console.log('light off')
}
}
const lightOnCommand = light => {
return () => light.on()
}
const lightOffCommand = light => {
return () => light.off()
}
class RemoteControl {
constructor(command) {
this.command = command
}
execute() {
this.command()
}
}
const light = new Light()
const lightOn = lightOnCommand(light)
const lightOff = lightOffCommand(light)
const remoteControl = new RemoteControl()
remoteControl.command = lightOn
remoteControl.execute()
remoteControl.command = lightOff
remoteControl.execute()