前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式之观察者模式

设计模式之观察者模式

作者头像
用户2781897
发布2020-11-25 17:34:39
3240
发布2020-11-25 17:34:39
举报
文章被收录于专栏:服务端思维服务端思维

观察者设计模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

当我们在打团队游戏时,当你受到攻击需要队友帮忙时该怎么办?

这时候就需要给你所有的队友发送一条你正在被攻击的消息。所有的队友会根据你发送的消息作出相应的动作。比如有团队意识来帮你,或者不帮你继续玩自己的。

这里面的队员就是该设计模式名字中的观察者。那么受到攻击的自己的是什么呢。被观察者?不,准确的我们称之为目标或者主题。

所以整个流程大概就是:当目标(主题)的状态发送改变时就会通知观察者,观察者根据自己的情况做出相应的动作。

代码语言:javascript
复制
import java.util.Observable;

/**
 * @Author gaotian
 * @Description 具体目标类 Subject 继承抽象类并实现通知观察者的方法
 * 它拥有自己的状态,当它的状态的改变时就会通知各个观察者。
 * @Date 9:01 2020/6/23
 **/
public class Subject extends Observable {

    /**
     * Observable 它是指被观察的对象。我们在主题中定义一个观察者集合。
     * 一个观察者对象可以接收任意多个观察者。同时提供了一系列的方法管理这些观察者。
     **/


    /**
     * @Author gaotian
     * @Description //开启改变状态
     * @Date 15:45 2020/6/23
     **/
    @Override
    protected synchronized void setChanged() {
        super.setChanged();
    }

}
代码语言:javascript
复制
import java.util.Observable;
import java.util.Observer;

/**
 * @Author gaotian
 * @Description
 * 具体观察者中会维护一个指向具体目标对象的引用,它存储了具体观察者的状态,这些状态和具体目标的状态要保持一致。
 *
 * 它实现了抽象观察者对象的updata方法。
 *
 * 通常在实现时,可以调用具体目标的attach和detach方法将自己加入到集合中或者从集合中剔除。
 * @Date 9:06 2020/6/23
 **/
public class ConcreteObserver implements Observer {

    private String observerName;

    public ConcreteObserver(String observerName) {
        this.observerName = observerName;
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println(observerName + "我要更新一下我的状态了......");
        System.out.println("目标类为:" + o);
        System.out.println("参数为 = " + arg);
    }
}
代码语言:javascript
复制
import java.util.Observable;
import java.util.Observer;

/**
 * @Author gaotian
 * @Description 第二个具体的观察者,测试是否能够同时收到消息并更新状态
 * @Date 9:09 2020/6/23
 **/
public class ConcreteOberverOther implements Observer {

    private String observerName;

    public ConcreteOberverOther(String observerName) {
        this.observerName = observerName;
    }


    @Override
    public void update(Observable o, Object arg) {
        System.out.println(observerName + "我要更新一下我的状态了......");
        System.out.println("目标类为:" + o);
        System.out.println("参数为 = " + arg);
    }
}
代码语言:javascript
复制
import java.util.Observer;

public class NotifyMain {

    public static void main(String[] args) {

        Subject subject = new Subject();
        subject.setChanged();

        Observer observer = new ConcreteObserver("观察者一号");
        Observer observer2 = new ConcreteOberverOther("观察者二号");

        //将观察者都加入观察者列表中
        subject.addObserver(observer);
        subject.addObserver(observer2);

        //通知观察者
        boolean hasChanged = subject.hasChanged();
        System.out.println("hasChanged = " + hasChanged);

        subject.notifyObservers("123");

    }
    /**
     * 1.主要优点
     *
     * (1)观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息传递机制,并抽象了更新接口,使得可以有各种各样的表示层充当具体的观察者角色。
     *
     * (2)观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察者对象只需要维持一个抽象观察者的集合,无需了解其具体观察者。
     *
     * (3)观察者模式支持广播通信,观察目标会向所有已注册的观察者发送通知,降低了一对多系统的设计难度。
     *
     * (4)观察者模式满足开闭原则的要求,增加新的具体观察者无须修改原有的系统代码。
     *
     * 2.主要缺点
     *
     * (1)如果一个观察目标对象有很多的直接观察者和间接观察者,那么所有的观察者接收到消息会耗费大量的时间。
     *
     * (2)如果观察者和被观察者之间存在循环依赖,那么观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
     *
     * (3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道目标观察对象发生了变化。
     **/

}

1.主要优点 (1)观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息传递机制,并抽象了更新接口,使得可以有各种各样的表示层充当具体的观察者角色。 (2)观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察者对象只需要维持一个抽象观察者的集合,无需了解其具体观察者。 (3)观察者模式支持广播通信,观察目标会向所有已注册的观察者发送通知,降低了一对多系统的设计难度。 (4)观察者模式满足开闭原则的要求,增加新的具体观察者无须修改原有的系统代码。 2.主要缺点 (1)如果一个观察目标对象有很多的直接观察者和间接观察者,那么所有的观察者接收到消息会耗费大量的时间。 (2)如果观察者和被观察者之间存在循环依赖,那么观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 (3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道目标观察对象发生了变化。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 服务端思维 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档