观察者模式

设计模式-观察者模式

定义:

在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
更直观的说可以叫做发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到。

两个角色:

  1. 被观察者:内部状态发生改变时,向观察者发出通知
  2. 观察者:收取被观察者的通知

应用场景:

  1. 基于消息发布订阅模式的应用
    1. 聊天软件
    2. 微博
    3. 在线购物等
  2. 在线游戏(MOBA游戏)

案例模拟:

被观察者抽象类:

public Subject(){
    observers = new ArrayList<>();

}
/**
 * 加关注
 * @param o 关注的人
 */
public void addObserver(Observer o){
    if (!observers.contains(o) && o != null){
        observers.add(o);

    }


}
/**
 * 取消关注
 * @param o
 */
public void removeObserver(Observer o){
    if (observers.contains(o)){
        observers.remove(o);

    }
}

/**
 * 消息通知
 * @param o
 */
public void notifyAllObserver(Object o){
    for (Observer observer : observers) {
        observer.update(this,o);
    }
}
public void notifyAllObserver(){
    for (Observer observer : observers) {
        observer.update(this, null);
    }

}

观察者接口

public interface Observer {
    /**
     * 接受消息通知更新
     * @param s 被观察者
     * @param object 消息类型
     */
    public void update(Subject s,Object object);
}

1. 商品降价通知

商品类

    public class Product extends Subject{
    //商品价格
    private double price;
    //商品名称
    private String name;
    public Product(String name) {
        super();
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    //价格变动通知买家
    public void setPrice(double price) {
        this.price = price;
        notifyAllObserver(new Double(price));
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

买家类:

    public class Buyer implements Observer{
    //接收商品降价通知
    @Override
    public void update(Subject s, Object object) {
        if (object instanceof Double){
            System.out.println("我降价了" +(Double)object);

        }
    }} 

测试类:

        Product niuzai = new Product("牛仔A");
        Buyer b1 = new Buyer();
        Buyer b2 = new Buyer();
        Buyer b3 = new Buyer();
        niuzai.addObserver(b1);
        niuzai.addObserver(b2);
        niuzai.addObserver(b3);
        niuzai.setPrice(35.5);

输出结果:
这里写图片描述
商品价格发生变化时通知关注的卖家
,也就是观察者。

2.仿MOBA游戏英雄类

public class Hero extends Subject implements Observer{
    //英雄位置
    private Position position;
    //名字
    private String name;
    public Position getPosition() {
        return position;
    }
    public void setPosition(Position position) {
        this.position = position;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Hero(Position position, String name) {
        super();
        this.position = position;
        this.name = name;
    }
    //移动函数,模拟英雄进行移动
    public void move(){
        this.position.setX(this.position.getX() + 3);
        this.position.setY(this.position.getY() + 2);
        notifyAllObserver();
    }
    /**
     * 模拟接收到其它英雄的位置
     */
    @Override
    public void update(Subject s, Object object) {

        if (s instanceof Hero){
            Hero hero = (Hero)s;
            System.out.println(this.name + "发现了 " + hero.getName() + "在" +hero.getPosition().toString());


        }
    }}

测试类

Hero ganjiang = new Hero(new Position(4,5),"干将莫邪");
        Hero hanxin = new Hero(new Position(-4,-5),"韩信");
        ganjiang.addObserver(hanxin);
        hanxin.addObserver(ganjiang);
        int  i = 0;
        while (i++ < 100){
            try {
                //模拟延迟实现数据逐步输出
                new Thread().sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            hanxin.move();
            ganjiang.move();
            }}

输出结果:
这里写图片描述
这种则是被观察者与观察者为一个类,即Hero即是观察者也是被观察者,这种类型还可以用到微博,聊天室等当中。

在Java当中也提供了被观察者抽象类Observable,与观察者接口Observer。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三寸花笺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值