框架模式-观察者模式

观察者模式:

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

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

角色概念:

  • 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值