<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>设计模式4</title>
</head>
<body>
<script type="text/javascript">
//十一、迭代器模式可以统一遍历集合对象的方式,并且十分容易扩展,开发者可以十分容易的让自定义的集合支持统一提供的迭代器
//使用者:统一的接口可以更加便于进行代码的组织和管理
//1、定义一个迭代器协议
var MyIterator = {
next:function(){
throw '必须实现next'
}
}
//2、迭代器方法
function tool(obj,callback){
var item=obj.next();
while(item!==undefined){
callback(item);
item=obj.next();
}
}
//3、实现迭代器的对象
var myObj = {
name:'Owen',
age:'30',
subject:'typescript',
teaching:function(){
console.log('teaching')
},
_keys:['name','age','subject'],
_tip:0,
next:function(){
return this._keys[this._tip++]
}
}
myObj.__proto__=MyIterator;
//验证
tool(myObj,function(item){console.log(item)});// name age subject
// 当有新的集合对象需要支持迭代时,只需要在其中实现next方法,tool函数就能进行很好的工作了
</script>
<script type="text/javascript">
//十二、备忘录设计模式(备份设计模式)
//用来进行对象内部状态的备份:备份的可能不是完整的对象,我们使用文本编辑器时可以撤销,浏览器可以返回,都是备忘录模式的实际应用
//场景:状态恢复,有时也可以用来缓存网络数据
var EditProtocol = {//核心的协议对象,任何需要支持撤销操作的对象,只要以它为原型并实现重写的方法,就可以完成状态的保存与恢复
_stateArray:[],
revoke:function(){
this._refresh(this._stateArray.pop())
},
save:function(){
this._stateArray.push(this._state())
},
_refresh:function(){
throw '必须实现_refresh'
},
_state:function(){
throw '必须实现_state'
}
}
var teacher = {
name:'Owen',
age:30,
subject:'typescript',
_refresh:function(state){
this.name=state.name;
this.age = state.age;
this.subject=state.subject;
},
_state:function(){
return {
name:this.name,
age:this.age,
subject:this.subject
}
}
}
teacher.__proto__=EditProtocol;//以EditProtocol为原型
teacher.save();//保存
console.log(teacher.name,teacher.age,teacher.subject)// Owen 30 typescript
teacher.name='jack';
teacher.age=45;
console.log(teacher.name,teacher.age,teacher.subject)//jack 45 typescript
teacher.revoke();//撤销
console.log(teacher.name,teacher.age,teacher.subject);// Owen 30 typescript
</script>
<script type="text/javascript">
//十三、观察者模式
vue使用了观察者模式:参阅:https://www.cnblogs.com/qisi007/p/11002583.html
//用来实现 订阅逻辑,当对象出现一对多的交互关系时,也可以使用观察者模式来处理
//观察者模式一般右服务端和客户端两方组成,客户端通过订阅来监听服务端的信息,由服务端发送信息给已经订阅的客户端
//教务处作为服务端,会给老师发布任务, 当教师接收到任务后,开始执行教学任务
var Service = {
_customer:new Set(),
addObserver:function(obj,func){
this._customer.add({obj:obj,func:func})
},
deleteObserver:function(obj){
var has;
this._customer.forEach(function(object){
if(object.obj===obj){
has=object
}
});
if(has!==undefined){
this._customer.delete(has)
}
},
publish:function(msg){
console.log("发布了订阅消息");
this._customer.forEach(function(obj){
obj.func.call(obj.obj,msg)
})
}
}
var teacher1 = {// 观察者1
name:'Owen',
teach:function(msg){
console.log(this.name+"开始教学"+msg);//Owen开始教学phyon
}
}
var teacher2 = {// 观察者1
name:'Jack',
teach:function(msg){
console.log(this.name+"开始教学"+msg);//Jack开始教学phyon
}
}
// 调用 服务端添加订阅的方法,即给相关老师发教学任务(教师通过订阅监听)
Service.addObserver(teacher1,teacher1.teach)
Service.addObserver(teacher2,teacher2.teach)
//服务端发布订阅消息
Service.publish('phyon')//发布了订阅消息 Owen开始教学phyon Jack开始教学phyon
//调用服务端删除订阅的方法,即删除对应的观察者
Service.deleteObserver(teacher1);// 删除一个订阅者
//服务端发布订阅消息(发消息给已经订阅的观察者)
Service.publish('javascript')//发布了订阅消息 Jack开始教学javascript
</script>
</body>
</html>