观察者模式 详解


什么时候需要观察者

答案是需要观察的时候(别喷我),观察的意思就是去看,看外界的状态,外界如果发生了某种变化,那观察外界的对象就执行其对应的操作,这种场景在现实应用中很常见,或者说整个社会就是在我观察你,你观察我这种机制下运行的。实际一点的例子:图形用户程序中,图形对象需要监视后台数据对象的变化来做响应的显示;再举一现在系统中常用的一个服务:短信推送服务,当用户发出了交易请求时,就给该用户发送一个短信验证码。

观察者模式

思考:为了实现观察者对外界对象变化做出响应,我们应该想到两种做法,一种是观察者以轮询的方式观察某一对象,当本次观察发现对象状态发生改变时就做出响应(这种效率太低,因为这意味着观察者在外界对象变化前不能做其他的事情);第二种做法是异步通知的方式,当对象状态发生改变时,对象会向观察者发送消息(在代码中体现为它调用了观察者的某一方法),因为这不像进程间通信一样可以通过中断或者信号的方式实现,对象之间的异步通信只能通过调用彼此之间的方法。这意味着什么?这意味着外界对象必须拥有观察者的指针或者引用。即他们之间应该有聚合关系。

下面我们给出一个简单的实例代码,就以父母来观察孩子为场景
首先给出一个ChinaParent类的实现
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. //观察者  
  2. public class ChinaParent {  
  3.       
  4.     //孩子生病了他们会给孩子电话慰问  
  5.     public void callChildren(){  
  6.           
  7.         System.out.println("回来吧,带你去看医生");  
  8.     }  
  9. }  

然后给出Children类的实现
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. //被观察者  
  2. public class ChinaChildren {  
  3.       
  4.     private ChinaParent p;  
  5.       
  6.     public void gotSick(){  
  7.           
  8.         p.callChildren();  
  9.     }  
  10. }  
ChinaChildren和ChinaParent是一种聚合关系,当孩子生病的时候会主动的调用观察这p的callChildren()方法,以表示通知了他的观察者。
但是这种观察者的实现方式很不好,因为我们在具体的实现类之间建立的很强的关联关系,我们需要对他们进行解耦,而面向对象中解耦的方法最好不过的是面向接口的设计方法了,所以我们给这两个对象都实现某一接口
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public interface Parent {  
  2.       
  3.     public void callChildren();  
  4. }  

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public interface Children {  
  2.       
  3.     public void notifyParent();  
  4. }  
然后具体的实现类实现对应的接口
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. //观察者  
  2. public class ChinaParent implements Parent{  
  3.       
  4.     //孩子生病了他们会给孩子电话慰问  
  5.     public void callChildren(){  
  6.           
  7.         System.out.println("回来吧,带你去看医生");  
  8.     }  
  9. }  
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <pre code_snippet_id="267314" snippet_file_name="blog_20140331_6_1751525" name="code" class="java">//被观察者  
  2. public class ChinaChildren implements Children{  
  3.       
  4.     private Parent p;  
  5.       
  6.     public void notifyParent() {  
  7.           
  8.         p.callChildren();  
  9.     }  
  10.       
  11.     public void setObserver(Parent p){  
  12.         this.p = p;  
  13.     }  
  14. }</pre><br>  
  15. <br>  
  16. <pre></pre>  
  17. 这样就把孩子和具体的Parent解耦了,现在当有新类型的Parent时,我们也不用担心为了将新的观察者加入到我们的系统中而修改源码了。如:  
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. //观察者  
  2. public class AmericaParent implements Parent{  
  3.       
  4.     //孩子生病了他们会给孩子电话慰问  
  5.     public void callChildren(){  
  6.           
  7.         System.out.println("自己去看医生");  
  8.     }  
  9. }  
到此为止其实你已经掌握了观察者模式的核心了,说白了就是用面向接口的方法将具体的观察者和被观察者对象解耦了,但是实际项目中我们还会发现对象往往可以由多个对象共同观察,所以被观察对象中应该有多个观察者的引用
首先我们改变Children接口
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public interface Children {  
  2.       
  3.     public void notifyAllParents();  
  4.       
  5. }  
然后修改对应的被观察者
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. import java.util.ArrayList;  
  2.   
  3. //被观察者  
  4. public class ChinaChildren implements Children{  
  5.       
  6.     private ArrayList<Parent> ps;  
  7.       
  8.     public void notifyAllParents() {  
  9.           
  10.         for(int i=0;i<ps.size();i++){  
  11.               
  12.             ps.get(i).callChildren();  
  13.               
  14.         }  
  15.           
  16.     }  
  17.       
  18.     public void addObserver(Parent p){  
  19.         ps.add(p);  
  20.     }  
  21.       
  22.     public void delObserver(Parent p){  
  23.         ps.remove(p);  
  24.     }  
  25.       
  26. }  
这种就是最常用的观察者模式了,其实就是实现了多观察者同时观察同一个对象,人们美其名曰:发布订阅。因为被观察对象给出了向该对象中注册新的观察者和删除已有观察者的接口。

四、总结

设计模式中有很多模式都是通过面向接口编程的思想来对强关联的对象之间解耦的,面向接口给我们的程序带来了更好的扩展性,而这种方法运用到不同的场景语义中便形成了不同的模式,也就是说很多模式不是技术上的不同(都是面向接口而已),而是将面向接口的思想运用在了不同的场景应用中而已。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面中可以对界面中显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面中查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
基于hal库的OLED显示屏驱动C语言实现源码.zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值