为了更清楚了的理解Angular中Http请求相关的 ObservAble与Subscribe,写此笔记,备忘、回顾。
-
相关链接:
- 观察者模式
- Observable详解
- 观察者模式和发布/订阅模式的区别
- 察者模式与发布/订阅模式区别
- 观察者模式与发布/订阅模式的区别
- C#设计模式(一)订阅-发布模式
- 设计模式之美:Observer(观察者)。实例
观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。观察者模式又叫发布订阅模式(Publish/Subscribe),二者有区别参见以上链接,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
- 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- 主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
- 何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
- 如何解决:使用面向对象技术,可以将这种依赖关系弱化。
- 关键代码:在抽象类里有一个 ArrayList 存放观察者们。
实例: 1、拍卖的时候,拍卖物为梵高的 向日葵(Subject),拍卖师(观察者Observer)观察最高标价,然后通知给其他竞价者(Client)竞价。
::对照着观察者模式可以这样描述:所有的竞价者(Client)依赖 梵高的向日葵(Subject,竞拍同一件物品),拍卖师(观察者Observer)观察到有出高价的 就通知所有的竞价者,竞价者收到通知更新自己的最低起拍价。哪些人是竞价者?要有名单记录,记录成这个样子:1. Client1=拍(订阅Subscribe)=>梵高的向日葵 2. Client2=拍(订阅Subscribe)=>梵高的向日葵 3. Client3=拍(订阅Subscribe)=>梵高的向日葵 4. Client4=拍(订阅Subscribe)=>毕加索最后自画像 5. Client5=拍(订阅Subscribe)=>毕加索最后自画像 6. Client6=拍(订阅Subscribe)=>梵高的向日葵 上面的记录记为:Client1、Client2、Client3、Client6 订阅(Subscribe)了梵高的向日葵(Subject,被观察者),起拍价100W(状态)。梵高的向日葵的状态一变化(Client拍价120W),拍卖师发现梵高的向日葵价格有变化(Subject状态改变)立即通知(Notify)所有竞价者(观察者Observer:Client1、Client2、Client3、Client6)有新的起拍价,这些竞价者们(观察者Observer)必须更新自己的信息(起拍价120W)。 拍卖师要通知(Notify)所有的竞价者(观察者Observer),拍卖师又怎么知道梵高的向日葵(Subject)状态改变了?需要有一个触发机制:向日葵的当前价格(属性),属性一旦变化(set),拍卖师立马做出响应=>通知(notify)所有的观察者。观察者们更新自己的信息。 这样理解观察者模式就清楚了。Client Subscribe Subject,Subject State Changed then Notify Observer,and then Observer Publish Subject's new state to Client,Client update itself's State .
以上已经分不清观察者模式 还是 发布-订阅模式 了,直接上别人的栗子吧。
实现:实例
- 猫叫了
- 所有老鼠听到叫声,知道是哪只猫来了
- 老鼠们逃跑,边逃边喊:”xx猫来了,快跑啊!我是老鼠xxx”
参照 上面猫和老鼠 改编拍卖 实例:
拍卖C#代码实现
class Program
{
static void Main(string[] args)
{
//拍卖物
拍卖物 拍卖物1 = new 拍卖物("梵高的向日葵",100);
//登记 拍卖物 与 竞价者
竞价者 竞价者1 = new 竞价者("张珊", 拍卖物1.拍卖价);
竞价者 竞价者2 = new 竞价者("李思", 拍卖物1.拍卖价);
竞价者 竞价者3 = new 竞价者("王武", 拍卖物1.拍卖价);
//拍卖物拍卖价变化 关联 竞价者的 更新起拍价方法。
拍卖物1.新起拍价 += new 拍卖物拍卖物起价变化eventHandler(竞价者1.更新起拍价);
拍卖物1.新起拍价 += new 拍卖物拍卖物起价变化eventHandler(竞价者2.更新起拍价);
拍卖物1.新起拍价 += new 拍卖物拍卖物起价变化eventHandler(竞价者3.更新起拍价);
拍卖物1.拍卖价 = 竞价者1.举牌(120);//举牌,触发拍卖价改变=>执行通知 竞价者们。
}
}
竞价者基类:竞价者可以举牌
public abstract class 竞价者Base
{
public abstract int 举牌(int price);
}
竞价者类:竞价者 name、拍价、举牌,更新拍卖物起拍价()
public class 竞价者: 竞价者Base
{
public 竞价者()
{
}
public string Name { get; set; }
public int 拍价 { get; set; }
public 竞价者(string name, int price)
{
this.拍价 = price;
this.Name = name;
}
public void 更新起拍价(object sender, 拍卖物起价改变event e)
{
Console.WriteLine(e.拍卖物Name + " 价格变了! 起拍价提高,["+this.Name+"]当前的拍价是:" + this.拍价.ToString()+",新起拍价:"+e.拍卖物拍卖价);
}
public override int 举牌(int price)
{
this.拍价 = price;
return price;
}
}
拍卖物:拍卖不name、起拍价,起拍价变化(Set)立即触发方法【起拍价变化】==》触发 拍卖物拍卖物起价变化eventHandler【新起拍价】(与拍价者【更新起拍价】方法关联)
public class 拍卖物
{
public event 拍卖物拍卖物起价变化eventHandler 新起拍价;
public 拍卖物()
{
}
/// <summary>
/// 拍卖物名称
/// </summary>
public string Name { get; set; }
private int _拍卖价;
public int 拍卖价 {
get
{
return _拍卖价;
}
set
{
if (_拍卖价==0)
{
_拍卖价 = value;
}
else
{
_拍卖价 = value;
起拍价变化();
}
}
}
public 拍卖物(string name,int price)
{
this.Name = name;
this.拍卖价 = price;
}
public void 起拍价变化()
{
Console.WriteLine("起拍价变化了!!");
if (this.新起拍价 != null)
{
拍卖物起价改变event e = new 拍卖物起价改变event(this.Name,this.拍卖价);
this.新起拍价(this, e);
}
}
}
拍卖物拍卖物起价变化eventHandler:
public delegate void 拍卖物拍卖物起价变化eventHandler(object sender, 拍卖物起价改变event e);
拍卖物起价改变event:触发拍卖价变化的事件,包含拍卖物信息。
public class 拍卖物起价改变event : EventArgs
{
private string _拍卖物Name;
private int _拍卖物拍卖价;
public 拍卖物起价改变event(string name,int price)
{
this.拍卖物Name = name;
this._拍卖物拍卖价 = price;
}
public string 拍卖物Name
{
get
{ return _拍卖物Name; }
set { this._拍卖物Name = value; }
}
public int 拍卖物拍卖价
{
get
{ return _拍卖物拍卖价; }
set { this._拍卖物拍卖价 = value; }
}
}