一句話總結JS的設計模式

minmin520發表於2019-01-08

工廠模式

new一個建立者來批量生產商品

class Product {
	constructor (name) {
		this.name = name
	}
	init() {
		alert('init')
	}
	fun1() {
		alert('fun1')
	}
	fun2() {
		alert('fun2')
	}
}

class Creator {
	create(name) {
		return new Product(name)
	}
}

// 測試
let creator = new Creator()
let p = creator.create('p1')
p.fun1()
複製程式碼

單例模式

如果沒有建立過,就建立。否則就使用之前new的,保證只有一個例項

class SingleObject {
	login() {
		console.log('login');
	}
}


SingleObject.getInstance = (function(){
	let instance
	return function () {
		if (!instance) {
			instance = new SingleObject()
		} 
		return instance
	}
})()

let obj1 = SingleObject.getInstance()
obj1.login()

let obj2 = SingleObject.getInstance()
obj2.login()

console.log('是否是單例模式', obj1 === obj2);

let obj3 = new SingleObject()
obj3.login()


console.log('是否是單例模式', obj1 === obj3);
複製程式碼

介面卡模式

一句話總結JS的設計模式
重點在轉換方法

class Adaptee {
	specificRequest() {
		return '德國標準插頭'
	}
}

class Target {
	constructor() {
		this.adaptee = new Adaptee()
	}
	request() {
		let info = this.adaptee.specificRequest();
		return `${info} - 轉換器 - 中國標準插頭`
	}
}

// 測試
let target = new Target()
let res = target.request()

console.log(res);
複製程式碼

裝飾器模式

在不影響原來功能的基礎上新增新的功能

function log(target, name, descriptor) {
	// body...
	let oldValue = descriptor.value
	descriptor.value = function() {
		console.log(`calling ${name}`, arguments)
		return oldValue.apply(this, arguments)
	}
	return descriptor
}
class Math {
	@log
	add (a, b) {
		return a+b
	}
}

let math = new Math()
const result = math.add(2, 4)
console.log('result', result)
複製程式碼

觀察者模式

一邊設定,一邊觸發

// 觀察者模式
// 主題, 儲存狀態,狀態變化子後出發所有觀察者物件
class Subject {
    constructor(state) {
        this.state = state
        this.obervers = []
    }
    setState(state) {
        this.state = state
        this.notifyAllObervers()
    }
    getState() {
        return this.state
    }
    notifyAllObervers() {
        this.obervers.forEach(oberver => oberver.update())
    }
    attach(oberver) {
        this.obervers.push(oberver)
    }
}

class Oberver {
    constructor(name, subject) {
        this.name = name
        this.subject = subject
        this.subject.attach(this)
    }
    update() {
        console.log(`${this.name} update, state: ${this.subject.getState()}`)
    }
}
// 初始化一個主題
let subject = new Subject();
// 
let o1 = new Oberver('o1', subject);
let o2 = new Oberver('o2', subject);
let o3 = new Oberver('o3', subject);
subject.setState(2)
複製程式碼

迭代器模式

各種陣列,都能遍歷

class Interator {
    constructor(container) {
        this.container = container
        this.index = 0
    }
    next() {
        if (this.hasNaxt()) {
            console.log(this.container.list[this.index]);
            this.index ++
        }
    }
    hasNaxt() {
        if (this.index === this.container.list.length) {
            return false
        }
        return true
    }
}

class Container {
    constructor(list) {
        this.list = list
    }
    interator() {
        return new Interator(this)
    }
}

let container = new Container([1, 2, 3, 4, 5]);
let interator = container.interator()
while (interator.hasNaxt()) {
    interator.next()
}

複製程式碼

狀態模式

紅綠黃燈切換處理

class State {
    constructor(color) {
        this.color = color
    }
    handleState(context) {
        context.setState(this.color)
        console.log(`turn to ${this.color}`);
    }
}

class Context {
    constructor() {
        this.state = null
    }
    getState() {
        return this.state
    }
    setState(state) {
        this.state = state
    }
}
let context = new Context()
let green = new State('green')
let red = new State('red')
let yellow = new State('yellow')

green.handleState(context)
red.handleState(context)
yellow.handleState(context)
複製程式碼

原型模式

重點在Object.create(prototype)

const prototype = {
    getName: function () {
       return this.firstName + '-' + this.lastName
    },
    say: function () {
        alert('hello')
    }
}

// 基於原型建立x
let x = Object.create(prototype)
x.firstName = 'M'
x.lastName = 'A'
alert(x.getName())
x.say()

// 基於原型建立b
let b = Object.create(prototype)
b.firstName = 'B'
b.lastName = 'A'
alert(b.getName())
b.say()

複製程式碼

橋接模式

三角形、圓形。紅色、黃色。組合處理

class Color  {
    constructor(color) {
        this.color = color
    }
}

class Shape  {
    constructor(name, color) {
        this.name = name
        this.color = color
    }
    draw() {
        console.log(`${this.color.color}, ${this.name}`);
    }
}
let red = new Color('red')
let yellow = new Color('yellow')

let sjx = new Shape('三角形', red)
sjx.draw()

let yx = new Shape('原型', yellow)
yx.draw()
複製程式碼

策略模式

分類進行

class normalUser {
    buy() {
        console.log('普通使用者購買')
    }
}

class memberUser {
    buy() {
        console.log('會員使用者購買')
    }
}

class vipUser {
    buy() {
        console.log('VIP 使用者購買')
    }
}

let u1 = new normalUser()
u1.buy()
let m1 = new memberUser()
m1.buy()
let v1 = new vipUser()
v1.buy()
複製程式碼

命令模式

將軍傳送命令給小號手,小號手傳送命令給士兵

// 接收者
class Receiver {
    exec() {
        console.log("執行")
    }
}
// 命令者
class Command {
    constructor(receiver) {
        this.receiver = receiver
    }
    cmd () {
        console.log('執行命令')
        this.receiver.exec()
    }
}
// 觸發者
class Invoker {
    constructor(command) {
        this.command = command
    }
    invoker() {
        console.log('開始')
        this.command.cmd()
    }
}

let solider = new Receiver()
let trumper = new Command(solider)
let general = new Invoker(trumper)
general.invoker()
複製程式碼

備忘錄模式

返回、再返回

class Memento {
    constructor(content) {
        this.content = content
    }
    getContent() {
        return this.content
    }
}

// 備忘列表
class CareTaker {
    constructor() {
        this.list = []
    }
    add(memento) {
        this.list.push(memento)
    }
    get(index) {
        return this.list[index]
    }
}

// 編輯器
class Editor {
    constructor() {
        this.content = null
    }
    setContent(content) {
        this.content = content
    }
    getContent() {
        return this.content
    }
    saveContentToMemento() {
        return new Memento(this.content)
    }
    getContentFromMemento(memento) {
        this.content = memento.getContent()
    }
}

// 測試程式碼
let editor = new Editor()
let careTaker = new CareTaker()

editor.setContent('111')
editor.setContent('222')
careTaker.add(editor.saveContentToMemento())
editor.setContent('333')
careTaker.add(editor.saveContentToMemento())
editor.setContent('444')

console.log(editor.getContent())
editor.getContentFromMemento(careTaker.get(1))
editor.getContentFromMemento(careTaker.get(0))
複製程式碼

相關文章