当前位置: 首页 > news >正文

哥特式建筑安全系统

本文讲的是哥特式建筑安全系统,在我的童年记忆里,电视上播放的那些低劣的冒险电影是模糊却持久的。通常,这些电影的场景会安排某个古旧的城堡、密室或走廊在其中起着重要的作用。为了找到它们,英雄们需要拉动楼顶的蜡烛托架,然后,轻拍两次墙壁。

想象有这样一家公司,他们决定根据这个想法构建一套安全系统。他们进入之后,设置某种无线网络,安装一些小的设备。如果发生某些有趣的事情,这些设备会发出一条四字符的消息。比如,打开抽屉,抽屉上附着的感应器就会发出一条消息:D2OP。还有一些小的控制设备,响应这样的四字符命令消息,比如,某个设备收到D1UL消息,就会打 开一扇门。
所有这一切的核心是一些控制器软件,它们会监听事件消息,弄清楚要做什么,然后发送命令消息。在那个网络产业崩溃的年代,这家公司买到了一堆廉价的烤面包机,它们可以用Java控制,所以,公司准备用它们来做控制器。因此,只要客户买了哥特式建筑安全系统,公司就会进驻其中,给这个建筑物装上一大堆设备,当然,还有一个烤面包机,里面装有Java编写的控制程序。

就这个例子而言,我们的关注点在于这个控制程序。每个客户都有各自的需求,但是,只要有一些好的样本,我们就不难发现其中的通用模式。为了打开密室,格兰特小姐要关上卧室房门,打开抽屉,然后,再开一盏灯。而肖瓦小姐则先要打开水龙头,再打开正确的灯,从而开启两个密室中的一个。至于史密斯小姐,她的办公室里有一个上锁的壁橱,内有一个密室。她必须先关上门,把墙上的画摘下来,再打开桌子上的灯三次,最后,打开那个满满的橱柜最上面的抽屉,这时,壁橱打开了。如果在打开里面的密室前,她忘记了关闭桌子上的灯,就会警报大作。
这是个异想天开的例子,但它所要表达的意图一点都不特别。我们有这样一系列系统,它们共享着大多数组件和行为,却彼此间差异极大。在这个例子里,对所有的客户来说,控制器发送和接收消息的方式是相同的,但是产生的事件序列和发送的命令却不尽相同。我们要整理一下这些东西,这样,当公司安装一个全新系统时,付出的代价才会是最小的。因此,对他们而言,为控制器编写动作序列必须非常简单才行。
了解了所有这些情况,一种好的处理方式浮出水面:把控制器看做状态机(state machine)。每个感应器都可以发送事件(event),改变控制器的状态(state)。当控制器进入某种状态时,它就会在网络上发出一条命令消息。
至此,我应该坦白,写作之初,这是全然不同的。状态机是一个很好的DSL例子,因此,我先选择了它。之所以选择 哥特式城堡,是因为我厌倦了其他所有状态机的例子。
格兰特小姐的控制器
这家神秘的公司拥有成千上万感到满意的客户,但在这里,我们只准备强调其中的一位:格兰特小姐,我最喜欢的客户。她的卧室里有个密室,通常情况下,这个密室都会紧锁着,隐蔽在那里。要打开这个密室,她就要关上门,然后,打开柜子里的第二个抽屉,打开床边的灯─二者顺序任意。做完这些,秘密面板就会解锁,她就可以打开密室了。
我用一张状态图来表示这个序列(见图1-1)。
如果你没接触过状态机,其实,它们只不过是描述行为的一种常见方式而已─并非广泛适用,但对于类似这样的情况,却是再合适不过了。其基本的想法是,控制器会处于不同的状态。当它们处于某个特定的状态时,某个事件会让控制器转换为另一个状态,在那种状态下会有不同的转换(transition)。因此,一系列的事件会让控制器从一个状态进到另一个状态。在这个模型里,当进入一个状态时,会执行某个动作(比如发送消息)。(其他类型的状态机可能会在不同的地方执行动作)。
基本上,这个控制器就是一个简单的传统状态机,不过需要一些微调。客户的控制器要有一个明确的空闲(idle) 态,系统会有大多数的时间处在该状态。某种特定的事件就可以让系统跳回到这个空闲态,即便它正处于一个更有趣的状态转换中间,这样就可以有效地重置整个模型了。在格兰特小姐的这个例子里,开门就是这样一个重置事件。
引入重置事件,意味着这里描述的状态机并不完全满足某种经典的状态机模型。状态机有几种非常有名的变体,这个模型便是以其中一个为起点的,只是略做微调,增加了重置事件,也就变成了只针对这种情况。
需要特别注意的是,严格来说,未必一定要有重置事件才能表示格兰特小姐的控制器。一种替代方案是,为每个状态添加一个转换,只要触发doorOpened,就会转换为空闲态。重置事件这个想法很有用,因为它简化了整个状态图。

来源:华章计算机

原文标题:哥特式建筑安全系统

相关文章:

  • 未能找到文件“\bin\roslyn\csc.exe”
  • 「hadoop」log4j参考
  • TensorFlow Serving 1.0的技术细节在Google I/O大会上公布
  • C语言经典算法100例
  • sql之left join、right join、inner join的区别
  • 洛谷——P1144 最短路计数
  • centos7 samba匿名访问设置
  • kafka基础知识点
  • 来来来!游戏场景风格暴露你的年纪
  • pandas模块学习笔记1--数据结构
  • Hadoop安装
  • VMware + JunOS + Linux 搭建安全测试平台
  • SecureCRT复制粘贴快捷键
  • hexo博客同步管理及迁移
  • WM_MOUSEWHEEL、WM_LBUTTONDOWN等父子窗口消息传递陷阱
  • 【comparator, comparable】小总结
  • 【技术性】Search知识
  • 【刷算法】求1+2+3+...+n
  • 2017年终总结、随想
  • 345-反转字符串中的元音字母
  • Android单元测试 - 几个重要问题
  • bearychat的java client
  • echarts花样作死的坑
  • ES学习笔记(12)--Symbol
  • Javascript基础之Array数组API
  • JS题目及答案整理
  • laravel with 查询列表限制条数
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Node 版本管理
  • OSS Web直传 (文件图片)
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Vue 重置组件到初始状态
  • Vue2 SSR 的优化之旅
  • 翻译--Thinking in React
  • 机器学习中为什么要做归一化normalization
  • 聚类分析——Kmeans
  • 小程序测试方案初探
  • 怎么将电脑中的声音录制成WAV格式
  • 你对linux中grep命令知道多少?
  • 积累各种好的链接
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • $$$$GB2312-80区位编码表$$$$
  • (9)目标检测_SSD的原理
  • (二)c52学习之旅-简单了解单片机
  • (二开)Flink 修改源码拓展 SQL 语法
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • .NET 8.0 发布到 IIS
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .Net面试题4
  • .NET与 java通用的3DES加密解密方法
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • @JsonSerialize注解的使用
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • @Mapper作用