当前位置: 首页 > 编程日记 > 正文

#每天一种设计模式# 观察者模式

系统常常会出现这种情况:

每一个部分需要知道整体的状态。比如Excel中,当你修改了一个单元格的值,可能横列的sum需要改变,纵列的sum需要改变,根据这个单元格做的图需要改变,是否被修改的按钮需要激活... 如果没有一种很好的处理方式,导致的结果将是系统 highly integrated。

仔细分析,比如Excel的单元格,我们可以抽象出单元格是a source of news ,而其他部门是 receiver,接受单元格的改动的通知,然后进行自己的处理。

比如,单元格修改之后,通知计算总和的类来做相应的处理。

class Excelattr_reader :celldef initialize(value,sum)@cell = value@sum = sumenddef cell=(value)@cell = value@sum.updateend
endclass Sumdef updateputs "Got Excel Cell Changed"end
endsum = Sum.new
excel = Excel.new(10,sum)
excel.cell = 11

在这个例子上,这一切完全ok。但是唯一的缺点是,Excel和Sum之间是硬连接(hard-wired)。比如,当cell改变的时候,除了Sum类,Graph类也需要得到通知,在这个例子上,我们只能修改cell=(value)这个函数。改动量的确不是很大,不过,Excel类并没有真的改变,只是因为增加一个receiver,却需要修改source所在的类。这总是有些不太合理吧。

ok,让我们把事情做的彻底一点。

class Excel attr_reader :celldef initialize(value)@cell = value@observers = []enddef cell=(value)@cell = valuenotify_observersenddef notify_observers@observers.each do |observer|observer.updateendenddef add_observer(observer)@observers << observerenddef delete_observer(observer)@observers.delete(observer)end
endclass Sumdef updateputs "Got Excel Cell Changed"end
endsum = Sum.new
excel = Excel.new(10)
excel.add_observer(sum)
excel.cell = 11

通过这种方式,source不需要知道有多少receiver对它感兴趣,而增加一个新的receiver也只需要调用add_observer方法即可。

这样Observer模式的结构就已经展现在眼前了。


GoF把source叫为subject class,而receiver较为observers.

the Ruby standard library 提供了一个Observable module让我们可以轻松实现Observer模式。

相关文章:

el-input怎么绑定回车事件

在 Vue 2.0 中&#xff0c;为自定义组件绑定原生事件必须使用 .native 修饰符&#xff1a;<el-input v-model"queryForm.skuName" placeholder"请输入商品名称" keyup.enter.native"skuNameSearch"></el-input> 转载于:https://www.…

DOS命令大全(经典收藏)

http://wuhua.javaeye.com/blog/32374 net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" /user:"用户名" 建立IPC非空链接 net use h: \\ip\c$ "密码" /user:"用户名" 直接登陆后映射对…

Ruby Metaprogramming

Ruby使用者对attr_accessor一定不会陌生。 class Aattr_accessor :num end 等效于&#xff1a; class Adef numnumenddef (value)num valueend end 在类的定义中&#xff0c;attr_accessor定义了num的读写方法&#xff0c;只用了一行代码就生成了两个实例方法&#xff0c;很…

四川大学线下编程比赛第一题:数字填充

四川大学线下编程比赛第一题&#xff1a;数字填充公布公司&#xff1a;有 效 期&#xff1a;CSDN 2014-09-27至2015-09-26 难 度 等 级&#xff1a;答 题 时 长&#xff1a;编程语言要求&#xff1a;120分钟C C Java C#题目详情peter喜欢玩数字游戏。但数独这种游戏对他来说太简…

Google AI骗过了Google,工程师竟无计可施?

作者 | 若名 出品 | AI科技大本营 如果你通过 Google 搜索购买演唱会门票或者注册论坛账号&#xff0c;系统会提示你必须点击几个图框、音频或者移动鼠标等操作来确认是人类在操作验证而不是机器人。 其背后的验证机制就是 CAPTCHA&#xff08;验证码&#xff09;&#xff0c;…

用高中数学理解AI “深度学习”的基本原理

本文作者尚俊霖&#xff0c;全职产品经理&#xff0c;业余自学机器学习。最近开始写硬核科普&#xff0c;欢迎关注公众号欠拟合&#xff08;ID:Underfit&#xff09;。Google 研发了十年自动驾驶后&#xff0c;终于在本月上线了自动驾驶出租车服务。感谢“深度学习”技术&#…

Linux I2C工具查看配置I2C设备【转】

转自&#xff1a;http://blog.chinaunix.net/uid-26895763-id-3478882.html 在處理音訊相關的問題時&#xff0c;我通常會找個方法來讀寫codec中register的值。幸好linux上也有這樣的工具 – i2c tools。先到lm-sensors下載soure code&#xff0c;然後cross compile成arm的執行…

