Java设计模式(五) Observer(观察者)模式及Tomcat引申

基本概念

Observer

  • 观察者模式(Observer Pattern)又称为发布订阅模式(Publish/subscribe)
  • 定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并且自动更新
  • 根据单一职责原则,每个类的职责是单一的,我们可以通过触发机制,形成一个触发链,把各个单一的职责串联成真实世界中的复杂的逻辑关系。
  • 观察者模式的角色分工(JDK中提供了抽象接口的定义):
    • Subject被观察者:

      抽象类型,定义被观察者必须实现的职责,动态地增加和取消观察者

    • Observer观察者:

      接口,观察者接收到消息后会进行update,对接收到的消息进行响应

    • Concrete Subject/Observer:

      提供具体的业务逻辑的实现

实践中会遇到的问题

  • 观察者的响应模式:

    • 如果观察者是一个复杂的逻辑,那么会导致多个观察者监听单个被观察者时,因为效率问题发生通知的滞后,所以决定观察者的响应方式很重要:

      • 采用多线程技术,启动异步线程执行耗时较长的工作,不会阻塞主线程,也就是异步架构
      • 采用缓存技术,通过大量资源的缓存,但是要进行压力测试,这就是同步架构
  • 通知需要定制,在被观察者实现是否通知观察者的逻辑,能减少没有意义的数据传输,否则,也会加重观察者的处理逻辑

例讲观察者模式

相信很多年轻人买不起房子,看到房子价格变化总会有感慨,这就是一个观察者模式的例子,大家都在关注房价,我们正好作为一个例子,来讲解应用广泛的观察者模式

  • 首先实现我们的ObserverSubject抽象接口
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

Java设计模式(五) Observer(观察者)模式及Tomcat引申的相关文章

Java设计模式(四) Facade(门面)模式及Tomcat引申

基本概念 Facade的概念 为子系统中的一组接口提供一个统一接口.Facade模式定义了一个更高层的接口,使子系统更加容易使用. 我们需要以一种比原有方式更简单直接的办法与系统交互,对于讨论的复杂系统我们只有针对性地使用它的一个子集 因为Facade模式可以封装多个子系统,可以减少客户必须处理的对象的数量 要求一个子系统的外部与内部的通信必须通过一个统一的对象进行.也就是说Facade对象是外界对于子系统的唯一通道,可以用来整合内部杂乱无章的子系统,不管是否败絮其中,都能做到金玉其外 Faca

Java设计模式(六) Command(命令模式)及Tomcat引申

基本概念 Command 命令模式是一个高内聚的模式(满足单一职责原则) 概念:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 命令模式在项目中频繁使用,封装性和拓展性都有很好的保障 Command模式中的角色分工: Client:创建一个命令并决定接受者 Command:命令接口,定义一个抽象方法 Concrete Command:具体命令,负责调用接受者的相关操作 Invoker:请求者,负责调用命令对象执行请求 R

Java设计模式(五) 之 工厂模式

源码均以JDK1.8作为参考 1.定义: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到子类. 2.解析: 可能乍一看Factory设计模式的定义有点晕,但是细想想Factory的字面含义,其实也是很好理解的,所谓工厂,就是按照指定的需求生产出一些产品,Factory设计模式也不例外,是按照提供给Factory的需求说明,然后Factory按照需求生产出指定的产品,供调用的应用场景使用. 通用类图: 类图解析: 2.1.Product(抽象产品类) 定义产品

设计模式之Observer(观察者)模式

需求: 有一个报社,用户可以随时订阅报纸,也可以随时取消订阅.当每天的新闻来的时候,报社用邮递员投递给订阅了报纸的用户.订阅者有老人.小孩和青年.   分析: 报社相当于被观察的对象,用户相当于观察者,一旦新闻有更新,报社就通知所有观察者.   类图:     扩展:  该类图使用的是"推"的方式将新闻推送给订阅者.还可以使用一种的"拉"的方式实现,在Update传递空参数,只是通知订阅者数据有更新,然后由订阅者自己去报社获取(GetNews).这种方式实现起来更麻

Java 设计模式(八) Proxy(代理)模式及Spring引申

Proxy 基本概念 代理模式(Proxy pattern)是一种使用率非常高的模式: 为其他对象提供一种代理以控制对这个对象的访问 代理模式也叫作委托模式,它是一项基本设计技巧 Proxy中的角色 Subject(抽象主题类):既可以是抽象类也可以是抽象的接口 RealSubject(具体的主题角色):是被委托角色或者说是被代理角色 Proxy(代理主题角色):是委托类或者代理类: 它负责对真实的角色的应用 把Subject定义的方法限制委托给RealSubject实现 在RealSubjec

Java 设计模式(九) Strategy(策略)模式及Spring引申

Strategy 基本概念 策略模式(Strategy Pattern): 定义一组算法,将每个算法都封装起来,并且他们之间可以互换. 使用面向对象的继承和多态机制实现 Strategy中的角色: Context封装角色: 它叫做上下文角色,起承上启下的封装作用,屏蔽高层模块对策略.算法的直接访问,封装可能存在的变化. Strategy抽象策略角色: 策略,算法家族的抽象,通常为接口,定义每个策略或算法的必须具有的算法和属性. Concrete Strategy具体策略角色: 实现抽象策略中的操

java设计模式之 装饰器模式

适AT java设计模式之 装饰器模式 装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,动态给一个对象添提供了额外的功能. 我们通过下面的实例来演示装饰器模式的用法.模拟一个人从想吃饭.找饭店.享受美食.结束吃饭的过程 代码展示: 首先创建一个被修饰的接口 Eat package deco

图解Java设计模式之职责链模式

图解Java设计模式之职责链模式 学校OA系统的采购审批项目 :需求是 传统方案解决OA系统审批,传统的设计方案 职责链模式基本介绍 职责链模式解决OA系统采购审批 职责链模式在SpringMVC框架应用的源码 职责链模式的注意事项和细节 学校OA系统的采购审批项目 :需求是 采购员采购教学器材1)如果金额 小于等于 5000,由教学主任审批 (0<=x<=5000)2)如果金额 小于等于 10000,由院长审批(5000 < x <= 10000)3)如果金额 小于等于 3000

一起学java设计模式--适配器模式(结构型模式)

适配器模式 现有一个接口DataOperation定义了排序方法sort(int[]) 和查找方法search(int[], int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法,类BinarySearch 的binarySearch(int[], int)方法实现了二分查找算法.现使用适配器模式设计一个系统,在不修改源代码的情况下将类QuickSort和类BinarySearch的方法适配到DataOperation接口中.绘制类图并编程实现. (要求实现