最近,学习了几种设计模式,由此来作出点总结。设计模式在我们的开发中是必不可缺的,它代表着最佳的实践,通常被有经验的面向对象的软件开发人员所采用,是软件开发人员在软件开发过程中面临的一般问题的解决方案,是由众多软件人员经过长时间的实验和错误总结出来的,所以我们使用设计模式会给我们带来极大的方便。设计模式只能在特定的情况,特定的时期,针对特定的问题使用。
单例模式
单例模式是最简单的设计模式之一,这种类型的设计模式属于创建型模式,它提供一种创建对象的最佳方式。
这种模式只涉及到单一的类,该类负责创建自己的对象,同时保证只有单个对象被创建。下面代码展示:
核心代码:
function Person() {
this.name = 'Jack'
}
// 全局
var instance = null
function singleton() {
if (instance === null) {
instance = new Person()
}
return instance
}
这样保证每次通过调用singleton产生的实例对象是同一个,下面是完整单例模式代码:
var Person = (function () {
function Person() {
}
Person.prototype.sayHi = function () {
console.log('hello')
}
var instance = null
return function () {
return instance = instance ? instance : new Person()
}
})()
console.log(Person);
var s1 = new Person()
var s2 = new Person()
console.log(s1 === s2 );
我们会发现s1 与 s2 相等 ,证明创建的是同一个实例。
组合模式
组合模式就是指在页面表现中,通过一条指令而达到在多个对象中的复杂的递归行为,就是通过控制一个对象,不过该对象复杂的递归下去又是很多复杂的对象,同时控制对象的行为。这样简化代码,可维护,复杂的对象的行为委托给一个对象。
class Compose {
constructor () {
this.composeArr = []
}
add (instance) {
this.composeArr.push(instance)
}
//初始化调用
init () {
console.log('启动')
this.composeArr.forEach(item => item.init())
}
}
class Play {
constructor () {
}
init () {
console.log('去玩耍')
}
}
class Eat {
constructor () {
}
init () {
console.log('去吃饭')
}
}
class Sleep {
constructor () {
}
init () {
console.log('去睡觉')
}
}
var p = new Compose()
// console.log(p);
p.add(new Eat())
console.log(p)
p.add(new Play())
console.log(p);
p.add(new Sleep())
console.log(p);
p.init();
我们将这些类添加到Compose身上,通过Compose的init来执行这些类的方法。
观察者模式(Observer模式)
Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。
Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。
被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。被观察者需要维持(添加,删除,通知)一个观察者对象的队列列表。
观察者模式分为两派,一是观察者模式,二是发布/订阅.
观察者模式
//观察者
class Observe {
constructor (name) {
this.name = name
}
qjz (state) {
console.log(`我是${this.name},因为你${state},我要请你家长来!`);
}
}
// 被观察者
class Student {
constructor () {
this.state = '好好学习'
this.observes = []
}
//改变状态
setState (value) {
this.state = value
this.notify()
}
//获取状态
getState () {
return this.state
}
// 添加观察者
addObserve (observer) {
this.observes.push(observer)
}
//通知
notify () {
//es6 this指向函数上下文作用域
this.observes.forEach(item => item.qjz(this.state))
}
}
var xm = new Student()
var bzr = new Observe('班主任')
var jwzr = new Observe('教务主任')
xm.addObserve(bzr)
console.log(xm);
xm.setState('睡觉')
//这里只有班主任
xm.addObserve(jwzr)
// 这里是班主任和教务主任
xm.setState('打游戏')
订阅/发布
<script>
function handlerA(e) { console.log('我是事件处理函数 handlerA', e) }
function handlerB(e) { console.log('我是事件处理函数 handlerB', e) }
function handlerC(e) { console.log('我是事件处理函数 handlerC', e) }
function handlerD(e) { console.log('我是事件处理函数 handlerD', e) }
function handlerE(e) { console.log('我是事件处理函数 handlerE', e) }
class Observe {
constructor () {
//信息盒子
this.message = {}
}
//订阅方法
on (type,fn) {
if(!this.message[type]) {
this.message[type] = []
}
// console.log(this.message[type]);
//过滤已存在的方法
if(!this.message[type].some(item => item === fn )) {
this.message[type].push(fn)
}
}
// 取消订阅的方法
off (type,fn) {
if(!this.message[type]) return
this.message[type] = this.message[type].filter(item => item !== fn )
}
//发布的方法
emit (type,...arg) {
if(!this.message[type]) return
var event = {
type:type,
data:arg
}
this.message[type].forEach(item => item(event))
}
}
var o = new Observe()
// console.log(o)
o.on('click', handlerA)
o.on('click', handlerB)
o.on('move',handlerD)
o.on('move',handlerD)
console.log(o);
o.emit('click', 'hello world', 100, true, { name: 'Jack' })
在我看来,观察者模式和发布/订阅最主要的区别在于是否有中间的调度中心。
1 观察者模式把订阅者维护在发布者这里,需要发布消息时直接发消息给订阅者。在观察者模式中,发布者本身是知道订阅者存在的。
2 而发布/订阅模式中,发布者并不维护订阅者,也不知道订阅者的存在,所以也不会直接通知订阅者,而是通知调度中心,由调度中心通知订阅者。
以上就是我对设计模式的一些看法。