原文 : oodesign
产生的诱因
我们在谈论 面向对象编程的时候,不得不考虑 对象状态的变化 。毕竟 面向对象编程 是 关于 对象 以及 对象之间的交互。
有这么一种业务情况,当 一个对象 发生改变时 ,某一类对象需要被通知 ,为了 解耦 可以采用 观察者模式,
观察者模式 用在 一个 对象需要 被 一个 或者 多个 观察者 观察的时候;
思路
在对象之间 定义 一个 一对多的依赖,当一个对象的状态改变时,所有他的依赖被自动 通知 和 更新
说明:
Observable :接口 或者 抽象类 ,定义了向 客户端 添加 观察者 和 删除观察者 的 操作, 通知操作 ,该类也可以叫做 Subject;
ConcreteObservable: Observable 具体实现,定义了更新操作,该方法的执行会执行通知操作
Observer :接口 或者 抽象类 ,定义了 用来通知 该对象的操作;
ConcreteObserverA,ConcreteObserverB: Observer 的具体实现;
实现流程:
首先 实例化 ConcreteObservable(ConcreteSubject) 对象;
然后再实例化 Observer 的具体实现类 并使用 Observable 接口中定义的 attach 方法 将 Obserserver 实例 纳入其中;
每次 ConcreteObservable 状态改变,会使用 Observable 接口中定义的 notifyObservers 方法 调用 所有已管理的 Observer 的 update 方法;
当一个新的 Observer 被添加到应用中时,我们需要做的仅仅是实例化它,然后将它添加到 Observable 对象中
应用 和 实例
典型的 案例:
MVC (MOdel View Controller)模式 :观察者模式 被用在 MVC架构模式中,在MVC 模式中,观察者模式是用来 将 数据层(Model)从 视图层(View)解耦。 View 代表 Observer 对象, Model 代表 Observable 对象
事件管理:
应用:新闻订阅
NewsPublisher :抽象类,相当于一个 Observable 接口
package com.ycit.observer;
import java.util.ArrayList;
import java.util.List;
/**
* Created by xlch on 2017/3/16.
*/
public abstract class NewsPublisher {
List<Subscriber> subscribers = new ArrayList<>();
String latestNews;
abstract void attach(Subscriber subscriber);
abstract void detach(Subscriber subscriber);
abstract void notifyObservers();
abstract void publishNews(String news);
public String getLatestNews() {
return latestNews;
}
}
SportNewsPublisher:具体实现类
package com.ycit.observer;
/**
* Created by xlch on 2017/3/16.
*/
public class SportNewsPublisher extends NewsPublisher {
private String name;
public SportNewsPublisher(String name) {
this.name = name;
}
@Override
void attach(Subscriber subscriber) {
subscribers.add(subscriber);
}
@Override
void detach(Subscriber subscriber) {
subscribers.remove(subscriber);
}
@Override
void notifyObservers() {
for (Subscriber subscriber:subscribers) {
subscriber.update(this);
}
}
/**
* 发布新闻,代表 latestNews 状态改变,通知所有订阅者
* @param news
*/
@Override
void publishNews(String news) {
System.out.println(this.name + " publish a news:" + news);
latestNews = news;
notifyObservers();
}
}
Subscriber : 订阅者 ,即观察者
package com.ycit.observer;
/**
* Created by xlch on 2017/3/16.
*/
public interface Subscriber {
/**
* 状态改变时执行的动作
* @param newsPublisher
*/
void update(NewsPublisher newsPublisher);
}
EmailSubscriber:邮件订阅者
package com.ycit.observer;
/**
* Created by xlch on 2017/3/16.
*/
public class EmailSubscriber implements Subscriber {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EmailSubscriber(String name) {
this.name = name;
}
private NewsPublisher newsPublisher;
public void setNewsPublisher(NewsPublisher newsPublisher) {
this.newsPublisher = newsPublisher;
}
public NewsPublisher getNewsPublisher() {
return newsPublisher;
}
@Override
public void update(NewsPublisher newsPublisher) {
System.out.println(this.name + " receive a news :" + newsPublisher.getLatestNews());
}
}
SMSSubscriber:sms 订阅者
package com.ycit.observer;
/**
* Created by xlch on 2017/3/16.
*/
public class SMSSubscriber implements Subscriber {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public SMSSubscriber(String name) {
this.name = name;
}
private NewsPublisher newsPublisher;
public void setNewsPublisher(NewsPublisher newsPublisher) {
this.newsPublisher = newsPublisher;
}
public NewsPublisher getNewsPublisher() {
return newsPublisher;
}
@Override
public void update(NewsPublisher newsPublisher) {
System.out.println(this.name + " receive a news :" + newsPublisher.getLatestNews());
}
}
Main:测试类
package com.ycit.observer;
/**
* Created by xlch on 2017/3/16.
*/
public class Main {
public static void main(String [] args) {
SportNewsPublisher sportNewsPublisher = new SportNewsPublisher("体育新闻发布者");
EmailSubscriber emailSubscriber = new EmailSubscriber("邮件订阅者");
SMSSubscriber smsSubscriber = new SMSSubscriber("sms 订阅者");
sportNewsPublisher.attach(emailSubscriber);
sportNewsPublisher.attach(smsSubscriber);
sportNewsPublisher.publishNews("姚明退出NBA,火箭篮下恐不保");
}
}
执行后 :
体育新闻发布者 publish a news:姚明退出NBA,火箭篮下恐不保
邮件订阅者 receive a news :姚明退出NBA,火箭篮下恐不保
sms 订阅者 receive a news :姚明退出NBA,火箭篮下恐不保