JavaScript设计模式

2018-09-03  本文已影响28人  阿昕_

前言

以下代码以及结合设计模式所做的案例请移步github:
https://github.com/webxing/design_patterns

设计原则

单一职责原则
开放封闭原则
李氏置换原则
接口独立原则
依赖倒置原则

工厂模式

示例
UML类图
工厂模式
代码
class Product {
    constructor(name) {
        this.name = name
    }
    init() {
        console.log('init')
    }
    fn1() {
        console.log('fn1')
    }
    fn2() {
        console.log('fn2')
    }
}
class Creator {
    create(name) {
        return new Product(name)
    }
}

let creator = new Creator()
let p = creator.create('兰州拉面')
p.init()
p.fn1()
设计原则

单例模式

示例
代码
class LoginForm {
   constructor() {
       this.state = 'hide'
   }
   show() {
       if (this.state === 'show') {
           console.log('has been show')
           return
       }
       this.state = 'show'
       console.log('show success')
   }
   hide() {
       if (this.state === 'hide') {
           console.log('has been hide')
           return
       }
       this.state = 'hide'
       console.log('hide success')
   }
}
LoginForm.getInstance = (function() {
   let instance = null
   return function() {
       if (!instance) {
           instance = new LoginForm()
       }
       return instance
   }
})()
let login1 = LoginForm.getInstance()
login1.show()

let login2 = LoginForm.getInstance()
login2.hide()

console.log(login1 === login2)
设计原则

适配器模式

示例
UML类图
适配器模式
代码
// 适配器模式
class Adapter {
    specialRequest() {
        return '香港电压'
    }
}
class Target {
    constructor() {
        this.adapter = new Adapter()
    }
    request() {
        let info = this.adapter.specialRequest()
        return `${info} --转换器-- 中国电压`
    }
}
let target = new Target()
let res = target.request()
console.log(res)
设计原则

代理模式

示例
UML类图
代理模式
代码
// 代理模式
class RealImg {
    constructor(fileName) {
        this.fileName = fileName
        this.loadFromDisk() // 模拟加载图片
    }
    display() {
        console.log('display...' + this.fileName)
    }
    loadFromDisk() {
        console.log('loadFromDisk...' + this.fileName)
    }
}
class ProxyImg {
    constructor(fileName) {
        this.realImg = new RealImg(fileName)
    }
    display() {
        this.realImg.display()
    }
}
let proxyImg = new ProxyImg('1.png')
proxyImg.display()
// ES6 经纪人
let star = {
    name: 'lx',
    age: 22,
    phone: 'star: 166111100006'
}
let agent = new Proxy(star, {
    get: function(target, key) {
        if (key === 'phone') {
            return 'agent: 1661786543'
        }
        if (key === 'price') {
            return 200000
        }
        return target[key]
    },
    set: function(target, key, value) {
        if (key === 'customPrice') {
            if (value < 200000) {
                console.log('too Low')
            } else {
                target[key] = value
                return true
            }
        }
    }
})
console.log(agent.name)
console.log(agent.age)
console.log(agent.phone)
console.log(agent.price)
agent.customPrice = 300000
console.log(agent.customPrice)
设计原则

装饰器模式

示例
UML类图
装饰器模式
代码
// 装饰器模式
class Circle {
    draw() {
        console.log('画一个圆形')
    }
}
class Decorator {
    constructor(circle) {
        this.circle = circle
    }
    draw() {
        this.circle.draw()
        this.setRedBorder(circle)
    }
    setRedBorder(circel) {
        console.log('设置红色边框')
    }
}
let circle = new Circle()
let decorator = new Decorator(circle)
decorator.draw()
// ES7 装饰器
@decoratorA
class A{}

function decoratorA(target) {
    target.isDec = true
}
console.log(A.isDec)

@decoratorB(false)
class B{}

function decoratorB(isDec) {
    return function(target) {
        target.isDec = isDec
    }
}
console.log(B.isDec)
// mixin装饰类
function mixin(...list) {
   return function(target) {
       Object.assign(target.prototype, ...list)
   }
}
const Foo = {
   foo() {
       console.log('foo')
   }
}
@mixin(Foo)
class MyClass {}
let obj = new MyClass()
obj.foo()
// readonly
function readonly(target, name, descriptor) {
    console.log(target, name, descriptor)
    descriptor.writable = false
    return descriptor
}
class Person {
    constructor() {
        this.first = '刘'
        this.last = '昕'
    }
    @readonly
    name() {
        console.log( `${this.first} ${this.last}` )
    }
}
let person = new Person()
person.name()
// person.name = function() {}
console.log(person)
// log
function log(target, name, descriptor) {
    console.log(target, name, descriptor)
    let oldValue = descriptor.value
    descriptor.value = function() {
        console.log(`calling f ${name}... `, arguments)
        return oldValue.apply(this, arguments)
    }
    return descriptor
}
class Math {
    @log
    add(a, b) {
        return a + b
    }
}
let math = new Math()
let addRes = math.add(1, 2)
console.log(addRes)
// core-decorators
import {readonly} from 'core-decorators'
class C {
    @readonly
    name() {
        console.log('lx')
    }
}
let c = new C()
c.name()
// c.name() = function(){}
设计原则

