设计模式之观察者模式(有源码简单实现及java函数简单实现)

来源:互联网 发布:手机怎么变成2g网络了 编辑:程序博客网 时间:2024/05/23 13:34
 简介:观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。 观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。  观察者模式使用的六个重要的方面  1:确定目标与观察者的之间的关系(是多对一还是一对多等等)  2:它们之间的关系是单方向依赖(观察者和目标是单向依赖的主动权在目标手中)  3:命名建议    (1)目标接口的定义,建议在名称后面跟Subject    (2)观察者接口定义,建议在名称后面跟Observer    (3)观察者接口的更新方法,建议在名称为update  4:触发通知的时机(要在完成数据状态维护之后触发通知,不然会造成通知数据的错误)  5:观察者模式的调用顺序示意图  ![这里写图片描述](http://img.blog.csdn.net/20160604095036940)、  6:通知顺序(多个观察的顺序是平行的,互相不应该存在有依赖关系)建议以下情况下使用观察者模式1.当一个抽象模型有俩个方面,其中一个方面的操作依赖与另一个方面的状态变化2.如果在更改一个对象的时候需要连带修改其他的对象,而且不知道究竟应该有多少对象需要被连带修改3.当一个对象必须通知其他的对象,但是又希望这个对象和其他被他通知的对象时松散耦合的这就是观察者模式的一个简单的结构图

这里写图片描述
Attach:是注册观察者
Detach:是删除观察者
Notify:是通知所有的观察者
Update:获取目标类的状态同步到观察者的状态中
这里写图片描述
源码实现拉模型的例子:推模型就是把注释有拉模型的注释掉,把注释有推模型的释放出来
Observer.java

/** * @ClassName: Observer * @Description: 这是一个观察着的接口  定义一个更新的接口给那些在目标发生改变的时候被通知的对象 * @author: Administrator * @date: 2016年5月31日 下午3:55:32 */public interface Observer {    //观察者自动更新的接口   subject是传入目标对象的状态  方便获取相应的目标对象的状态    //public void update(WeatherSubject subject);//拉模型    public void update(String content);//推模型}

ConcreteWeatherSubject.java

/** * @ClassName: ConcreteSubject * @Description: 具体的一个目标对象  负责把有关状态存入相应的观察着对象中 * @author: Administrator * @date: 2016年5月31日 下午3:53:53 */public class ConcreteWeatherSubject extends WeatherSubject{    //目标对象的状态信息    private String weatherContent;    public String getWeatherContent() {        return weatherContent;    }    public void setWeatherContent(String weatherContent) {        this.weatherContent = weatherContent;        //这表示状态发生改变的时候就会通知每一个观察者        //this.notifyObservers();//拉模型        this.notifyObservers(weatherContent);//推模型    }} 

ConcreteObserver.java

/** * @ClassName: ConcreteObserver * @Description: 这是一个具体观察者对象  实现更新方法  是自身的状态和目标状态保持一致 * @author: Administrator * @date: 2016年5月31日 下午3:58:20 */public class ConcreteObserver implements Observer {    //观察者的状态名字    private String observerName;    //观察者所要知道的信息  这个消息从目标处获取    private String weatherContent;    //提醒的内容   不同的观察者要提醒不同的内容    private String remindThing;    //获取目标类的状态的同步道观察者的状态中    @Override    //public void update(WeatherSubject subject) {//拉模型    public void update(String content){//推模型        //weatherContent=((ConcreteWeatherSubject)subject).getWeatherContent();//拉模型        weatherContent=content;//推模型        System.out.println(observerName+"收到了"+weatherContent+","+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;    }}

WeatherSubject.java

import java.util.ArrayList;import java.util.List;/** * @ClassName: Subject * @Description: 目标对象  它知道观察它的观察着  并提供注册(添加)和删除观察者的接口 * @author: Administrator * @date: 2016年5月31日 下午3:50:47 */public class WeatherSubject {    //用来保存注册的观察者的对象    private List<Observer> observers = new ArrayList<Observer>();    //attach detach notifyObervers    //添加集合观察者    public void attach(Observer observer){        observers.add(observer);    }    //删除集合中的观察者    public void detach(Observer observer){        observers.remove(observer);    }    //通知所有注册的观察者对象//  protected void notifyObservers(){//拉模型    protected void notifyObservers(String content){//推模型        for(Observer observer:observers){            //observer.update(this);//拉模型            observer.update(content);//推模型        }    }}

测试运行的Client.java

public class Client {    public static void main(String[] args) {        //1创建一个目标        ConcreteWeatherSubject weather = new ConcreteWeatherSubject();        //2创建观察者        ConcreteObserver observerGril = new ConcreteObserver();        observerGril.setObserverName("姚鸿的女朋友");        observerGril.setRemindThing("第一次约会的地点,大连民族学院南门,不见不散哦");        ConcreteObserver observerBoy = new ConcreteObserver();        observerBoy.setObserverName("夏文齐");        observerBoy.setRemindThing("走,去吃饭");        //注册观察者        weather.attach(observerGril);        weather.attach(observerBoy);        //4目标发布的天气        weather.setWeatherContent("没下雨");    }}

直接用java的函数实现
这里写图片描述
Client.java

/** * @ClassName: Client * @Description: 测试类 * @author: Administrator * @date: 2016年5月31日 下午8:34:19 */public class Client {    public static void main(String[] args) {        //创建天气作为一个目标  也可以说是被观察        ConcreteWeatherSubject subject = new ConcreteWeatherSubject();        //创建一个观察者        ConcreteObserver gril =  new ConcreteObserver();        gril.setObserverName("小花");        //创建第二个观察者        ConcreteObserver boy = new ConcreteObserver();        boy.setObserverName("兄弟");        //注册观察者        subject.addObserver(gril);        subject.addObserver(boy);        //目标更新的情况        subject.setContent("今天天气不错哦");    }}

ConcreteObserver.java

import java.util.Observable;import java.util.Observer;/** * @ClassName: ComcreteObserver * @Description: 具体的观察者对象 * @author: Administrator * @date: 2016年5月31日 下午8:29:08 */public class ConcreteObserver implements Observer {    //观察者的名称对象    private String observerName;    @Override    public void update(Observable o, Object arg) {        //第一种是推的方式        System.out.println(observerName+"收到了消息,目标推送过来的是"+arg);        //第二种是拉的方式        System.out.println(observerName+"收到消息,主动到目标对象中去拉,拉的内容是"+        ((ConcreteWeatherSubject)o).getContent());    }    public String getObserverName() {        return observerName;    }    public void setObserverName(String observerName) {        this.observerName = observerName;    }}

ConcreteWeatherSubject.java

import java.util.Observable;//天气目标的具体实现类public class ConcreteWeatherSubject extends Observable{    //天气情况的内容    private String content;    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;        //天气情况有了  通知所有的观察者        //注意通知之前  在用java中的Observer模式的时候  下面的这句话不可少        this.setChanged();        //然后主动通知   notifyObservers()不带参数的是拉模型    带参数的推模型        this.notifyObservers(content);        //this.notifyObservers();//拉模型    }}
0 0
原创粉丝点击