zoukankan      html  css  js  c++  java
  • 【设计模式】行为型03观察者模式(Observer Pattern)

         记得16年初第一次学习了23种设计模式,但是除了少数几个简单的外,其他的很多都是学了个似懂非懂,以至于有人问起甚至说不上来,现在想想,其实就是没看懂而已。例如观察者模式,其实原理很简单,但是当时并没有能静下心来细细总结,在此自我反思,也望后来者共勉。

         而关于设计模式是否能够被用的到这个问题,其实当我们遇到很多业务场景的时候,也会自然而然的想到与设计模式类似的思路,所以设计模式并没有我多年前认为的那么深不可测。然后就是类似于发布订阅这种需求,在如今大数据高并发的前提下,也已经有了很多完善的中间件框架,所以本人用到的极少。但并不是说没有用,例如JDK中大量使用的“委托”(并不在23中设计模式中),可以重用大量代码,是我最喜欢的设计模式,以后的博客中会详细描述。

    废话说完  ,开始正题:


    观察者模式其实就是发布订阅模式,发布者发布信息,订阅者订阅就能收到信息,没订阅就收不到信息。


    应用场景:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。


    实现方式:

    类图


    代码(参考了runnoob网站案例,稍作精简修改):

    1、首先我定义了一个公众号,持有一个被观察者对象的集合,发布文章时会调用方法通知所有观察者:

    package com.pat.observer;
    /**
     * 被观察者-模仿公众号
     * @author Administrator
     *
     */
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Subject {
    	//即将更新的头条文章
    	private String articles;
    	//持有观察者集合
    	private List<Observer> observers=new ArrayList<>();
    	
    	
    	public String getArticles() {
    		return articles;
    	}
    	public void setArticles(String articles) {
    		this.articles = articles;
    		notifyAllObservers();
    	}
    	
    	public void attach(Observer observer) {
    		observers.add(observer);
    	}
    	
    	public void notifyAllObservers() {
    		for(Observer obs:observers) {
    			obs.update();
    		}
    	}
    }
    

    2、定义一个订阅者(观察者)接口或者抽象类:

    package com.pat.observer;
    /**
     * 观察者
     * @author Administrator
     *
     */
    public abstract class Observer {
        protected Subject subject;
        public abstract void update();
    }
    

    3、假设存在A、B、C三位订阅者,继承观察者对象:

    package com.pat.observer;
    
    public class ObserverA extends Observer{
    
    	@Override
    	public void update() {
    		System.out.println("观察者A查看订阅的Subject公众号>>>"+subject.getArticles());
    		
    	}
    	public ObserverA(Subject subject) {
    		this.subject=subject;
    		this.subject.attach(this);
    	}
    
    }
    
    package com.pat.observer;
    
    public class ObserverB extends Observer{
    
    	@Override
    	public void update() {
    		System.out.println("观察者B查看订阅的Subject公众号>>>"+subject.getArticles());
    		
    	}
    	public ObserverB(Subject subject) {
    		this.subject=subject;
    		this.subject.attach(this);
    	}
    
    }
    

    package com.pat.observer;
    
    public class ObserverC extends Observer{
    
    	@Override
    	public void update() {
    		System.out.println("观察者C查看订阅的Subject公众号>>>"+subject.getArticles());
    		
    	}
    	public ObserverC(Subject subject) {
    		this.subject=subject;
    		this.subject.attach(this);
    	}
    
    }
    

    4、测试类中我们被观察者(被订阅者)发布文章:

    package com.pat.observer;
    
    public class Test {
    	public static void main(String[] args) {
    		Subject sub = new Subject();
    		new  ObserverA(sub);
    		new  ObserverB(sub);
    		new  ObserverC(sub);
    		
    		sub.setArticles("Subject更新文章《如何高效装逼》");
    	}
    }
    

    5、结果:

    观察者A查看订阅的Subject公众号>>>Subject更新文章《如何高效装逼》
    观察者B查看订阅的Subject公众号>>>Subject更新文章《如何高效装逼》
    观察者C查看订阅的Subject公众号>>>Subject更新文章《如何高效装逼》


  • 相关阅读:
    Python3中zipfile模块文件名乱码问题
    python zipfile 文件压缩和文件
    django+celery+rabitmq
    解决 Jumpserver coco 使用登录用户(ldap)进行SSH连接目标主机,忽略系统用户
    日志实时查看、轮询、统计、监控工具 Loggrove
    python django 多级业务树形结构规划及页面渲染
    nginx+uwsgi 部署 django
    python tornado websocket 实时日志展示
    python tornado websocket 多聊天室(返回消息给部分连接者)
    python 实时遍历日志文件
  • 原文地址:https://www.cnblogs.com/the-fool/p/11054150.html
Copyright © 2011-2022 走看看