观察者模式

来源:互联网 发布:退伍军人召回通知软件 编辑:程序博客网 时间:2024/05/01 16:42

对于观察者模式还不是特别大额理解,现在那么静静下心来好好的整理了一下。
自己理解搞这么多的设计模式到底是干什么? 解耦和模块化。试着想象,现在很吊的滴滴打车,曾经出现了很多的黑科技优惠券,不就是由于发展太快,解耦处理不好,出现了很多的‘黑科技’。(刚开始写,表达能力不是很强,后期我会慢慢的优化的。)

首先

观察者模式要做到

  • 开放-封闭原则(修改原有的代码就代表不好)。
  • 依赖倒转原则(应该让程序都依赖抽象,而不是相互依赖)。
    让耦合的双方都依赖于抽象,而不是依赖于具体,从而使各自的变化都不会影响到另一边的变化。

到底观察者模式是什么样子的呢?

用一张图来解释观察者模式
观察者模式

代码来源(书籍):大话设计模式

//Subject类,可翻译为主题或抽象通知者,一般用一个抽象类或一个接口实现。它把所有对观察者对象的引用保存在一个聚集里面,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以拉回和删除观察者对象。  public abstract class Subject  {      private List<Observer>    observers   = new ArrayList<Observer>();      public void attach(Observer observer)      {          observers.add(observer);      }      public void detach(Observer observer)      {          observers.remove(observer);      }      public void announce()      {          for (Observer obj : observers)          {              obj.update();          }      }  }  //Observer类,抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。更新接口通常包含一个update()方法,这个方法叫做更新方法。  public abstract class Observer  {      public abstract void update();  }  //ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。  public class ConcreteSubject extends Subject  {      // 具体被观察者状态      private String  subjectState;      public String getSubjectState()      {          return subjectState;      }      public void setSubjectState(String subjectState)      {          this.subjectState = subjectState;      }  }  //ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。具体观察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。  public class ConcreteObserver extends Observer  {      private String          name;      private String          observerState;      private ConcreteSubject subject;      public ConcreteObserver(String name, ConcreteSubject subject)      {          this.name = name;          this.subject = subject;      }      public void update()      {          observerState = subject.getSubjectState();          System.out.println("观察者" + name + "的新状态是" + observerState);      }      public ConcreteSubject getSubject()      {          return subject;      }      public void setSubject(ConcreteSubject subject)      {          this.subject = subject;      }  }  //客户端代码  public class Main  {      public static void main(String[] args)      {          ConcreteSubject s = new ConcreteSubject();          s.attach(new ConcreteObserver("X", s));          s.attach(new ConcreteObserver("Y", s));          s.attach(new ConcreteObserver("Z", s));          s.setSubjectState("ABC");          s.announce();      }  }  结果显示:  观察者X的新状态是ABC  观察者Y的新状态是ABC  观察者Z的新状态是ABC  

但是这样的话,抽象通知者还是依赖观察者

万一没有抽象观察者这样的接口,那么我们的观察者模式还是完成不了

用委托来解决

EventHandler(事件处理程序)
用委托的方式来进行通知每个具体的观察者的不同的updata的处理方法。

但是委托也是有前提的,那么就是委托对象所搭载的所有的方法必须具有相同的原型和形式,也就是拥有相同的返回值类型和参数列表

代码来源(书籍):大话设计模式

 //看股票的同事      class StockObserver      {          private string name;          private Subject sub;          public StockObserver(string name, Subject sub)          {              this.name = name;              this.sub = sub;          }          //关闭股票行情          public void CloseStockMarket()          {              Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);          }      }      //看NBA的同事      class NBAObserver      {          private string name;          private Subject sub;          public NBAObserver(string name, Subject sub)          {              this.name = name;              this.sub = sub;          }          //关闭NBA直播          public void CloseNBADirectSeeding()          {              Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);          }      }  //抽象通知者由于不希望依赖于抽象观察者,所以增加和减少的就没有必要了,抽象观察者已经不存在了,通知者接口如下      //通知者接口      interface Subject      {          void Notify();          string SubjectState          {              get;              set;          }      }  
//事件处理程序的委托  delegate void EventHandler();  //老板类和前台秘书类      class Secretary : Subject      {          //声明一事件Update,类型为委托EventHandler          public event EventHandler Update;          private string action;          public void Notify()          {              Update();          }          public string SubjectState          {              get { return action; }              set { action = value; }          }      }      class Boss : Subject      {          //声明一事件Update,类型为委托EventHandler          public event EventHandler Update;          private string action;          public void Notify()          {              Update();          }          public string SubjectState          {              get { return action; }              set { action = value; }          }  }  //客户端代码  class Program      {          static void Main(string[] args)          {              //老板胡汉三              Boss huhansan = new Boss();              //看股票的同事              StockObserver tongshi1 = new StockObserver("魏关姹", huhansan);              //看NBA的同事              NBAObserver tongshi2 = new NBAObserver("易管查", huhansan);              huhansan.Update += new EventHandler(tongshi1.CloseStockMarket);              huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding);              //老板回来              huhansan.SubjectState = "我胡汉三回来了!";              //发出通知              huhansan.Notify();              Console.Read();          }  }  运行结果:  老板回来了!  魏关姹关闭股票行情,继续工作!  老板回来了!  易管查关闭股票行情,继续工作!  
0 0
原创粉丝点击