观察者模式
来源:互联网 发布:退伍军人召回通知软件 编辑:程序博客网 时间: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
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- SQL执行XML编码问题
- 使用matplotlib实现画图
- Android控件visible,invisible和gone
- (1)RIL简析(高通)——RIL如何启动及初始化
- hdu 1203- I NEED A OFFER!
- 观察者模式
- 项目间的循环依赖
- python 画雷达图
- HDU 4445 Crazy Tank
- ssh连接提示 "Connection closed by remote host"
- Android 各层调用的方式
- 【zzuliOJ】1916 - 树(dfs序 & 树状数组)
- MyBatis 简单参考
- 初学者学习 - Unity中的热更新 - Lua和C#通信