观察者模式详解以及代码实现

1、简介:

当对象之间存在一对多关系时,则使用观察者模式。当目标对象发送变化时,则通知他所依赖的所有对象(观察者对象)更新状态。

2、优点:

2.1 观察者与被观察者之间是抽象耦合的
2.2 建立了一套触发机制

3、缺点:

3.1 当一个被观察者有很多直接或间接的观察者时,将所有的观察者通知到会花费大量时间
3.2 如果观察者与目标对象之间存在循环依赖的话,目标对象会触发它们之间的循环调用,可能导致系统崩溃
3.3 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

4、注意事项

4.1 JAVA 中已经有了对观察者模式的支持类。
4.2 避免循环引用。
4.3如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

5、实现

5.1 创建三个类Subject、Observer、Client

	5.1.1 Subject是目标对象或目标对象的父类
		5.1.1.1 目标对象中应该有一个存放所有观察者的容器以及一个通知方法
		5.1.1.2 通知方法中遍历每个观察者,调用Observer中接口的方法(update())进行更新
	5.1.2 Observer是观察者接口和实现了接口的实体类
	5.1.3 Client是进行测试的客户端

5.2 代码

5.2.1 创建Observer接口

package pattern;
//观察者接口
public interface Obsever {
    //调用update()更新观察者的状态
    void update(Subject subject);
}

5.2.2 创建主题Subject-目标对象及目标对象的父类

public class Subject {
    private List<Obsever> obsevers = new ArrayList<>();
    //注册观察者
    public void register(Obsever obsever){
        obsevers.add(obsever);
    }
    //移除观察者
    public void remove(Obsever obsever){
        obsevers.remove(obsever);
    }
    //通知所有订阅者更新状态
    public void notify(Subject subject){
        for (Obsever obsever : obsevers) {
            obsever.update(subject);
        }
    }
}

5.2.3 创建目标对象实体类

public class ConcreateSubject extends Subject {
    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        //目标对象的状态发送变化,通知所有的订阅者进行状态更新
        this.notify(this);
    }
}

5.2.4 创建观察者实体类

public class ObseverA implements Obsever {
    private int myState;//myState的值需要与目标对象的state的值保持一致

    public int getMyState() {
        return myState;
    }

    public void setMyState(int myState) {
        this.myState = myState;
    }

    @Override
    public void update(Subject subject) {
        this.myState =((ConcreateSubject)subject).getState();
    }
}

5.2.5 创建Client进行测试

public class Client {
    public static void main(String[] args) {
        //消息发布者
        ConcreateSubject concreate = new ConcreateSubject();

        //创建多个观察者对象
        ObseverA obsever1=new ObseverA();
        ObseverA obsever2=new ObseverA();
        ObseverA obsever3=new ObseverA();

        //将多个观察者进行注册/订阅
        concreate.register(obsever1);
        concreate.register(obsever2);
        concreate.register(obsever3);

        concreate.setState(100);
        System.out.println(obsever1.getMyState());
        System.out.println(obsever1.getMyState());
        System.out.println(obsever1.getMyState());
        System.out.println("#################");

        concreate.setState(300);
        System.out.println(obsever1.getMyState());
        System.out.println(obsever1.getMyState());
        System.out.println(obsever1.getMyState());
    }
}

5.2.6 测试结果
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值