Ruby之类定义

介绍几种不常见的类定义方法&#xff1a; 1. Struct PersonStruct.new(:name,:age,:sex)pPerson.new("liyuchun")puts p Struct生成一个仅仅包含数据属性的类。但是你可以在这个类的基础上扩展&#xff1a; PersonStruct.new(:name,:age,:sex)class Persondef …

引用 引用 引用 学会求知 学会共处 学会做人 学会做事

◆学历不等于能力和水平&#xff0c;学校学到的在社会能用上的只有15%&#xff0c;而在社会能学到85%。◆世上很多发生的事必有其原因&#xff0c;必有其结果&#xff0c;必有其收获。◆心态归零&#xff0c;天道酬勤。◆老板是私营企业家&#xff0c;赚了小钱是自己的&#xf…

python写一个通讯录step by step V3.0

python写一个通讯录step by step V3.0 更新功能&#xff1a; 数据库进行数据存入和读取操作 字典配合函数调用实现switch功能 其他&#xff1a;函数、字典、模块调用 注意问题&#xff1a; 1、更优美的格式化输出 2、把日期换算成年龄 3、更新操作做的更优雅 准备工作 db准备…

#每天一种设计模式# 模板方法

《松本行弘的程序世界》对模板方法(Template method)的说明非常清晰&#xff1a; 在父类的一个方法中定义算法的框架&#xff0c;其中几个步骤的具体内容则留给子类来实现。 比如一个用于公司欢迎同事的程序&#xff1a; class Adef initializename "jinbin"word …

如何更好地玩转GitHub?

本文作者黄昱俊&#xff0c;国资企业投资部总经理&#xff0c;主要负责投资部门建设、投资流程管理、投后资源管理。历经10年&#xff0c;从医疗器械研发工程师到投资管理的蜕变&#xff0c;业余尝试ETF量化投资。 本文介绍如何在GitHub上更新Fork以及PullRequest给源项目。 在…

System Center Data Protection Manager 2007补助说明

在 DPM 服务器上配置 Windows 防火墙 1. 在 Control Panel&#xff08;控制面板&#xff09;中&#xff0c;单击 Windows Firewall&#xff08;Windows 防火墙&#xff09;。2. 在 General&#xff08;常规&#xff09;选项卡中&#xff0c;验证是否已开启 Windows 防火墙&am…

可伸缩系统的设计模式(译)

Ricky Ho在他的博客中分享了该文章&#xff0c;该文章是一个简单的概括分享&#xff0c;详细的可以参见他博客的其它详细文章。下面主要是意译。 1、Load Balancer&#xff1a;负载均衡 – 由分发者来决定哪个工作者处理下一个请求&#xff0c;这种决定可以基于不同的策略。 “…

Boson_Netsim_6使用方法

使用说明&#xff1a; netsim6.0只有在英文操作系统下才能释放出正确的pdf文件&#xff0c;大家可以到文档中心下载以下3个pdf文件&#xff1a; SequentialLabs.pdf&#xff1a;解压后复制到安装目录下的\MyLabs\ccna_sequential\Sequential Labs (CCNA)\common中覆盖相应的文件…

Ruby之Enumerator类

今天发现了Ruby1.8.6和 Ruby1.9.2的一个不同之处&#xff0c;试运行以下代码&#xff1a; require findputs Find.find("./data").class 在Ruby1.9.2中&#xff0c;最后的结果是Enumerator&#xff0c;而在Ruby1.8.6中&#xff0c;结果则是find: no block given (L…

澎思科技获IDG资本数千万元Pre-A轮融资  推出AI安防全场景软硬件解决方案

1月8日&#xff0c;人工智能安防公司澎思科技宣布完成数千万元 Pre-A 轮融资&#xff0c;该轮融资由 IDG 资本领投&#xff0c;高捷资本、上古资本、洪泰基金跟投。澎思科技表示&#xff0c;此轮融资会更多用来“修炼内功”&#xff0c;进一步夯实公司的技术研发和产品落地能力…

看linux书籍做的一些重要笔记(2011.07.03更新)

&#xff08;1&#xff09;制作启动盘 •用户可以用dd&#xff0c;cat&#xff0c;cp等命令自行将这些image文件制作成启动盘。 •例如&#xff1a; •ddif/mnt/cdrom/RedHat/images/bootdisk.img of/dev/fd0 •cp /mnt/cdrom/RedHat/images/bootdisk.img /dev/fd0 •cat /mnt…

C++ Primer 读书笔记 (1)

