设计模式20——行为型模式之观察者模式

  定义: 观察者模式 (ObserverPattern) ,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

类型:对象行为型模式

概述:

         观察者模式也是比较难以理解,单看类图,会发现观察者模式与中介模式非常相似。如果不真正理解他们二者之间的区别,是难以真正理解观察者模式的。如果不理解观察者模式,更奢谈运用观察者模式了。

         中介模式主要是解决一系列交互对象的耦合的问题,而提出了中介类。几个以前交互的对象现在统一通过中介类来完成交流。而观察者模式侧重的是一对多的通知的功能,即当发生某件事时,主题对象将向所有注册过的观察者对象发出通知消息。

         中介模式侧重通过中介类来完成交流;而观察者模式侧重于一对多的通知。中介模式不需要知道具体的中介类的对象,需要交互的对象只需要知道一个通知中介对象的接口即可,具体是哪个中介来完成交互对象告诉的任务,交互对象不需要知道。但是交互对象必须知道有哪些交互对象,这样才能把对象A需要对象B做的事想办法通知到对象B

          观察者模式则,Subject对象不需要知道具体的观察者是谁,它只需要知道观察者的通知接口,就可以将消息通知到观察者。至于具体有哪些消息,则需要观察者自己去具体的Subject那里查看。

          这里举一个例子,某电商有大促销,通过邮件发送促销消息给消费者。但是如果消费者想了解有哪些具体的促销信息,则即需要亲自去电商网站查看有哪些具体的促销信息。

类图:


 参与者:

  1. Vender,提供接口来完成对观察者的注册通知。
  2. YiXun,具体的电商,为消费者提供所需要查看具体信息。
  3. Observer,提供Update接口。
  1. CustomerACustomerB,具体的观察者,当有更新时去查看电商中自己喜欢的产品。

 示例代码:

using  System ;
using  System . Collections . Generic ;
using  System . Text ;
namespace  Design20
{
     abstract  class  Vender
     {
         private  IList < Observer >  observers  =  new  List < Observer > ( ) ;
         // 
         public  void  Register ( Observer  observer )
         {
              observers . Add ( observer ) ;
         }
         //
         public  void  Notify ( )
         {
              foreach  ( Observer  o  in  observers )
              {
                   o . Update ( ) ;
              }
         }
     }
     //
     class  YiXun  :  Vender
     {
         private  string  subjecPhone ;
         private  string  subjecLaptop ;
         //
         public  string  SubjecPhone
         {
              get  {  return  subjecPhone ;  }
              set  {  subjecPhone  =  value ;  }
         }
         //
         public  string  SubjecLaptop
         {
              get  {  return  subjecLaptop ;  }
              set  {  subjecLaptop  =  value ;  }
         }
     }
     abstract  class  Observer
     {
         public  abstract  void  Update ( ) ;
     }
     class  CustomerA  :  Observer
     {
         private  YiXun  subject ;
         public  CustomerA (
            YiXun  subject )
         {
              this . subject  =  subject ;
         }
         //
         public  override  void  Update ( )
         {
              Console . WriteLine ( " A{0} " ,  this . subject . SubjecPhone ) ;
         }
         public  YiXun  Subject
         {
              get  {  return  subject ;  }
              set  {  subject  =  value ;  }
         }
     }
     class  CustomerB  :  Observer
     {
         private  YiXun  subject ;
         public  CustomerB (
            YiXun  subject )
         {
              this . subject  =  subject ;
         }
         //
         public  override  void  Update ( )
         {
              Console . WriteLine ( " B{0} " ,  this . subject . SubjecLaptop ) ;
         }
         public  YiXun  Subject
         {
              get  {  return  subject ;  }
              set  {  subject  =  value ;  }
         }
     }
     class  Program
     {
         static  void  Main ( string [ ]  args )
         {
              YiXun  subject  =  new  YiXun ( ) ;
              subject . Register ( new  CustomerA ( subject )) ;
              subject . Register ( new  CustomerB ( subject )) ;
              // ,.
              // .
              subject . SubjecPhone  =  " IPhone5s " ;
              subject . SubjecLaptop  =  " ThinkPad " ;
              subject . Notify ( ) ;
              Console . Read ( ) ;
         }
     }
}
  适用性:
  1.  一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
  1. 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象
  1. 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

优缺点:

  1. 优点,降低命令发起者与命令接受者之间的耦合,发布者通过接口通知所有观察者。
  1. 缺点,具体的观察者依赖了具体的发布者。

参考资料:

  1. 《设计模式——可复用面向对象软件基础》
  1. 《大话设计模式》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值