框架模式-观察者模式

来源:互联网 发布:java void方法结束 编辑:程序博客网 时间:2024/05/29 11:43

观察者模式:

  • 概念:定义对象间的一种一对多的依赖关系。当一个对象的状态发生变化时,所有依赖它的对象都得到了通知并自动更新。

  • 一个软件系统里面包含了各种对象,就像一片欣欣向荣的森林充满了各种生物一样。在一篇森林中,各种生物彼此依赖和约束,形成一个个生物链。一种生物的状态变化会造成其它生物的相应行动,每一个生物都处于别的生物的互动中。

角色概念:

  • Subject(被观察者): 提供一个具体被观察者的接口,定义了添加,移除,通知等操作。
  • ConcreteSubject(具体被观察者):实现或者继承Subject,将有关状态存入具体观察者对象,在内部状态变化时,通知其内所有ConcreteObserver(具体观察者)。
  • Observer(抽象观察者):提供一个具体观察者的接口,定义了实现通知的方法。
  • ConcreteObserver(具体观察者):实现Observer,实现或者继承通知方法,根据不同的需求,添加自己的逻辑代码。

实现这样一个逻辑demo:当订阅一个微信公众号时,如果这个微信公众号,有新的推送消息,就会收到这个推送消息。这里,微信公众号就是一个被观察者(Subject),其中的一个公众号就是具体被观察者(ConcreteSubject)。全部的订阅者是观察者(Observer),其中的一个就是具体观察者(ConcreteObserver)。

观察者模式分为推模型和拉模型,这个是推模型:

Subject(公众号代码):

/** * Created by user on 2017/4/7. * 微信公众号 */public abstract class Subject{    //用来保存观察者对象    private List<Observer> observers=new ArrayList<>();    //实现被观察者的三个方法 attach 、detach、notifyObserver    /**     * 添加观察者(即一个订阅者订阅这个公众号)     */    public void attach(Observer observer){        observers.add(observer);    }    /**     *去除观察者(即一个订阅者取消订阅这个公众号)     */    public void detach(Observer observer){        observers.remove(observer);    }    /**msg     * 通知观察者(订阅号有新消息了,去通知每一个订阅者)     */    protected void notifyObserver(String msg){        for(Observer observer:observers){            observer.updateMsg(msg);        }    }}

ConcreteSubject(一个公众号):

/** * Created by user on 2017/4/7. * 一个具体的公众号 */public class ConcreteSubject extends Subject {    //更新的消息    private String msg;    public String getMsg(){        return msg;    }    /**     * 公众号有新的信息要推送了     */    protected void update(String newMsg){        msg=newMsg;        Log.i("Tag8","公众号要推送消息是:"+msg);        //把新消息推送给所有订阅者 这块子类如果进行复写,那么调用子类的,如果没有实现,就调用父类的        this.notifyObserver(msg);    }}

Observer(所有订阅者):

/** * Created by user on 2017/4/7. * 所有订阅者 */public interface Observer {    //更新公众号推送过来的信息    public void updateMsg(String msg);}

ConcreteObserver(一个订阅者):

/** * Created by user on 2017/4/7. * 一个具体的公众号 */public class ConcreteSubject extends Subject {    //更新的消息    private String msg;    public String getMsg(){        return msg;    }    /**     * 公众号有新的信息要推送了     */    protected void update(String newMsg){        msg=newMsg;        Log.i("Tag8","公众号要推送消息是:"+msg);        //把新消息推送给所有订阅者 这块子类如果进行复写,那么调用子类的,如果没有实现,就调用父类的        this.notifyObserver(msg);    }}

一个用户订阅一个公众号,并推送一条消息代码:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //获得这个公众号的对象        ConcreteSubject concreteSubject=new ConcreteSubject();        //获得这个用户对象        ConcreteObserver concreteObserver=new ConcreteObserver();        //用户去订阅这个公众号        concreteSubject.attach(concreteObserver);        concreteSubject.update("you are my sunshine");    }

这里直接用android代码里写了,就不写main函数了,上面可以去写多个类去实现Observer,每一个类都是一个用户,detach()就不去写了,取消订阅对应这步操作。

拉模型:
这个也用微信公众号举例,当我们订阅一个微信公众号是,很多时候都会看到底部下面的几个条目,当选择其中一个条目时,就会发过来对应的这条消息条目的信息。和推模型相比这个是选择性获取的,传递的不再是一个String类型的msg消息,而是一个Observer对象,接收这个对象,获取对象里面你所需要的消息。

与推模型相比,拉模型改动部分:

  • ConcreteSubject(用户接收的是推送过来的对象)
    /**msg     * 通知观察者(订阅号有新消息了,去通知每一个订阅者)     */    protected void notifyObserver(){        for(Observer observer:observers){            observer.updateMsg(this);        }    }
  • Observer(所有订阅者)
public interface Observer {    //更新公众号推送过来的信息    public void updateMsg(Subject subject);}
  • ConcreteObserver(一个订阅者)
public class ConcreteObserver implements Observer {    @Override    public void updateMsg(Subject subject) {        //得到的ConcreteSubject的对象        ConcreteSubject concreteSubject=(ConcreteSubject)subject;        //通过这个对象,我们获取指定的想要拉取的消息        Log.i("Tag8","用户接收到的消息是:"+concreteSubject.getMsg());    }}

拉模型完成代码:

/** * Created by user on 2017/4/7. * 微信公众号 */public abstract class Subject{    //用来保存观察者对象    private List<Observer> observers=new ArrayList<>();    //实现被观察者的三个方法 attach 、detach、notifyObserver    /**     * 添加观察者(即一个订阅者订阅这个公众号)     */    public void attach(Observer observer){        observers.add(observer);    }    /**     *去除观察者(即一个订阅者取消订阅这个公众号)     */    public void detach(Observer observer){        observers.remove(observer);    }    /**msg     * 通知观察者(订阅号有新消息了,去通知每一个订阅者)     */    protected void notifyObserver(){        for(Observer observer:observers){            observer.updateMsg(this);        }    }}
/** * Created by user on 2017/4/7. * 一个具体的公众号 */public class ConcreteSubject extends Subject {    //更新的消息    private String msg;    public String getMsg(){        return msg;    }    /**     * 公众号有新的信息要推送了     */    protected void update(String newMsg){        msg=newMsg;        Log.i("Tag8","公众号要推送消息是:"+msg);        //把新消息推送给所有订阅者 这块子类如果进行复写,那么调用子类的,如果没有实现,就调用父类的        this.notifyObserver();    }}
public interface Observer {    //更新公众号推送过来的信息    public void updateMsg(Subject subject);}
public class ConcreteObserver implements Observer {    @Override    public void updateMsg(Subject subject) {        //得到的ConcreteSubject的对象        ConcreteSubject concreteSubject=(ConcreteSubject)subject;        //通过这个对象,我们获取指定的想要拉取的消息        Log.i("Tag8","用户接收到的消息是:"+concreteSubject.getMsg());    }}

结论:就写到这里了,有问题就说,再去修改,另外Java提供了观察者观察者Observer接口,和被观察者Observable抽象类,用的时候,直接实现和继承就可以了^…^~~

装载请标明:http://blog.csdn.net/zxyudia/article/details/69569375

0 0