观察者模式2种用法---结合代理模式实现

在安卓的内容提供者ContentProvider,RxJava都运用到了观察者模式
今天来了解并学习下观察者模式,希望在自己编写代码时候,更多的运用此模式

什么是观察者模式呢?
我是这样理解观察者模式的,当我去使用一个设计模式时候,我很喜欢将抽象的问题具体化
1、被观察者
2、被观察者的行为
3、观察者
4、观察者的行为
5、关联2者的类(简单的可以在被观察者里面去关联2者)

首先先来了解一个最简单的观察者模式,我就拿一个最经典的例子来解释
我和小明(观察者)去订报(观察者行为),邮局(被观察者)有报纸(被观察者行为)就会通知我和小明

那么首先来看观察者的方法吧,观察者里面只有一个接口,就是邮件给我报纸,我就有报纸了,只有这一个方法

ObserverInterface

package com.godinsec;
//订阅者
public interface ObserverInterface {
    // 有新的报纸了就会被执行通知
    void HasNewPaper();
}

再看来下观察者类的具体实现吧,也就是我和小明,对外提供了一个setP_name和 getP_name的方法
ObserverImpl

package com.godinsec;
public class ObserverImpl implements ObserverInterface {
    // 订阅者的名字
    private String p_name;
    public ObserverImpl(String f_name) {
        p_name = f_name;
    }
    public String getP_name() {
        return p_name;
    }
    public void setP_name(String p_name) {
        this.p_name = p_name;
    }
    // 告诉订阅者有新报纸了
    public void HasNewPaper() {
        System.out.println(p_name + "!! 有新的报纸了,请查收!");
    }
}

然后就该涉及到被观察者方法接口这块了,也就是邮局实体类的方法,其实邮局最好只有发送报纸的接口实现,哪些添加取消订阅者,最好抽取出来一个新的类,我们就先看看被观察者拥有订阅取消的功能吧
它里面只有添加和订阅,以及自己的方法,那就是发送报纸的功能
ObserveredInterface

package com.godinsec;
 public interface ObserveredInterface
   {
       //添加订阅者
       void RegisterSubscriber(ObserverInterface f_subScribe);
       //取消订阅
       void RemoveSubScriber(ObserverInterface f_subScribe);
       //发送报纸
       void SendPaper();
   }

继续看下被观察者,也就是我和小明的实体类
ObserveredImpl

package com.godinsec;
import java.util.ArrayList;
import java.util.List;
//人民日报
public class ObserveredImpl implements ObserveredInterface {
    private List<ObserverInterface> subList = new ArrayList<ObserverInterface>();
    public void RegisterSubscriber(ObserverInterface f_subScribe) {
        subList.add(f_subScribe);
    }
    public void RemoveSubScriber(ObserverInterface f_subScribe) {
        if (subList.indexOf(f_subScribe) >= 0) {
            subList.remove(f_subScribe);
        }
    }
    @Override
    public void SendPaper() {
        for (int i = 0; i < subList.size(); i++) {
            ObserverImpl observerImpl = (ObserverImpl) subList.get(i);
            System.out.println("----发报纸----"+observerImpl.getP_name());
            subList.get(i).HasNewPaper();
        }
    }
}

通过添加订阅的方式,然后在调用自己的方法SendPaper,去为每一个订阅者发送邮报,呵呵,这跟代理模式灰常像呀,如果你想了解代理模式,请戳如下链接:

静态、动态代理模式

最后看下测试类是如何实现的吧:
MyMainDemo

package com.godinsec;

public class MyMainDemo {
    public static void main(String[] args) {

        ObserveredImpl _paper = new ObserveredImpl();
        ObserverImpl _me = new ObserverImpl("我");
        ObserverImpl _XiaoMing = new ObserverImpl("小明");
        // 小明订报
        _paper.RegisterSubscriber(_XiaoMing);
        // 赵云订报
        // 刘备订报
        _paper.RegisterSubscriber(_me);
        // 有新报纸了
        _paper.SendPaper();

        System.out.println("---------------发完报纸了------------------");
        // 小明不想订了,取消报纸
        _paper.RemoveSubScriber(_XiaoMing);
        // 又有新报纸了 就没有小明的报纸 了
        _paper.SendPaper();

    }
}

看下日志输出:

