<!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>