为了账号安全,请及时绑定邮箱和手机立即绑定

JAVA设计模式之观察者模式

标签:
Java

观察者模式介绍

观察者模式又被叫做发布订阅模式。观察者模式在Java中非常的常见,比如说Spring中的事件监听设计就是观察者模式,再比如说Redis、kafka的发布订阅功能就是观察者模式。

应用场景

观察者模式在应用上非常广泛,比如订阅推送,发布订阅功能,聊天场景,微信公众号订阅等非常多。这个模式说白了就是:被观察者(发布者)生产内容,观察者(订阅者)获取内容。比如说订阅推送,假如我的博客发了一篇新的文章,那么那些关注我的人就会收到推送的消息。再比如说51CTO的付费专栏,如果专栏作者发布了新的专栏内容,那么那些订阅了该作者该专栏的人就会收到专栏推送的消息。而聊天分为一对一和一对多,一对一是私聊模式,而一对多是群聊模式,他们都是观察者模式。

观察者模式类图

JAVA设计模式之观察者模式

实现订阅专栏功能

1.Observer接口

/**

 * @ClassName Observer

 * @Description TODO:描述该接口职责

 * @Author ckmike

 * @Date 18-12-7 下午3:00

 * @Version 1.0

 * @Copyright ckmike

 **/

public interface Observer {

    void update(String message);

}

2.Observerable接口

/**

 * @ClassName Observerable

 * @Description TODO:描述该接口职责

 * @Author ckmike

 * @Date 18-12-7 下午2:56

 * @Version 1.0

 * @Copyright ckmike

 **/

public interface Observerable {

    // 注册观察者

    void register(Observer observer);

    // 注销观察者

    void remove(Observer observer);

    void notifyObserver();

}

3.SubscriptionChannel类

/**

 * SubscriptionChannel 简要描述

 * <p> TODO:描述该类职责 </p>

 *

 * @author ckmike

 * @version 1.0

 * @date 18-12-7 下午3:04

 * @copyright ckmike

 **/

public class SubscriptionChannel implements Observerable{

    List<Observer> observers;

    private String message;

    public SubscriptionChannel() {

        this.observers = new ArrayList<Observer>();

    }

    @Override

    public void register(Observer observer) {

        this.observers.add(observer);

    }

    @Override

    public void remove(Observer observer) {

        this.observers.remove(observer);

    }

    @Override

    public void notifyObserver() {

        // 通知所有observer

        for(Observer observer: this.observers){

            observer.update(message);

        }

    }

    public void sendMessage(String message) {

        this.message = message;

        System.out.println("专栏作者更新专栏文章......");

        // 调用通知所有订阅者

        notifyObserver();

    }

}

4.User类

/**

 * User 简要描述

 * <p> TODO:描述该类职责 </p>

 *

 * @author ckmike

 * @version 1.0

 * @date 18-12-7 下午3:13

 * @copyright ckmike

 **/

public class User implements Observer {

    private String name;

    private String message;

    public User(String name) {

        this.name = name;

    }

    @Override

    public void update(String message) {

        this.message = message;

        // 这里应该写到数据库中的,但我们这里就直接输出吧,方便

        read();

    }

    public void read() {

        System.out.println(name+"收到推送消息:"+this.message);

    }

}

5.测试用例

/**

 * Test 简要描述

 * <p> TODO:描述该类职责 </p>

 *

 * @author ckmike

 * @version 1.0

 * @date 18-12-7 下午3:19

 * @copyright ckmike

 **/

public class Test {

    public static void main(String[] args) {

        // 订阅专栏

        SubscriptionChannel channel = new SubscriptionChannel();

        // 三个用户

        Observer user = new User("Mike");

        Observer user1 = new User("William");

        Observer user2 = new User("Crane");

        // 用户订阅专栏,开启一个线程进行订阅

        new Thread(()->{

            // 假设读者订阅付费的间隔是10s

            try {

                channel.register(user);

                TimeUnit.SECONDS.sleep(5);

                channel.register(user1);

                TimeUnit.SECONDS.sleep(5);

                channel.register(user2);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }).start();

        // 专栏作者线程进行发布文章,每隔一秒发布一篇文章

        new Thread(()->{

            int i = 1;

            while (true){

                channel.sendMessage("JAVA设计模式之观察者模式!-第"+i+"章");

                try {

                    TimeUnit.SECONDS.sleep(5);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

                i++;

                if(i>5){

                    break;

                }

            }

        }).start();

        // 中途有用户退出订阅专栏,同时有人加入订阅

        new Thread(()->{

            try {

                TimeUnit.SECONDS.sleep(7);

                channel.remove(user1);

                TimeUnit.SECONDS.sleep(5);

                channel.register(new User("Nill"));

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }).start();

    }

}

JAVA设计模式之观察者模式

那么到这里我们就实现了订阅专栏消息推送。是不是很简单。那么我这里再给大家提供两个思考问题:1.如何让后来订阅的读者能够收到作者之前发布的消息呢?2.Spring的事件监听是如何实现的呢?如果你想到了欢迎在下面留言分析,和大家讨论哟。好!打完收工!

©著作权归作者所有:来自51CTO博客作者刺激乐天派的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消