观察者模式

示例
UML类图
观察者模式
代码
// 观察者模式
class Subject {
    constructor() {
        this.state = 0
        this.observers = []
    }
    getState() {
        return this.state
    }
    setState(state) {
        this.state = state
        this.notifyObservers()
    }
    notifyObservers() {
        this.observers.forEach(observer => {
            observer.update()
        })
    }
    attach(observer) {
        this.observers.push(observer)
    }
}
class Observer {
    constructor(name, subject) {
        this.name = name
        this.subject = subject
        this.subject.attach(this)
    }
    update() {
        console.log(this.name + ' has been update,' + this.subject.getState())
    }
}

let subject = new Subject()
for(let i = 0; i< 10; i++) {
    new Observer(i, subject)
}
subject.setState(10)
设计原则

迭代器模式

UML类图
迭代器模式
代码
// 迭代器模式
class Iterator {
    constructor(container) {
        this.list = container.list
        this.index = 0
    }
    next() {
        if (this.hasNext()) {
            return this.list[this.index++]
        }
        return null
    }
    hasNext() {
        if (this.index >= this.list.length) {
            return false
        }
        return true
    }
}
class Container {
    constructor(list) {
        this.list = list
    }
    getIterator() {
        return new Iterator(this)
    }
}

let arr = [1, 2, 3]
let container = new Container(arr)
let iterator = container.getIterator()
while(iterator.hasNext()) {
    console.log(iterator.next())
}
// ES6 Iterator
let iterator = arr[Symbol.iterator]()
let item = { done: false}
while (!item.done) {
    item = iterator.next()
    if(item.value) {
        console.log(item.value)
    }
}

// for..of  遍历迭代器
for (let item of arr) {
    console.log(item)
}
设计原则

状态模式

示例
UML类图
状态模式
代码
// 状态模式
class State {
    constructor(color) {
        this.color = color
    }
    handle(context) {
        console.log('turn to ' + this.color)
        context.setState(this)
    }
}
class Context {
    constructor() {
        this.state = null
    }
    getState() {
        return this.state
    }
    setState(state) {
        this.state = state
    }
}
let context = new Context()
let green = new State('green')
green.handle(context)
console.log(context.getState())
// 有限状态机
import StateMachine from 'javascript-state-machine'
let fsm = new StateMachine({
    init: '收藏',
    transitions: [
        {
            name: 'doStore',
            from: '收藏',
            to: '取消收藏'
        },
        {
            name: 'deleteStore',
            from: '取消收藏',
            to: '收藏'
        }
    ],
    methods: {
        onDoStore() {
            console.log('收藏了')
            updateText()
        },
        onDeleteStore() {
            console.log('取消收藏了')
            updateText()
        }
    }
})
let dom = document.querySelector('p')
dom.onclick = function() {
    if (fsm.is('收藏')) {
        fsm.doStore()
    } else {
        fsm.deleteStore()
    }
}
function updateText() {
    dom.innerHTML = fsm.state
}
updateText()
// 有限状态机 promise
import StateMachine from 'javascript-state-machine'
let fsm = new StateMachine({
    init: 'pending',
    transitions: [
        {
            name: 'resolve',
            from: 'pending',
            to: 'fullfilled'
        },
        {
            name: 'reject',
            from: 'pending',
            to: 'rejected'
        }
    ],
    methods: {
        onResolve(state, data) {
            data.successList.forEach(fn => fn())
        },
        onReject(state, data) {
            data.failList.forEach(fn => fn())
        }
    }
})

class MyPromise {
    constructor(fn) {
        this.successList = []
        this.failList = []

        fn(() => {
            fsm.resolve(this)
        }, () => {
            fsm.reject(this)
        })
    }
    then(successFn, failFn) {
        this.successList.push(successFn)
        this.failList.push(failFn)
    }
}

function loadImg(src) {
    const promise = new MyPromise(function(resolve, reject) {
        let img = document.createElement('img')
        img.onload = function() {
            resolve(img)
        }
        img.onerror = function() {
            reject()
        }
        img.src = src   
    })
    return promise
}
let result = loadImg('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1535887490282&di=8e030a963f1cdf657713aedfe0eda25f&imgtype=0&src=http%3A%2F%2Fnpic7.fangtoo.com%2Fcn%2Fzixun%2Fzh-chs%2F2017-10%2F27%2F354172-2017102710051570.jpg')
result.then(function() {
    console.log('加载成功')
}, function() {
    console.log('加载失败')
})
设计原则

