【设计模式】20.行为型模式-观察者(Observer)

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路【设计模式】20.行为型模式-观察者(Observer),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、描述

  定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。也称为发布-订阅模式。

  角色:

  1.抽象目标类:除自身业务逻辑外,包含增加、删除、唤醒观察者功能。

  2.具体目标类:为那些在目标发生改变时需获取通知的对象定义一个更新接口。

  2.抽象观察类:定义响应抽象方法。

  3.具体观察类:继承抽象观察类,实现抽象方法。

  类图:

【设计模式】20.行为型模式-观察者(Observer)

 二、优点

  1.目标和观察者之间的耦合是最小的。一个目标所知道的仅仅是它有一系列的观察者,但是不知道这些观察者是哪些类,目标类只需要负责通知就可以了。

  2.支持广播通信。通知被自动广播给所有已向该目标对象登记的有关对象。

三、缺点

  1.意外的更新。因为一个观察者并不知道其他观察者的存在,它可能对改变目标的最终代价一无所知。

  2.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会话费很多的时间。

  3.如果观察者和观察目标之间有循环依赖的话,观察目标会触发他们之间进行循环调用,可能导致系统崩溃。

 四、适用场景

  1.当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变

  2.当一个对象必须通知其他对象,而它又不能假定其他对象是谁。

五、示例

  以“交通灯亮,其他对象针对交通灯不同的颜色作出不同反应为例”。

  1.抽象观察者类

public abstract class AbstractObserver {
    /**
     * 作出反应
     *
     * @param type
     */
    abstract void update(Integer type);
}

  2.具体观察者类,汽车、行人、自行车等

  (1)汽车

public class CarObserver extends AbstractObserver {
    @Override
    void update(Integer type) {
        System.out.print("我是轿车:");
        if (Objects.equal(type, 1)) {
            System.out.println("踩刹车,停车");
        } else if (Objects.equal(type, 2)) {
            System.out.println("开始行驶");
        } else if (Objects.equal(type, 3)) {
            System.out.println("缓慢行驶");
        }
    }
}

  (2)行人

public class PedestriansObserver extends AbstractObserver {
    @Override
    void update(Integer type) {
        System.out.print("我是行人:");
        if (Objects.equal(type, 1)) {
            System.out.println("原地站立");
        } else if (Objects.equal(type, 2)) {
            System.out.println("行走");
        } else if (Objects.equal(type, 3)) {
            System.out.println("行走,注意车辆");
        }
    }
}

  (3)自行车

public class BikeObserver extends AbstractObserver {
    @Override
    void update(Integer type) {
        System.out.print("我是自行车:");
        if (Objects.equal(type, 1)) {
            System.out.println("捏闸,停车");
        } else if (Objects.equal(type, 2)) {
            System.out.println("开始骑行");
        } else if (Objects.equal(type, 3)) {
            System.out.println("骑行,注意车辆");
        }
    }
}

  3.抽象目标类

public abstract class AbstractSubject {
    public List<AbstractObserver> observerList = new ArrayList<>();

    public void addObservers(AbstractObserver observer) {
        observerList.add(observer);
    }

    public void removeObserver(AbstractObserver observer) {
        observerList.remove(observer);
    }

    /**
     * 当前目标的行为
     *
     * @param type
     */
    public abstract void doAction(Integer type);
}

  4.具体目标类,交通灯类

public class TrafficFlightSubject extends AbstractSubject {
    @Override
    public void doAction(Integer type) {
        if (Objects.equal(type, 1)) {
            System.out.println("红灯亮");
        } else if (Objects.equal(type, 2)) {
            System.out.println("绿灯亮");
        } else if (Objects.equal(type, 3)) {
            System.out.println("黄灯亮");
        }
        for (AbstractObserver observer : observerList) {
            observer.update(type);
        }
    }
}

  5.测试类

public class Client {
    public static void main(String[] args) {
        TrafficFlightSubject subject = new TrafficFlightSubject();

        CarObserver carObserver = new CarObserver();
        subject.addObservers(carObserver);

        PedestriansObserver pedestriansObserver = new PedestriansObserver();
        subject.addObservers(pedestriansObserver);

        BikeObserver bikeObserver = new BikeObserver();
        subject.addObservers(bikeObserver);
        
        //红灯
        subject.doAction(1);
        System.out.println();
        
        //绿灯
        subject.doAction(2);
        System.out.println();
        
        //黄灯
        subject.doAction(3);
    }
}

  测试效果:

     【设计模式】20.行为型模式-观察者(Observer)

 六、注意事项

  观察者和中介者模式有些类似,但是不要弄混。二者的区别如下:

  1.行为不同,观察者模式的目标类自身会有操作,之后通知观察者列表。中介者模式是直接通知对应的对象。

  2.目的不同,观察者模式主要是一堆观察者观察目标类,当目标类有所操作之后,同时作出反应。中介者模式是一个对象通过中介通知另外一个对象。

  3.目标群体不同,观察者模式中,目标类并不清楚观察者列表具体包含哪些对象;中介者模式的通知模式是清楚要通知哪些对象的。

  推荐一篇解释二者对比比较透彻的文章:https://www.cnblogs.com/yaopengfei/p/13502916.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/158094.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!