java-观察者模式【行为型模式】

行为型模式[观察者模式]

观察者模式就是定义对象之间的一对多依赖,这样一来,当一个对象状态发生改变时,它的所有依赖者都会收到通知并自动更新。 这样的好处就是两个或多个对象之间松耦合,它们依然可以交互,但不太清楚彼此的细节。观察者模式提供了一种对象的设计,让主题和观察者之间松耦合。松耦合的设计可以让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。

应用场景:
1、当一个抽象模型包含两个方面内容,其中一个方面依赖于另一个方面。
2、其他一个或多个对象的变化依赖于另外一个对象的变化。
3、实现类似广播机制的功能,无需知道具体收听者,只需分发广播,系统中感兴趣的对象会自动连接接收该广播。
4、多层级嵌套使用,形成一种链式触发机制,使用事件具备跨域(跨越两种观察者类型)通知。

观察者模式通用的UML类图
在这里插入图片描述
抽象主题(IMianHero):指被观察的对象。该角色是一个抽象类或者接口定义了增加,删除,通知观察者对象的方法。
具体主题(MianHero):具体背观察者,当其内状态变化时,会通知已注册的观察者。
抽象观察者(IHero):定义了响应接收通知。
具体观察者(Hero):在得到状态更新时,会自动作出回应。

观察者应用场景代码

// 抽象被观察者
public interface IMianHero {

    void addHero(IHero IHero);

    void notify(String context);
}
// 实现被观察者
public class MianHero implements IMianHero {

    private final List<IHero> IHeroes = new ArrayList<>();

    private String name;
    private String context;

    public MianHero(String name) {
        this.name = name;
    }

    @Override
    public void addHero(IHero IHero) {
        IHeroes.add(IHero);
    }

    @Override
    public void notify(String context) {
        if (CollectionUtils.isEmpty(IHeroes)) {
            return;
        }
        System.out.println(this.name+"发送了一条:"+context);
        this.context = context;
        for (IHero IHero : IHeroes) {
            IHero.receive(this);
        }
    }

    @Override
    public String toString() {
        return this.name+"英雄发送了"+this.context+"消息给你们";
    }
}
// 抽象观察者接口
public interface IHero {

    void receive(IMianHero context);
}
// 具体观察者
public class Hero implements IHero {

    private String name;

    public Hero(String name) {
        this.name = name;
    }
    @Override
    public void receive(IMianHero mianHero) {
        System.out.println(this.name+" 英雄收到来之"+mianHero);
        System.out.println("收到收到ovov\n");
    }
}
public class Test {
    public static void main(String[] args) {
        IMianHero iMianHero = new MianHero("大桥");
        iMianHero.addHero(new Hero("小乔"));
        iMianHero.addHero(new Hero("马超"));
        iMianHero.addHero(new Hero("典韦"));
        iMianHero.addHero(new Hero("张良"));
        iMianHero.notify("辅助不见了,快跑。");
    }
}

JDK原生的观察者模式

// 消息体
public class Context {
    private String context;

    public Context(String context) {
        this.context = context;
    }

    public String getContext() {
        return this.context;
    }
}
// 观察者对象
public class Hero implements Observer {
    private String name;
    public Hero(String name) {
        this.name = name;
    }
    @Override
    public void update(Observable o, Object arg) {// o = 被观察者对象,arg 传入的参数
        MianHero mianHero = (MianHero) o;
        Context context = (Context) arg;
        System.out.println(name+"收到来之 " +mianHero.getName()+" 发送的消息:"+context.getContext());
        System.out.println("收到收到ovov\n");
    }
}
// 被观察者对象
public class MianHero extends Observable {
    private String name;

    public MianHero(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    void notify(String context){
        Context c = new Context(context);
        setChanged();
        notifyObservers(c);
    }
}
public class Test {
    public static void main(String[] args) {
        MianHero mianHero = new MianHero("小乔");
        mianHero.addObserver(new Hero("张三"));
        mianHero.addObserver(new Hero("赵云"));
        mianHero.addObserver(new Hero("大桥"));
        mianHero.addObserver(new Hero("花木兰"));
        mianHero.notify("中路不见了,中路不见了");
    }
}

google的观察者模式配置

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>
// 观察者对象
public class LvBu {
    private String name = "吕布";
    private String context;

    public LvBu(String context) {
        this.context = context;
    }
    @Override
    public String toString() {
        return this.name+"收到发送的:"+ context +"消息";
    }
}
public class WangZhaoJun {
    private String name = "王昭君";
    private String context;

    public WangZhaoJun(String context) {
        this.context = context;
    }
    @Override
    public String toString() {
        return this.name+"收到发送的:"+ context +"消息";
    }
}
public class ZhaoYun {
    private String name = "赵云";
    private String context;

    public ZhaoYun(String context) {
        this.context = context;
    }
    @Override
    public String toString() {
        return this.name+"收到发送的:"+ context +"消息";
    }
}
// 事件触发场景  采用责任链触发形式
public class Event {
    @Subscribe
    public void observer(LvBu lvBu) {
        System.out.println("参数名称:lvBu");
        System.out.println(lvBu);
    }
    @Subscribe
    public void observer(WangZhaoJun wangZhaoJun) {
        System.out.println("参数名称:wangZhaoJun");
        System.out.println(wangZhaoJun);
    }
    @Subscribe
    public void observer(ZhaoYun zhaoYun) {
        System.out.println("参数名称:zhaoYun");
        System.out.println(zhaoYun);
    }
    @Subscribe
    public void observer(Object o) {
        System.out.println("参数名称:Object");
        System.out.println(o);
    }
}
public class Test {
    public static void main(String[] args) {
        EventBus eventBus = new EventBus();
        eventBus.register(new Event());
        eventBus.post(new LvBu("快跑快跑"));
        eventBus.post(new WangZhaoJun("快跑快跑"));
        eventBus.post(new ZhaoYun("快跑快跑"));
    }
}

观察者的优缺点
优点:
1、观察者和被观察者是松耦合(抽象耦合)分开的,符合依赖倒置原则。
2、分离了表示层(观察者)和数据逻辑层(被观察者),并且建立了一套触发机制,使得数据的变化可以响应到多个表示层上。
3、实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察者触发事件时,只有感兴趣的观察者可以接收到通知。
缺点:
1、如果观察者数量过多,则事件通知会耗时较长。
2、事件通知呈线性关系,如果其中一个观察者处理事件卡壳,会影响后续的观察者接收该事件。
3、如果观察者和被观察者之间存在循环依赖,则可能造成两者之间的循环调用,导致系统死循环崩溃状态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值