专栏首页大大的微笑观察者模式详解

观察者模式详解

观察者模式是众多软件设计模式中的一种,又称发布订阅模式.被观察的对象发生了变化,观察者对象们可以第一时间收到通知, 并作出相应的处理,例如作为一家餐馆的会员,若餐馆出了新品那么会第一时间通知到各个会员,不是会员的路人则不会收到通知

再看一下类图:

FoodSubject sub = new FoodSubject();
	    new LisaObserver(sub);
	    Observer tom = new TomObserver(sub);
	    System.out.println("----菜品发布------");
	    Thread.sleep(1000);
	    sub.onChange("剁椒鱼头", "80.00", "热菜");
	    
	    System.out.println("--- tom竟然取消关注  ---");
	    sub.remove(tom);
	    System.out.println("----又有菜品发布哦------");
	    Thread.sleep(1000);
	    sub.onChange("外婆菜炒蛋", "18.00", "热菜");
----菜品发布------
我是lisa, 食物:剁椒鱼头,价格:80.00,菜品类型:热菜
我是tom, 食物:剁椒鱼头,价格:80.00,菜品类型:热菜
--- tom竟然取消关注  ---
----又有菜品发布哦------
我是lisa, 食物:外婆菜炒蛋,价格:18.00,菜品类型:热菜

JDK已经帮我们实现了观察者模式,Observable相当于Subject,Observer同上自定义的Observer,只有一个方法: //①.被观察者对象,②.参数  void update(Observable o, Object arg);

Observable是一个class而非一个接口 提供addObserver(Observer o) deleteObserver(Observer o)

notifyObservers() notifyObservers(Object arg) //必须在调用notifyObservers方法前先调用一次 //因为只有为true时才会通知观察者 void setChanged()

public class News extends Observable{
	private String subject;
	private String content;
	private Date date;
	public News() {}
	public void onChange(String subject, String content){
		this.subject = subject;
		this.content = content;
		this.date = new Date();
		setChanged();
		notifyObservers();
	}
	
	public String getSubject() {
		return subject;
	}
	
	public String getContent() {
		return content;
	}
	
	public Date getDate() {
		return date;
	}
	
}
public class Person implements Observer, IShow {
	private News news;
	private String name;
	public Person(Observable subject, String name) {
		subject.addObserver(this);
		this.name = name;
	}

	@Override
	public void update(Observable o, Object arg) {
		if (o == null || !(o instanceof News)) {
			return;
		}
		news = (News) o;
		show();
	}

	@Override
	public void show() {
		System.out.println("我是" + name + ",我阅读了:\n 主题:" + news.getSubject() + "\n内容:"
		        + news.getContent()
		        + "\n发布时间:" + news.getDate());
	}

如果观察者对象不需要所有的参数 

public class Lisa implements Observer, IShow{
	private News news;
	public Lisa(Observable subject) {
	    subject.addObserver(this);
    }
	@Override
	public void show() {
		System.out.println("我是lisa,我阅读了最新的新闻:\n 主题:" + news.getSubject() + ",内容:"
		        + news.getContent());
	}

