观察者模式

观察者模式

    对象为一对多关系时,当修改对象,要自动通知其依赖的对象,这个时候就可以使用观察者模式,观察者模式属于行为型模式。

    例如双色球开奖,其开奖结果是发布在双色球官网,其开放了一个公共接口,我们可以通过这个接口拿到本期及往期的开奖数据,然后公布在自己的平台上,因此我们除了可以在双色球官网查看结果外,还可以在QQ、支付宝、TV等第三方平台上查看开奖结果。

    首先,我们来看一下通常的做法,分析他的缺点。

public class QQMessageInformation{
    private DoubleColorBallPublish doubleColorBallPublish;
    public QQMessageInformation(DoubleColorBallPublish doubleColorBallPublish){
    this.doubleColorBallPublish=doubleColorBallPublish;
    }
    public void send() {
        System.out.println("QQ Show Double Color Ball "+this.doubleColorBallPublish.getPublishTimes()+" Times:"+this.doubleColorBallPublish.getNumber());
    }
}
public class DoubleColorBallPublish {
    private Integer publishTimes;
    private String  number;
    private QQMessageInformation qqMessageInformation;
    public DoubleColorBallPublish(QQMessageInformation qqMessageInformation){
        this.qqMessageInformation=qqMessageInformation;
    }
    public Integer getPublishTimes() {
        return publishTimes;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number,Integer publishTimes) {
        this.number = number;
        this.publishTimes=publishTimes;
        showInformations();

    }

    public void showInformations(){
            qqMessageInformation.send();
    }
}

    DoubleColorBallPublish类是双色球官方发布开奖的一个类,其有发布时间和中奖号码两个属性,这里对QQ平台进行了接入,代码中聚合了QQMessageInformation类,在实例化DoubleColorBallPublish类的时候需要传入QQMessageInformation类,对该类进行管理。在setNumber方法中来设置此次中奖号码及当前发布时间,并同时调用showInformations()方法,通知第三方平台进行更新,showInformations()方法中为QQMessageInformation对象调用send()方法将信息通过自己平台推送出去。

    假如现在阿里平台也要接入平台获取双色球开奖信息,此时我们看如下代码:

public class ApliPayInformation{
    private DoubleColorBallPublish doubleColorBallPublish;
    public ApliPayInformation(DoubleColorBallPublish doubleColorBallPublish){
        this.doubleColorBallPublish=doubleColorBallPublish;
    }
    public void send() {
        System.out.println("AppliPay Show Double Color Ball "+this.doubleColorBallPublish.getPublishTimes()+" Times:"+this.doubleColorBallPublish.getNumber());
    }
}
public class DoubleColorBallPublish {
    private Integer publishTimes;
    private String  number;
    private QQMessageInformation qqMessageInformation;
    private ApliPayInformation apliPayInformation;
    public DoubleColorBallPublish(QQMessageInformation qqMessageInformation,ApliPayInformation apliPayInformation){
        this.qqMessageInformation=qqMessageInformation;
        this.apliPayInformation=apliPayInformation;
    }
    public Integer getPublishTimes() {
        return publishTimes;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number,Integer publishTimes) {
        this.number = number;
        this.publishTimes=publishTimes;
        showInformations();

    }

    public void showInformations(){
            qqMessageInformation.send();
            apliPayInformation.send();
    }

    我们可以看到在DoubleColorBallPublish类中又聚合了ApliPayInformation类,在构造方法中需要传入ApliPayInformation对象,在showInformations()方法中加上对ApliPayInformation的通知。那么如果我们再接入微信平台、TV平台呢,是不是都要按此步骤去添加,这样每加一个平台就要去修改代码,而且构造方法处还会变得越来越臃肿,显然,这不是一个很好的方式,那么,如何来修改呢,我们就借用观察者模式来改造我们的代码。



现在我们的结构设计如上图所示,具体代码如下

public abstract class Information {
    protected  DoubleColorBallPublish doubleColorBallPublish;
    public abstract void send();
}
public class QQMessageInformation extends Information{
    public QQMessageInformation(DoubleColorBallPublish doubleColorBallPublish){
    this.doubleColorBallPublish=doubleColorBallPublish;
    this.doubleColorBallPublish.pushInformation(this);
    }
    @Override
    public void send() {
        System.out.println("QQ Show Double Color Ball "+this.doubleColorBallPublish.getPublishTimes()+" Times:"+this.doubleColorBallPublish.getNumber());
    }
}
public class ApliPayInformation extends Information {
    public ApliPayInformation(DoubleColorBallPublish doubleColorBallPublish){
        this.doubleColorBallPublish=doubleColorBallPublish;
        this.doubleColorBallPublish.pushInformation(this);
    }
    @Override
    public void send() {
        System.out.println("AppliPay Show Double Color Ball "+this.doubleColorBallPublish.getPublishTimes()+" Times:"+this.doubleColorBallPublish.getNumber());
    }
}
public class TVInformation extends Information {
    public TVInformation(DoubleColorBallPublish doubleColorBallPublish){
        this.doubleColorBallPublish=doubleColorBallPublish;
        this.doubleColorBallPublish.pushInformation(this);
    }
    @Override
    public void send() {
        System.out.println("TV Show Double Color Ball "+this.doubleColorBallPublish.getPublishTimes()+" Times:"+this.doubleColorBallPublish.getNumber());
    }
}
public class DoubleColorBallPublish {
    private Integer publishTimes;
    private String  number;
    private List<Information>informations=new ArrayList<Information>();

    public Integer getPublishTimes() {
        return publishTimes;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number,Integer publishTimes) {
        this.number = number;
        this.publishTimes=publishTimes;
        showInformations();

    }

    public void pushInformation(Information information){
    informations.add(information);
    }
    public void showInformations(){
        for (Information information:informations) {
            information.send();
        }
    }
}

测试方法

public class KaiJiang {

    public static void main(String[] args) {
        DoubleColorBallPublish doubleColorBallPublish=new DoubleColorBallPublish();
        new TVInformation(doubleColorBallPublish);
        new QQMessageInformation(doubleColorBallPublish);
        new ApliPayInformation(doubleColorBallPublish);
        System.out.println("上一期开奖结果:");
        doubleColorBallPublish.setNumber("01 03 06 13 27 31 : 04 13",20170814);
        System.out.println("本期开奖结果:");
        doubleColorBallPublish.setNumber("02 03 09 15 24 30 : 02 19",20170817);
    }
}

测试结果


    简单说一下代码,这里抽象了一个Information父类,各个平台继承该类并重写自己的推送方法。DoubleColorBallPublish类中增加了List<Information>属性,用来管理注册到这里的各个平台。在setNumber()方法赋值的时候来发布信息,在showInformations()方法中依次遍历对所有注册到双色球中心的平台进行通知发布信息。各个平台实例中,创建对象时需要指定双色球服务中心,并调用双色球中心的注册方法将自己注册进去,在send()方法中用来推送最新的双色球服务中心的数据。

以上就是对观察者模式的介绍,本次介绍了观察者模式的使用场景及如何实现一个观察者模式。




阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39623859/article/details/80319493
个人分类: 23种设计模式
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