我的《C Primer》扉页记着购书的日期和地点&#xff1a;C Primer 2009.11.28购于西区求索。那时对于这本厚书一直心怀敬畏&#xff0c;仿佛是眼前的一座大山。那时&#xff0c;虽然已经大四&#xff0c;但是对于面向对象的理解还很肤浅(相当肤浅)&#xff0c;只能用C编写一些简…

招聘:兼职ASP 高级工程师

工作职责&#xff1a;1、负责ASP网站设计和页面制作&#xff1b;2、配合运营团队做客户服务支持&#xff1b;3、参与海洋工作室其他相关设计工作。 职位描述&#xff1a; 1. 要求有很强大ASP开发功底;2. SQL Server使用经验;3. 有与策划者和美工合作的习惯;4. 可独立开发&…

GitHub重大好消息:私有仓库可无限制免费创建

作者 | 一一 出品 | AI科技大本营 GitHub 被微软收购之后&#xff0c;第一次公布了有利于广大程序员的好消息。 1 月 8 日&#xff0c;GitHub 宣布无限制的免费为普通用户提供私有仓库服务&#xff0c;这给程序员每年省下了 84 美元。此前&#xff0c;企业要创建私有仓库进行代…

“AI下乡”:华为和袁隆平一起种海水稻,欲改造1亿亩良田

作者| 琥珀 出品| AI科技大本营我们总是无法忘怀“杂交水稻之父”袁隆平的名字&#xff0c;即便后来很多学者对他的成就有所争议。距今&#xff0c;三系杂交水稻的发现已经过去了 50 多年&#xff0c;袁隆平也近 90 岁高龄&#xff0c;但他依然活跃在农业生产一线。想必近日不少…

finecms设置伪静态后分享到微信不能访问怎么处理

finecms设置伪静态后分享到微信不能访问&#xff0c;分享的链接自动增加了一串参数&#xff0c;类似这样的***.html?fromsinglemessage&isappinstalled0&#xff0c;刚开始ytkah没注意&#xff0c;以为是微信屏蔽了不安全网址&#xff0c;后面在论坛上问了一下&#xff0c…

Access和SQL server开启表间关系,并实现更新或删除母表数据自动更新或删除子表数据...

1.Access开启表间关系,并实现删除母表数据自动删除子表数据: 在Tables等界面 - > 右键 - > Relationships... -> 弹出Relationships窗口 -> 选择需要关联的表 -> 双击Relationships窗口空白位置 -> 弹出 Edit Relationships 窗口 -> 就可以看到Enforce Re…

推荐并简要分析一个silverlight的相册DEMO--ImageSnipper(V2)

下面就是它的一些演示截图。 首先是缩放&#xff0c;旋转和透明处理&#xff1a;然后是文字水印处理&#xff1a;然后是使用Ink的涂鸭&#xff1a;相信做为一个相册&#xff08;图片浏览&#xff09;的基本功能已经没什么问题了。下面来看一下这个DEMO的类图&#xff…

Ruby之Tempfile

今天又机会尝试了下Ruby的Tempfile库&#xff0c;相比于自己创建临时文件再删除的方法简便了很多。 require tempfiletmp Tempfile.new("tmp")tmp.path # > /tmp/tmp20110928-12389-8yyc6w 不唯一tmp.write("This is a tempfile") tmp.rewind tmp.read…

快车 FlashGet 3.1 修正版(1057)

快车 FlashGet 3.1 修正版(1057) SM发布于 2009-06-25 23:43:23| 2326 次阅读 字体&#xff1a;大 小 打印预览感谢VxuE的投递快车(FlashGet)是互联网上最流行,使用人数最多的一款下载软件.采用多服务器超线程技术、全面支持多种协议,具有优秀的文件管理功能.快车是绿色软件,无…

Python模拟微博登陆,亲测有效!

作者 l 上海小胖 来源 l Python专栏&#xff08;ID&#xff1a;xpchuiit&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;pythonzhuanlan&#xff09;今天想做一个微博爬个人页面的工具&#xff0c;满足一些不可告人的秘密。那么首先就要做那件必做之事&#xff01…

Ruby调用shell命令

原来发在diandian的几篇旧闻&#xff0c;也一并转到iteye上来吧。 1. exec exec echo "hello $HOSTNAME" 用echo命令来取代当前进程&#xff0c;无法知道命令是否成功 2. system system(echo "hello $HOSTNAME") 运行一个子shell来避免覆盖当前进程&a…

mac os下valgrind的安装

valgrind是一款性能分析工具&#xff0c;功能强大。 在mac os下的安装略有不同&#xff0c;特写此文以记之。 现在最新的版本是3.8.1 tar jxvf valgrind-3.8.1.tar.bz2 cd valgrind-3.8.1 ./configure sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer m…