设计模式之观察者模式
观察者模式又叫发布-订阅模式(Publish/Subscribe)是一种一对多的信息发布模式 ;一个发布者对应多个观察者;
什么意思呢?
比如说 你某天想发一条动态,写完之后发布 有很多人给你点赞评论; 你(发布动态的人)就是发布者;看你动态的人是观察者;
观察者模式的优点1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制
可以被用来设计微信公众号等;
首先我们要建立观察者模式个结构:
构建Obs 发布者实例对象
// 发布者 :
function Observer(){
this.list = [];
}
Observer.prototype = {
constructor : Obs,
}
作为发布者肯定需要添加内容和执行内容 建立on函数添加内容,用emmit函数执行将内容发布,delete函数删除内容
On函数中传入的参数是要放入的内容,然后将内容放入定义好的list数组之中,
emmit函数遍历list数组,将数组中存入的内容逐一发布,delete函数遍历list数组将传入的参数删除掉
function Observer(){
this.list = [];
}
Observer.prototype = {
constructor : Observer,
on : function( sub ){
this.list.push( sub );
},
emmit : function(msg){
this.list.forEach( function( sub ){
sub.strategy( msg );
})
},
delete : function( sub ){
this.list.splice( this.list.indexOf(sub) , 1 )
}
}
建立订阅者结构
// // 订阅者;
function Sub( name ){
this.name = name;
}
Sub.prototype.strategy = function( msg ){
typeof this[msg] === "function" ? this[msg]() : "";
}
Sub.prototype.happy = function(){
console.log("我好开心啊");
}
Sub.prototype.unhappy = function(){
console.log("我好难过啊");
}
发布者将内容添加发布
var obs = new Observer();
obs.on( new Sub("订阅者1") );
obs.on( new Sub("订阅者2") );
obs.on( new Sub("订阅者3") );
obs.on( new Sub("订阅者4") );
// console.log(obs)
obs.emmit("happy");
因为有四个订阅者所以内容反馈了四次
当然发布者发布的内容肯定是有人喜欢而有人不喜欢的,所以我们需要将发布的内容选择给谁看
function Observer(){
this.list = {};
}
Observer.prototype = {
constructor : Observer,
on : function( sub , type ){
type = type || "default";
// 判定对应类别之中是否为数组;
if(this.list[type] && this.list[type] instanceof Array){
// 如果是数组直接放入;
this.list[type].push(sub);
}else{
// 如果不是数组建立数组结构;
this.list[type] = [sub];
}
},
emmit : function(msg , type){
type = type || "default";
if(this.list[type] instanceof Array){
this.list[type].forEach( function( sub ){
sub.strategy( msg );
})
}
},
delete : function( sub , type ){
this.list[type].splice( this.list[type].indexOf(sub) , 1 )
}
}
为了区别订阅者多传入了一个参数type ,如果发布者不传type值 会默认type=default 当传入type值的时候就与其他订阅者区分开来 将list 转换为了对象数组结构,将不同type的订阅者存储在list对象不同 属性中,以数组存储;
//订阅者;
function Sub( name ){
this.name = name;
}
Sub.prototype.strategy = function( msg ){
typeof this[msg] === "function" ? this[msg]() : "";
}
Sub.prototype.happy = function(){
console.log("我好开心啊");
}
Sub.prototype.unhappy = function(){
console.log("我好难过啊");
}
var obs = new Observer();
obs.on( new Sub("订阅者1") );
obs.on( new Sub("订阅者2") );
obs.on( new Sub("订阅者3") );
obs.on( new Sub("订阅者4") );
obs.on( new Sub2("订阅者5") , "heifen" );
obs.on( new Sub2("订阅者6") , "heifen" );
console.log(obs)
obs.emmit("happy" );
obs.emmit("happy","heifen" );
订阅者可以 区别设置 当传入同一个内容时,不同订阅者可以产生不同的反应
最后总结一下发布者规范写法
function Observer(){
this.list = {};
}
Observer.prototype = {
constructor : Observer,
on : function( sub , type ){
type = type || "default";
// 判定对应类别之中是否为数组;
if(this.list[type] && this.list[type] instanceof Array){
// 如果是数组直接放入;
this.list[type].push(sub);
}else{
// 如果不是数组建立数组结构;
this.list[type] = [sub];
}
},
emmit : function(msg , type){
type = type || "default";
if(this.list[type] instanceof Array){
this.list[type].forEach( function( sub ){
sub.init( msg );
})
}
},
delete : function( sub , type ){
this.list[type].splice( this.list[type].indexOf(sub) , 1 )
}
}