组件协作之观察者模式

观察者模式

定义
  • 又叫做发布订阅模式。项目中经常使用。
  • 定义了对象间的一对多的依赖关系,每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
观察者模式的优点
  • 观察者和被观察者之间是抽象耦合。耦合关系通过接口来维系。
  • 支持广播通信。
观察者模式的缺点
  • 如果一个主题有多个直接或者间接的观察者,则通知所有的观察者会花费很多时间,且开发和调试都比较复杂。
  • 如果主题之间有循环依赖,被观察者会触发它们之间进行循环调用,导致系统崩溃。
  • 如果对观察者的通知是通过另外的线程进行异步投递的,系统必须保证投递的顺序执行。
  • 虽然观察者模式可以随时使观察者知道所观察的对象发生改变,但是没有提供相应的机制感知变化的形式。
观察者模式的应用场景
  • 关联行为场景。
  • 事件多级触发场景。
  • 跨系统的消息交换场景。如消息队列的处理机制。
观察者模式的注意事项
  • 广播链问题。一个观察者可以存在双重身份,既是观察者,又是被观察者,此时链路就会比较复杂,应保证最多只有一个双重身份的对象。
  • 异步处理问题。需要考虑线程安全和队列的问题。
代码

被观察者接口

public interface Clickable {
    // 单击
    void click();
    // 添加单击事件的观察者
    void addClickableObserver(ClickableObserver clickableObserver);
    // 移除单击事件的观察者
    void removeClickableObserver(ClickableObserver clickableObserver);
}

观察者接口

public interface ClickableObserver {
    // 发生单击事件
    void clicked(Clickable clickable);
}

被观察者实现类(Button)

public class Button implements Clickable {
    // 存储注册过的单击事件观察者
    List<ClickableObserver> observers = new ArrayList<>();

    //按钮信息
    String color; //颜色
    int x,y; //坐标

    @Override
    public void click() {
        System.out.println("按钮被单击");
        for (int i = 0;i < observers.size();++i){
            observers.get(i).clicked(this);
        }
    }

    @Override
    public void addClickableObserver(ClickableObserver clickableObserver) {
        observers.add(clickableObserver);
    }

    @Override
    public void removeClickableObserver(ClickableObserver clickableObserver) {
        observers.remove(clickableObserver);
    }

    @Override
    public String toString() {
        return "Button{" +
                "observers=" + observers +
                ", color='" + color + '\'' +
                ", x=" + x +
                ", y=" + y +
                '}';
    }
}

观察者实现类

  • 改变颜色观察者
public class ChangeColorObserver implements ClickableObserver{
    @Override
    public void clicked(Clickable clickable) {
        Button b = (Button) clickable;
        b.color = "红色";
    }
}
  • 改变坐标观察者
public class ChangeCoordinateObserver implements ClickableObserver {
    @Override
    public void clicked(Clickable clickable) {
        Button b = (Button) clickable;
        b.x = 100;
        b.y = 200;
    }
}
  • 其他观察者
public class OtherObserver implements ClickableObserver {
    @Override
    public void clicked(Clickable clickable) {
        System.out.println("执行其他方法...");
    }
}

主逻辑

public class Test {
    public static void main(String[] args) {
        Button button = new Button();
        button.color = "白色";
        button.x = 0;
        button.y = 1;

        button.addClickableObserver(new ChangeColorObserver());
        button.addClickableObserver(new ChangeCoordinateObserver());
        button.addClickableObserver(new OtherObserver());

        button.click();

        System.out.println(button);
    }
}
执行结果

在这里插入图片描述

图示

在这里插入图片描述

个人理解

下方三个观察者一直在监听被观察者的事件,一旦被观察者发生click事件,三者都会触发自身的clicked事件进行响应。动作的发生是由上层传向下层的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值