模式的秘密-观察者模式(一)

学习观察者模式通用代码:

1,目标对象的定义

2,具体的目标对象定义。

3,再来看看观察者的接口定义

4,看看观察者的具体实现。

 先来一个通用的观察者模式实例:

1:定义一个目标对象:包含观察者的添加,删除,以及最重要的通知观察者方法(观察者对象调用自己的方法,方法参数是目标对象)

package com.ObserverPatternCommon;

import java.util.ArrayList;
import java.util.List;

/*
 * 目标对象,他知道观察它的观察者,并提高注册(添加)和删除观察者的接口
 * */
public class Subject {
    //保存注册的观察者对象
    private List<Observer> observers=new ArrayList<Observer>();
    
    //attach  detach  notifyObserver
    //添加观察者到集合中
    public void attach(Observer observer)
    {
        observers.add(observer);
    }
    //删除集合中的指定观察者
    public void detach(Observer observer)
    {
        observers.remove(observer);
    }
    
    //通知所有注册的观察者对象
    protected void notifyObservers()
    {
        for(Observer observer:observers)
        {
            observer.update(this);
        }
    }

}

2,建立一个具体的目标对象:继承目标对象,并且加上具体目标对象所需的方法:一个目标对象状态的设置和获取,在设置状态的时候,通知观察者。

package com.ObserverPatternCommon;

/*
 * 具体的目标对象,负责把有关状态存入到相应的观察者对象中
 * */
public class ConcreteSubject extends Subject {

    //保存目标对象的状态
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        this.notifyObservers();//状态发生改变了,就通知所有的观察者
    }
}

3,建立观察者接口:

package com.ObserverPatternCommon;

/*
 * 这是一个观察者接口,定义一个更新的接口给哪些在目标发生改变的时候被通知的对象
 * */
public interface Observer {

    //更新的接口,subject表示传入目标对象,方便获取相应的目标对象状态
    public void update(Subject subject);
    
}

4,建立具体的观察者接口:因为观察者被目标对象通知的时候,需要观察者调用自己的方法,这里的update。

package com.ObserverPatternCommon;

/*
 * 具体的观察者对象,实现更新的方法,使自身和目标的状态保持一致
 * */
public class ConcreteObserver implements Observer {

    //观察者的状态
    private String observerState;
    
    /*
     * 获取目标类的状态,同步到观察者的状态中
     * */
    @Override
    public void update(Subject subject) {
        observerState=((ConcreteSubject)subject).getSubjectState();
    }

}

上面就是观察者模式通用的结构。

下面以一个具体例子来说:当天气变化的时候,需要通知所有注册的观察者用户(如这里的女朋友和老妈)。

第一步:建立天气目标对象类:包括用户注册方法,用户注销方法,用户通知方法

package WeatherObserverPattern;

import java.util.ArrayList;
import java.util.List;

/*
 * 目标对象,他知道观察它的观察者,并提高注册(添加)和删除观察者的接口
 * */
public class WeatherSubject {
    //保存注册的观察者对象
    private List<Observer> observers=new ArrayList<Observer>();
    
    //attach  detach  notifyObserver
    //把订阅天气的人添加到订阅者列表中
    public void attach(Observer observer)
    {
        observers.add(observer);
    }
    //删除集合中的指定订阅天气的人
    public void detach(Observer observer)
    {
        observers.remove(observer);
    }
    
    //通知所有已经订阅天气的人
    protected void notifyObservers()
    {
        for(Observer observer:observers)
        {
            observer.update(this);
        }
    }

}

第二步:建立具体的天气目标对象类:包含天气信息方法,当改变天气信息的时候,调用通知用户方法。

package WeatherObserverPattern;

/*
 * 具体的目标对象,负责把有关状态存入到相应的观察者对象中
 * */
public class ConcreteWeatherSubject extends WeatherSubject {

    //获取天气的内容信息
    private String weatherContent;
    
    public String getWeatherContent() {
        return weatherContent;
    }

    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
        //内容有了,说明天气更新了,通知所有的订阅的人
        this.notifyObservers();
    }
}

第三步:定义用户观察者接口:包含一个更新接口

package WeatherObserverPattern;

/*
 * 这是一个观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象
 * */
public interface Observer {

    //更新的接口,subject表示传入目标对象,方便获取相应的目标对象状态
    public void update(WeatherSubject subject);
    
}

第四步:定义用户观察者具体类:包含变量:用户名字,不同用户的提醒信息,以及用来接收天气信息的变量。当天气类通知用户,用户会调用update方法,并且传入

天气类对象,通过天气类对象获取天气信息。

package WeatherObserverPattern;

/*
 * 具体的观察者对象,实现更新的方法,使自身和目标的状态保持一致
 * */
public class ConcreteObserver implements Observer {
    
    //观察者的名字,是谁收到了这个讯息,黄明的女朋友海事他老妈
    private String observerName;
    //天气的内容情况,这个消息从目标处获取
    private String weatherContent;
    //提醒的内容,黄明的女朋友提醒约会,而他老妈则提醒购物
    private  String remindThing;
    
    public String getObserverName() {
        return observerName;
    }
    public void setObserverName(String observerName) {
        this.observerName = observerName;
    }
    public String getWeatherContent() {
        return weatherContent;
    }
    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
    }
    public String getRemindThing() {
        return remindThing;
    }
    public void setRemindThing(String remindThing) {
        this.remindThing = remindThing;
    }    
    /*
     * 获取目标类的状态,同步到观察者的状态中
     * */
    @Override
    public void update(WeatherSubject subject) {
        weatherContent=((ConcreteWeatherSubject)subject).getWeatherContent();
        System.out.println(observerName+"收到了:"+weatherContent+","+remindThing);
    }

}

最后:实现该天气信息通知用户的调用。

package WeatherObserverPattern;

public class Client {

    public static void main(String[] args) {

        //1,创建目标
        ConcreteWeatherSubject weather=new ConcreteWeatherSubject();
        //2,创建观察者
        ConcreteObserver observerGirl=new ConcreteObserver();
        observerGirl.setObserverName("黄明的女朋友");
        observerGirl.setRemindThing("是我们的第一次约会,地点街心公园");
        
        ConcreteObserver observerMum=new ConcreteObserver();
        observerMum.setObserverName("老妈");
        observerMum.setRemindThing("是一个购物的好日子,明天去天虹扫货");
        
        //3,注册观察者
        weather.attach(observerGirl);
        weather.attach(observerMum);
        //4,目标发布天气
        weather.setWeatherContent("明天 天气晴朗,蓝天白云,气温28度");
    }

}

执行结果:

黄明的女朋友收到了:明天 天气晴朗,蓝天白云,气温28度,是我们的第一次约会,地点街心公园
老妈收到了:明天 天气晴朗,蓝天白云,气温28度,是一个购物的好日子,明天去天虹扫货

猜你喜欢

转载自www.cnblogs.com/alsf/p/8939647.html