最近在学习设计模式,特将学习的内容自我总结下,希望能和大家分享,并得到指正。首先分享观察者模式。
一、定义。
定义了对象之间的一对多的依赖,当一个对象发生改变时,它的所有依赖者都会收到通知并自动更新。如果对观察者模式不是很清楚的朋友,估计初看这个定义可能收获的会比较模糊。其实用通俗的话来说的话,其实就是表示一个一对多的结构。其中一代表一个主题,是产生消息的;而多则是需要接受消息,就是观察者了。书上举了一个很简单的例子,由气象局来代表主题,由它来产生气象信息,而这个气象消息可能需要不同的方式去展示,则每一种展示气象消息的媒介则就是每一个依赖于气象局的观察者了,因为要获取最新消息只能找气象局。
二、观察者的实现。
书中是先讲主题的,但是我觉得观察者更简单一些,所有还是先说一下观察者。这里是通过一个接口来定义的。
public interface Observer {
void update(Subject subject,Object obj);
}
比较简单,只有一个update方法,其中有两个参数,其中的subject是其所依赖的主题,而obj则是主题更新时传递过来的消息。每次发现有更新后会自动执行观察者的update方法将信息传递过来。
三、主题的实现。
同样也是通过接口定义,毕竟能面向接口编程,就少用继承。
public interface Subject {
/**
* 注册一个观察者
* @param observer
*/
void addObserver(Observer observer);
/**
* 删除一个观察者
* @param observer
*/
void removeObserver(Observer observer);
/**
* 发起通知观察者的动作
*/
void notifyObserver();
}
也是较为简单,其中也就最基本的三个方法。下面看一下具体实现吧。
public class SubJectTest implements Subject {
private boolean change;
private List<Observer> observerList;
private Object paramObject;
public SubJectTest(){
this.observerList=new ArrayList<Observer>();
}
public void addObserver(Observer observer) {
int i=this.observerList.indexOf(observer);
if(i<0){
this.observerList.add(observer);
}else{
System.out.println("is exist");
}
}
public void notifyObserver() {
if(change){
for (Observer ob:observerList) {
ob.update(this,paramObject);
}
this.makeChange(false);
}
}
public void removeObserver(Observer observer) {
int i=this.observerList.indexOf(observer);
if(i!=-1){
this.observerList.remove(observer);
}else{
System.out.println("is not exist");
}
}
public void makeChange(boolean change){
this.change=change;
}
public void updateInfo(Object obj){
this.paramObject=obj;
this.notifyObserver();
}
}
1、使用一个ArryList来存放注册的观察者。在构造方法中进行初始化。
2、其中还定义了一个change变量,在通知其所有的观察者前会先判断这个变量。其存在的意义时,也许主题并不是每一次改变都需要进行通知观察者,可以自己灵活控制。比如说,气象局对天气信息可能每1分钟就能更新一次,但是真正需要显示时的也许每天只需要通知一次而已。
3、updateInfo就是气象局自己更新了obj时,直接调用就好了,当change满足条件时,则会自动通知其依赖的所有的观察者。
4、makeChange则是你自己认为需要通知观察者时,改变其状态好了。
其结构也是相对较为简单的。那么下面实现两个简单的观察者好了,用来接收气象信息。
四、观察者的实现。
1、电视方式展示气象信息。
/*
* 电视方式展示气象信息
*/
public class CCTVObserver implements Observer {
public void update(Subject subject, Object obj) {
System.out.println("CCTV:"+obj);
}
}
2、短信方式展示气象信息。
/*
* 短信方式展示气象信息
*/
public class MessageObserver implements Observer {
public void update(Subject subject, Object obj) {
System.out.println("Message:"+obj);
}
}
五、测试。。
public class MainTest {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 创建主题
*/
SubJectTest subject=new SubJectTest();
/*
* 创建观察者
*/
Observer cctv=new CCTVObserver();
Observer message=new MessageObserver();
/*
* 注册观察者
*/
subject.addObserver(cctv);
subject.addObserver(message);
//认为可以通知
subject.makeChange(true);
subject.updateInfo("成都地区,今天晴转多云,最高气温29度,最低气温15度,风力三级");
}
}
运行结果:
CCTV:成都地区,今天晴转多云,最高气温29度,最低气温15度,风力三级
Message:成都地区,今天晴转多云,最高气温29度,最低气温15度,风力三级
五、通过jdk自带API实现观察者模式。
jdk提供了java.util.Observable来定义主题,注意这个一个类,而不是接口。而提供java.util.Observer接口来定义接口,和我们自已定义的相同,只有一个update方法。
1、实现主题。
public class Subject extends java.util.Observable {
public void updateInfo(Object obj){
super.setChanged();
this.notifyObservers(obj);
}
}
可以看出,很简单了,注册呀删除呀事情,父类都帮你做了。你只要自己实现逻辑,需要通知时调用notifyObservers方法就好了。注意父类的makeChange是protected的,所有只有子类才能调用。
2、其他的实现和我们定义的就完全相同了,没有什么太大的改变。
/*
* 电视方式展示气象信息
*/
public class CCTVObserver implements java.util.Observer {
public void update(Observable o, Object arg) {
System.out.println("CCTV:"+arg);
}
}
/*
* 短信方式展示气象信息
*/
public class MessageObserver implements java.util.Observer {
public void update(Observable o, Object arg) {
System.out.println("Message:"+arg);
}
}
public static void main(String[] args) {
/*
* 创建主题
*/
Subject subject=new Subject();
/*
* 创建观察者
*/
Observer cctv=new CCTVObserver();
Observer message=new MessageObserver();
/*
* 注册观察者
*/
subject.addObserver(cctv);
subject.addObserver(message);
//认为可以通知
subject.updateInfo("成都地区,今天晴转多云,最高气温29度,最低气温15度,风力三级");
}
运行结果:
Message:成都地区,今天晴转多云,最高气温29度,最低气温15度,风力三级
CCTV:成都地区,今天晴转多云,最高气温29度,最低气温15度,风力三级
但是这样看,貌似使用jdk自带的观察者要简单一些。
六、jdk观察者的一些问题。
1、首先Observable不是接口。这个比较郁闷,毕竟继承了它就不能集成其他类了。
2、仔细的朋友可以看出两次运行结果的顺序不同。Observable注册的顺序和通知的顺序不同。从这点看出,灵活性不强。
附件为具体的代码。。
分享到:
相关推荐
HeadFirst 设计模式学习笔记2--观察者模式 demo http://blog.csdn.net/laszloyu/archive/2010/05/12/5581769.aspx
031114_【第11章:Java常用类库】_观察者设计模式笔记
行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...
观察者模式笔记1
3. 行为型模式:行为型模式关注对象之间的通信和协作,包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。这些模式可以帮助...
设计模式经典样例笔记与代码Swift.zip 基础 [x] 类间的关系 [x] 设计原则 创建型 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定...
在PHP学习中,收集了一些常用的编程方法和思想,集中详细的记录了9种设计模式的设计思路和用法。比如:工厂模式,单例模式,注册模式,适配器模式,观察者模式等
3.设计模式Design Pattern:创建型模式(厂模式Factory、抽象工厂模式Abstract Factory、单例模式Singleton、建造者模式Builder、原型模式Prototype和对象池模式Object Pool Pattern)、结构型模式(适配器模式、...
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。工厂模式、抽象工厂模式、...
该文档是自己在学习设计模式时整理的常用设计模式pdf文档,包括源码,包括装饰模式,代理模式,责任链模式,命令模式,解释器模式,迭代器模式,备忘录模式,观察者模式,工厂模式,建造者模式,适配器模式,桥梁...
2.1观察者模式(不依赖jdk) 博文链接:https://biaowen.iteye.com/blog/505950
本人的笔记,关于java基础中设计模式的内容 包括 1.作业回顾 2.内部类 2.1局部内部类 2.2静态内部类 2.3匿名内部类 3.设计模式 3.1单例模式 3.2代理模式 3.3观察者模式 3.4模板模式 4.练习
在线阅读地址:设计原则创建型模式作用:将创建与使用代码解耦结构型模式作用:将不同的功能代码解耦桥接模式装饰器模式适配器模式外观模式组合模式享元模式行为型模式(更新中...)作用:将不同的行为代码解耦观察...
是我在学习设计模式时整理的,其中一些是我自己学习,很多来自网络.希望对模式有兴趣的朋友有帮助,我会很高兴.
describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器模式,装饰器模式,代理模式,...
比如单例设计模式、工厂设计模式、观察者模式、MVC框架结构设计模式等。 接下来我们一起来学习PHP中最常用的三种设计模式:单例设计模式、工厂设计模式和观察者设计模式。 单例设计模式 所谓单例模式,即在应用程序...
Android源码设计模式解析与实战读书笔记源代码 说明: 包名factorypattern.normal表示的是工厂方法模式的普通用法 包名factorypattern.practices表示的是工厂方法模式的常用 包名observerpattern表示的是观察者模式...