基本概念
Observer
- 观察者模式(Observer Pattern)又称为发布订阅模式(Publish/subscribe)
- 定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并且自动更新
- 根据单一职责原则,每个类的职责是单一的,我们可以通过触发机制,形成一个触发链,把各个单一的职责串联成真实世界中的复杂的逻辑关系。
- 观察者模式的角色分工(JDK中提供了抽象接口的定义):
- Subject被观察者:
抽象类型,定义被观察者必须实现的职责,动态地增加和取消观察者
- Observer观察者:
接口,观察者接收到消息后会进行update,对接收到的消息进行响应
- Concrete Subject/Observer:
提供具体的业务逻辑的实现
- Subject被观察者:
实践中会遇到的问题
- 观察者的响应模式:
- 如果观察者是一个复杂的逻辑,那么会导致多个观察者监听单个被观察者时,因为效率问题发生通知的滞后,所以决定观察者的响应方式很重要:
- 采用多线程技术,启动异步线程执行耗时较长的工作,不会阻塞主线程,也就是异步架构
- 采用缓存技术,通过大量资源的缓存,但是要进行压力测试,这就是同步架构
- 如果观察者是一个复杂的逻辑,那么会导致多个观察者监听单个被观察者时,因为效率问题发生通知的滞后,所以决定观察者的响应方式很重要:
- 通知需要定制,在被观察者实现是否通知观察者的逻辑,能减少没有意义的数据传输,否则,也会加重观察者的处理逻辑
例讲观察者模式
相信很多年轻人买不起房子,看到房子价格变化总会有感慨,这就是一个观察者模式的例子,大家都在关注房价,我们正好作为一个例子,来讲解应用广泛的观察者模式
- 首先实现我们的Observer和Subject抽象接口
abstract class Subject{
List<Observer> list = new LinkedList<Observer>();
public void addObserver( Observer observer ){
list.add(observer);
}
public void removeObserver ( Observer observer ){
list.remove( observer);
}
public abstract void notifyObserver( String message );
}
interface Observer {
void update(String message);
}
然后看具体的实现类
interface PriceVary{
String GO_HIGH ="The price of house still go high";
String GO_LOW = "The price of house go low";
}
class HousePrice extends Subject {
@Override
public void notifyObserver( String message ) {
for (Observer observer : list) {
observer.update(message);
}
}
}
class Poor implements Observer{
@Override
public void update(String message) {
System.out.println(message + "But,what about me!");
}
}
class Middle implements Observer{
@Override
public void update(String message) {
if( message.equals( PriceVary.GO_HIGH) ){
System.out.println( message +", I need to save more money!-_-");
}else{
System.out.println( message + " I can buy it! Woh!");
}
}
}
class Rich implements Observer{
@Override
public void update(String message) {
if( message.equals( PriceVary.GO_HIGH) ){
System.out.println( message +", money coming baby!^_^");
}else{
System.out.println( message + " Fuck!");
}
}
}
public class ObserverTest {
public static void main ( String [] args ){
Subject subject = new HousePrice();
subject.addObserver( new Rich());
subject.addObserver( new Poor());
subject.addObserver( new Middle());
subject.notifyObserver( PriceVary.GO_HIGH);
subject.notifyObserver( PriceVary.GO_LOW);
}
}
运行结果如下,这就是一个简单的观察者模式的实现
JDK中提供的Observer模式的API
java.util.Observer
- 声明为public interface Observer
- 方法如下:
//一旦被监听者发生改变就会调用该方法
void public update( Observable o , Object arg )
java.util.Observable
- 声明为public class Observable extends Object
- 方法如下:
//添加一个监听者
void addObserver ( Observer o )
//获取监听者的数目
int countObservers ()
//删除指定的监听者
void deleteObserver ( Observer o )
//删除所有的监听者
void deleteObservers ()
//判断被监听者是否发生了变化
boolean hasChanged ()
//通知监听者被监听者发生了变化,该操作会调用clearChanged()
void notifyObservers()
void notifyObservers( Object o )
//清零变化的标志位
protected void clearChanged()
//设置变化的标志位,表示发生变化
protected void setChanged()
那么我们来利用JDK的API改写之前的代码….
class HousePrice1 extends Observable {
public void priceUp( ){
setChanged();
super.notifyObservers( PriceVary.GO_HIGH );
}
public void priceDown(){
setChanged();
super.notifyObservers(PriceVary.GO_LOW);
}
}
class Poor1 implements java.util.Observer{
@Override
public void update(Observable o, Object arg) {
String message = arg.toString();
System.out.println(message + "......");
}
}
public class ObserverTest2 {
public static void main ( String [] args ){
HousePrice1 observable = new HousePrice1();
observable.addObserver( new Poor1());
observable.priceUp();
observable.priceDown();
}
}
没有写全部,但是足以授意
Tomcat中的Observer模式的使用
- Tomcat中对于观察者模式的一个经典使用就是用来控制组件生命周期的Lifecycle
- 首先我们将Lifecycle用到的几个类对应到Observer模式中的角色中去:
- LifecycleListener:对应抽象的Observer
- ServerLifecycleLisener等:对应具体的Observer
- Lifecycle:对应抽象的Subject
- StandardServer等:对应具体的Subject
- 除此之外还有两个辅助类:
- LifecycleEvent:可以定义事件类别,对不同的事件可区分处理,更加灵活
- LifecycleSupport:代理了Subject对于Observers的管理,将这个管理抽出来统一实现,以后如果修改只要修改LifecycleSupport类就可以了,不需要去修改所有的Subject,因为所有具体的Subject对Observers的操作都被代理给了LifecycleSupport类了。
时间: 2024-10-06 01:15:19