1. 单体单例模式
单体单例模式:一个构造函数,无所使用多少次 new
,值都是相等的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function Person() { this.name = "John"; }
function Singleton(construct) { let obj = new construct(); Singleton = function () { return obj; }
return obj; }
let p1 = new Singleton(Person); let p2 = new Singleton(Person);
console.log(p1 === p2);
|
2. 观察者模式
观察者模式两点
- 观察者至少需要
- 方法 下面代码中
Observer
的 fn
方法
- 其他 下面代码中
Observer
的 name
属性
- 被观察者至少需要
- 状态 下面代码中
Subject
的 state
属性
- 观察者列表 下面代码中
Subject
的 observers
属性
- 修改状态,添加删除观察者 下面代码中
Subject
的 setState
,listen
,unlisten
方法
- 其他
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class Observer { constructor(name, fn = () => {}) { this.name = name; this.fn = fn; } };
class Subject { constructor(state) { this.state = state; this.observers = []; }
setState(newState) { if(this.state === newState) return; this.state = newState;
this.observers.map(item => item.fn(newState)); }
listen(observer) { if (this.observers.indexOf(observer) === -1) { this.observers.push(observer); } }
unlisten(observer) { const index = this.observers.indexOf(observer); if (index !== -1) { this.observers.splice(index, 1); } } };
const p1 = new Observer('小夫', (state) => {console.log(`${state} ==> 小夫--> 打篮球`)}); const p2 = new Observer('胖虎', (state) => {console.log(`${state} ==> 胖虎--> 睡大觉`)});
const s1 = new Subject('学习');
s1.listen(p1); s1.listen(p2); console.log(s1);
s1.setState('玩');
s1.unlisten(p1);
s1.setState('学习');
|
3. 发布订阅模式
发布订阅有点像观察者模式,但是有不尽相同。发布订阅模式很常见,就是 addEventListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| class Subscribe { constructor() { this.events = {}; }
includeEvent(event) { return this.events[event] !== undefined; }
notIncludesEvent(event) { return this.events[event] === undefined; }
on(event, func) { if (this.notIncludesEvent(event)) { this.events[event] = [func]; } else { this.events[event].push(func); } }
off(event, func) { if (this.includeEvent(event)) { const index = this.events[event].indexOf(func); if (index !== -1) { this.events[event].splice(index, 1); } } }
trigger(event) { if (this.includeEvent(event)) { this.events[event].map(item => item()); } } }
let sub = new Subscribe();
function func1() {console.log('func1');} function func2() {console.log('func2');} function func3() {console.log('func3');} function func4() {console.log('func4');} function func5() {console.log('func5');}
sub.on('click', func1); sub.on('click', func2); sub.on('click', func3); sub.on('click', func4); sub.on('click', func5);
sub.trigger('click');
sub.off('click', func3); sub.off('click', func5);
sub.trigger('click');
|
4. 策略模式
一个问题匹配多个解决方案,不一定要用到哪一个。而且有可能随时增加多个方案。
常见的就是购物车,各种活动,满减,满折,红包等等。
需要暴露借口,后期可以添加与删除,而不影响源代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| function caculatePrice() { let sales = { "100-10": (price) => price -= 10, "200-25": (price) => price -= 25, "80%": (price) => price *= 0.8 };
function calculate(type, price) { if (!sales[type]) return "没有这个折扣";
return sales[type](price); }
calculate.add = (type, func) => { sales[type] = func; }
calculate.del = (type) => { delete sales[type]; }
return calculate; }
const calculate = caculatePrice();
const res = calculate('100-10', 300); console.log(res);
const res2 = calculate('80%', 300); console.log(res2);
const res3 = calculate('70%', 300); console.log(res3);
calculate.add("70%", (price) => price *= 0.7); const res4 = calculate('70%', 300); console.log(res4);
calculate.del("80%"); const res5 = calculate('80%', 300); console.log(res5);
|