----发报纸----小明
小明!! 有新的报纸了,请查收!
----发报纸----
我!! 有新的报纸了,请查收!
---------------发完报纸了------------------
----发报纸----
我!! 有新的报纸了,请查收!


我们来改进改进上面那个观察者模式
以上就是一个灰常简单的观察者模式,那么我们接下来进行改造,邮局只有发送邮报的方法,让订阅取消订阅方法抽取出来

观察者及其观察者的方法没有做更改还是如下的代码:
ObserverInterface

package com.godinsec;
//订阅者
public interface ObserverInterface {
    // 有新的报纸了就会被执行通知
    void HasNewPaper();
}

ObserverImpl

package com.godinsec;
public class ObserverImpl implements ObserverInterface {
    // 订阅者的名字
    private String p_name;
    public ObserverImpl(String f_name) {
        p_name = f_name;
    }

    public String getP_name() {
        return p_name;
    }
    public void setP_name(String p_name) {
        this.p_name = p_name;
    }
    // 告诉订阅者有新报纸了
    public void HasNewPaper() {
        System.out.println(p_name + "!! 有新的报纸了,请查收!");
    }
}

接下来看被观察者类,及其接口方法,这个做了更改,只有发送邮报的功能,取消了,订阅和取消订阅的功能,代码如下:
ObserveredInterface

package com.godinsec;
import java.util.List;
public interface ObserveredInterface {
    // 发送报纸
    void SendPaper(List<ObserverInterface> subList);
}

ObserveredImpl

package com.godinsec;
import java.util.ArrayList;
import java.util.List;
//人民日报
public class ObserveredImpl implements ObserveredInterface {
    @Override
    public void SendPaper(List<ObserverInterface> subList) {
        for (int i = 0; i < subList.size(); i++) {
            ObserverImpl observerImpl = (ObserverImpl) subList.get(i);
            System.out.println("----发报纸----"+observerImpl.getP_name());
            subList.get(i).HasNewPaper();
        }
    }
}

最后我们新添加了一个控制类,就是将订阅,取消订阅摘出来了
ControllerInterface

package com.godinsec;
import java.util.List;
public interface ControllerInterface {
       //添加订阅者
    void RegisterSubscriber(ObserverInterface f_subScribe);
    //取消订阅
    void RemoveSubScriber(ObserverInterface f_subScribe);

    //发送报纸
    void SendPaper();
}

ControllerImpl

package com.godinsec;
import java.util.ArrayList;
import java.util.List;
public class ControllerImpl implements ControllerInterface{
    private List<ObserverInterface> subList = new ArrayList<ObserverInterface>();
    ObserveredImpl observeredImpl;
    @Override
    public void RegisterSubscriber(ObserverInterface f_subScribe) {
        subList.add(f_subScribe);
    }
    @Override
    public void RemoveSubScriber(ObserverInterface f_subScribe) {
        if (subList.indexOf(f_subScribe) >= 0) {
            subList.remove(f_subScribe);
        }
    }
    public ControllerImpl(ObserveredImpl observeredImpl) {
        super();
        this.observeredImpl = observeredImpl;   
    }
    @Override
    public void SendPaper() {
        observeredImpl.SendPaper(subList);
    }
}

最后来看下主界面代码把
MyMainDemo

package com.godinsec;

public class MyMainDemo {
    public static void main(String[] args) {

        ObserverImpl _me = new ObserverImpl("我");
        ObserverImpl _XiaoMing = new ObserverImpl("小明");

        ObserveredImpl _paper = new ObserveredImpl();

        ControllerInterface controllerImpl = new ControllerImpl(_paper);

        controllerImpl.RegisterSubscriber(_me);
        controllerImpl.RegisterSubscriber(_XiaoMing);

        // 有新报纸了
        controllerImpl.SendPaper();

        System.out.println("---------------发完报纸了------------------");
        // 小明不想订了,取消报纸
        controllerImpl.RemoveSubScriber(_XiaoMing);
        // 又有新报纸了 就没有小明的报纸 了
        controllerImpl.SendPaper();

    }
}

log输出如下:

----发报纸----
我!! 有新的报纸了,请查收!
----发报纸----小明
小明!! 有新的报纸了,请查收!
---------------发完报纸了------------------
----发报纸----
我!! 有新的报纸了,请查收!
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值