原型模式

示例
代码
// 原型模式
const prototype = {
    getName: function() {
        return this.first + ' ' + this.last
    },
    say: function() {
        console.log('hello')
    }
}
let x = Object.create(prototype)
x.first = 'X'
x.last = 'x'
console.log(x.getName())

let y = Object.create(prototype)
y.first = 'Y'
y.last = 'y'
console.log(y.getName())

桥接模式

代码
// 桥接模式
class Draw {
    constructor(type, color) {
        this.type = type
        this.color = color.name
    }
    draw() {
        console.log(`draw a ${this.type} with ${this.color} color`)
    }
}
class Color {
    constructor(name) {
        this.name = name
    }
}
let red = new Color('red')
let blue = new Color('blue')
let rect = new Draw('rect', red)
let circ = new Draw('circ', blue)
rect.draw()
circ.draw()
设计原则

组合模式

示例
设计原则

享元模式

设计原则

策略模式

代码
class OrdinaryUser {
    buy() {
        console.log('普通用户')
    }
}
class MemberUser {
    buy() {
        console.log('会员用户')
    }
}
class VipUser {
    buy() {
        console.log('vip用户')
    }
}
let u1 = new OrdinaryUser()
u1.buy()
let u2 = new MemberUser()
u2.buy()
let u3 = new VipUser()
u3.buy()
设计原则

职责链模式

代码
// 职责链模式
class Action {
    constructor(name) {
        this.name = name
        this.nextAction = null
    }
    setNextAction(action) {
        this.nextAction = action
        return action
    }
    handle() {
        console.log(this.name + '====审批')
        if (this.nextAction != null) {
            this.nextAction.handle()
        }
    }
}
let a1 = new Action('组长')
let a2 = new Action('经理')
let a3 = new Action('总裁')
a1.setNextAction(a2).setNextAction(a3)
a1.handle()
设计原则

命令模式

示例
代码
// 命令模式
class Receiver {
    exec() {
        console.log('执行 exec')
    }
}
class Command {
    constructor(receiver) {
        this.receiver = receiver
    }
    cmd() {
        this.receiver.exec()
    }
}
class Invoke {
    constructor(command) {
        this.command = command
    }
    exec() {
        this.command.cmd()
    }
}
let receiver = new Receiver()
let command = new Command(receiver)
let invoke = new Invoke(command)
invoke.exec()
设计原则

备忘录模式

代码
// 备忘录模式
class Momento { // 备忘类
    constructor(content) {
        this.content = content
    }
    getContent() {
        return this.content
    }
}
class CareTaker { // 备忘列表
    constructor() {
        this.list = []
    }
    add(momento) {
        this.list.push(momento)
    }
    get(index) {
        return this.list[index]
    }
}
class Editor {
    constructor() {
        this.content = null
    }
    setContent(content) {
        this.content = content
    }
    getContent() {
        return this.content
    }
    saveContentToMomento() {
        return new Momento(this.content)
    }
    getContentFromMomento(momento) {
        this.content = momento.getContent()
    }
}
let editor = new Editor()
let caretaker = new CareTaker()

editor.setContent('1111')
editor.setContent('2222')
caretaker.add(editor.saveContentToMomento()) // 备份当前内容
editor.setContent('3333')
caretaker.add(editor.saveContentToMomento()) // 备份当前内容
editor.setContent('4444')
console.log(editor.getContent())

editor.getContentFromMomento(caretaker.get(1)) // 撤销
console.log(editor.getContent())
editor.getContentFromMomento(caretaker.get(0)) // 撤销
console.log(editor.getContent())
设计原则

中介者模式

代码
// 中介者模式
class A1 {
    constructor() {
        this.number = 0
    }
    setNumber(num, m) {
        this.number = num
        if (m) {
            m.setB()
        }
    }
}
class B1 {
    constructor() {
        this.number = 0
    }
    setNumber(num, m) {
        this.number = num
        if (m) {
            m.setA()
        }
    }
}
class Mediator {
    constructor(a, b) {
        this.a = a
        this.b = b
    }
    setA() {
        let number = this.b.number
        this.a.setNumber(number)
    }
    setB() {
        let number = this.a.number
        this.b.setNumber(number)
    }
}

let a = new A1()
let b= new B1()
let mediator = new Mediator(a, b)
a.setNumber(1000, mediator)
console.log(a, b)
b.setNumber(100, mediator)
console.log(a, b)
设计原则
上一篇 下一篇

猜你喜欢

热点阅读