	@Override
    public void update(Observable o, Object arg) {
		if(o == null || !(o instanceof News)){
			return;
		}
		news = (News)o;
		show();
    }
public interface IShow {
	void show();
}
//测试
 News news = new News();
	    System.out.println("----- 新闻资讯 -------");
	    String subject = "生态养海 拥海而兴";
	    String content = "进入11月下旬,海风吹在脸上已有些刺骨,但温州洞头区东屏街道东岙村,渔家乐的生意依旧红火。";
	    new Tom(news);
	    new Person(news,"any");
	    new Person(news,"tony");
	    new Person(news,"lexa");
	    Lisa lisa = new Lisa(news);
	    news.onChange(subject, content);
	    Thread.sleep(1000);
	    System.out.println("lisa不感兴趣,取消关住.");
	    news.deleteObserver(lisa);
	    Thread.sleep(1000);
	    System.out.println("----- 又发布了最新资讯 --------");
	    subject = "特朗普赦免感恩节火鸡:它将拥有一个非常光明的未来";
	    content = "美国总统特朗普21日遵照白宫的节日传统,在感恩节前赦免了两只火鸡。";
	    news.onChange(subject, content);
----- 新闻资讯 -------
我是lisa,我阅读了最新的新闻:
 主题:生态养海 拥海而兴,内容:进入11月下旬,海风吹在脸上已有些刺骨,但温州洞头区东屏街道东岙村,渔家乐的生意依旧红火。
我是lexa,我阅读了:
 主题:生态养海 拥海而兴
内容:进入11月下旬,海风吹在脸上已有些刺骨,但温州洞头区东屏街道东岙村,渔家乐的生意依旧红火。
发布时间:Thu Nov 23 16:53:16 CST 2017
我是tony,我阅读了:
 主题:生态养海 拥海而兴
内容:进入11月下旬,海风吹在脸上已有些刺骨,但温州洞头区东屏街道东岙村,渔家乐的生意依旧红火。
发布时间:Thu Nov 23 16:53:16 CST 2017
我是any,我阅读了:
 主题:生态养海 拥海而兴
内容:进入11月下旬,海风吹在脸上已有些刺骨,但温州洞头区东屏街道东岙村,渔家乐的生意依旧红火。
发布时间:Thu Nov 23 16:53:16 CST 2017
我是tom,我阅读了:
 主题:生态养海 拥海而兴,内容:进入11月下旬,海风吹在脸上已有些刺骨,但温州洞头区东屏街道东岙村,渔家乐的生意依旧红火。,发布时间:Thu Nov 23 16:53:16 CST 2017
lisa不感兴趣,取消关住.
----- 又发布了最新资讯 --------
我是lexa,我阅读了:
 主题:特朗普赦免感恩节火鸡:它将拥有一个非常光明的未来
内容:美国总统特朗普21日遵照白宫的节日传统,在感恩节前赦免了两只火鸡。
发布时间:Thu Nov 23 16:53:18 CST 2017
我是tony,我阅读了:
 主题:特朗普赦免感恩节火鸡:它将拥有一个非常光明的未来
内容:美国总统特朗普21日遵照白宫的节日传统,在感恩节前赦免了两只火鸡。
发布时间:Thu Nov 23 16:53:18 CST 2017
我是any,我阅读了:
 主题:特朗普赦免感恩节火鸡:它将拥有一个非常光明的未来
内容:美国总统特朗普21日遵照白宫的节日传统,在感恩节前赦免了两只火鸡。
发布时间:Thu Nov 23 16:53:18 CST 2017
我是tom,我阅读了:
 主题:特朗普赦免感恩节火鸡:它将拥有一个非常光明的未来,内容:美国总统特朗普21日遵照白宫的节日传统,在感恩节前赦免了两只火鸡。,发布时间:Thu Nov 23 16:53:18 CST 2017

因为Observable是一个“类”,你必须设计一个类继承它。如果某类想同时 具有Observable类和另一个超类的行为,就会陷入两难,毕竟Java不支持多重继承。 这限制了Observable的复用潜力. 再者,因为没有Observable接口,所以无法建立自己的实现和Java内置的 Observer搭配使用,也无法将java.util的实现换成另一套做法的实现(比方说, 如果你能够扩展java.util.Observable,那么Observable“可能”可以符合你的需求。 否则,你可能需要像本章开头的做法那样自己实现这一整套观察者模式。 而且setChanged()方法被保护起来了(被定义成protected)。这意味着:除非你继承自Observable,否则你无法创建Observable实例并组合到你自己的对象中来。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java使用mina和websocket通信

    这里以mina整合springMVC为例: //springMVC的配置: <!-- mina --> <bean class="org.spring...

    用户1215919
  • java队列,ArrayBlockingQueue

    提供了三个构造方法:    ①.ArrayBlockingQueue(int capacity)//指定长度,默认加锁机制为非公平锁    ②.Array...

    用户1215919
  • 设计模式之单例模式深究

    为什么使用单例模式?         我认为是由于某些对象的创建比较耗时,对内存的消耗又比较大回收成本过高,这时候如果允许 不断的创建对象代价势必太高,如果...

    用户1215919
  • lombok使用基础教程

    前言 lombok是一个编译级别的插件,它可以在项目编译的时候生成一些代码。在很多工具类的项目中都有这个功能。比如dagger。 通俗的说,lombok可以通过...

    Ryan-Miao
  • 设计模式之抽象工厂模式(创建型)

    抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模...

    SmileNicky
  • IM TCP网络问题分析

    应该下调心跳周期,但是旧版(1.0.1Realease-1.0.6Realease版本)存在

    大大大大大先生
  • Java设计模式 | 建造者模式解析与实战

    因为一个复杂的对象有很多大量组成部分, 如汽车,有车轮、方向盘、发动机,还有各种小零件等, 如何将这些部件装配成一辆汽车,这个装配过程很漫长,也很复杂, ...

    凌川江雪
  • Python - bytes与字符串的相互转化

    by.decode(encoding='UTF-8',errors='strict')

    小菠萝测试笔记
  • Lombok 使用小结

    Lombok 简介 Lombok 是一种 Java 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注释...

    静默虚空
  • Jetson AGX Xavier NX模组初步踩坑记

    第一波购买到NX模组的用户此时已经拿到模组了。我们跟他们一样,也是怀着某种奇妙的心情开始测试这个模组。

    GPUS Lady

扫码关注云+社区

领取腾讯云代金券