Pre/post
请注意pre/post不能算是典型意义上的设计模式,Pre/post是契约式编程思想的概念。但是在从chromium代码中确实能看到不少他们的身影。
契约式编程中的PRE/POST
契约式编程(英语:Design by Contract,缩写为DBC)在Wiki上的解释:契约式编程是一种设计计算机软件的方法。这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。这种方法的名字里用到的“契约”或者说“契约”是一种比喻,因为它和商业契约的情况有点类似。
在《程序员修炼之道:从小工到专家》中专门有一条讲的就是契约式编程(按合约设计)。
DesignbyContract的核心是断言(assertion)。所谓“断言”,是指永远为真的布尔型语句,如果不为真,则程序必然存在错误。通常情况下,检查断言的时机,应该局限于调试(debug)阶段,而不是代码的实际执行阶段。实际上,完成的程序永远不应期望断言会被检查。
DesignbyContract使用了三类断言:后继条件(post-conditions),前提条件(pre-conditions),以及不变量(invariants)。其中前驱条件与后继条件都是针对操作(operation)而言的。
前提条件preconditions:acondition that must hold up on invocation of a function在方法被调用之前就必须满足的条件。
后继条件post-conditions:acondition that must hold up on exit from a function法被调用之后所要保持的条件
不变量invariants:acondition that must always hold for objects of the class,except while a public member function is executing.在方法的执行过程中,不变量可能为假,但是,在其他任何对象能够与被调用方进行交互的时刻,不变量断言必须恢复为真。
在之前MBT的探索中,我们曾经尝试使用了PRE/POST模型,可参考文章http://tmq.qq.com/2016/11/pre_post_explore/。
虽然c++11不支持contract的语法,但是从chromium的代码上也可以看到代码也采用了pre/post的方式来设计。
我们可以从chromium的启动代码中看下pre/post思想是怎么使用的。
下图是Chromium中浏览器启动时候的代码顺序:
具体函数调用可以参考网上文章(http://blog.gclxry.com/chromium-framework-start/)。
启动的主要逻辑都是在Browser Main RunnerImpl,可以看到下面这段函数也是典型的pre/post的设计:
上面函数在main_loop_->Main Message Loop Start之前, 先调用main_loop_->Pre Main Message Loop Start准备相应的环境, 在执行完main_loop_->Main Message Loop Start之后又调用main_loop_->Post Main Message Loop Start来做后置条件的相关操作。
在每个layer里面都有对应的pre/post代码:
Browser MainLoop 里面的Pre Main Message LoopStart 又会调用对应的平台的Chrome应用(_parts对应的就是Chrome Browser Main Parts,不同的平台的应用不一样,windows上面就是Chrome Browser Main Parts Win)的Pre Main Message Loop Start。
在Chrome Browser Main Parts里面Pre Main Message Loop Start又会调用chrome_extra_parts_(多个扩展应用Chrome Browser Main Extra Parts:其中Chrome Browser Main Parts是对应的平台,
Chrome Browser Main Extra Parts是对应不同的Chrome toolkits (e.g., GTK, VIEWS, ASH, AURA, etc.))的Pre Main Message Loop Start。
在编程语言不支持了DBC的情况下,在代码层面采用PRE/POST的设计可以极大地提高代码的易读性和可维护性。且建立这种契约明确了我们什么时候什么阶段该干什么事。
维基百科的解释:委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。
Chromium是一个复杂的开源项目,其中应用了丰富的设计模式来组织代码,应用最广泛的应该算是Delegate Pattern(委托模式)。
在chromium中,每个模块具体功能的实现基本上都是通过Delegate类来实现的,如果开发者继承该Delegate类,并加以实现就能很方便的完成定制,倘若开发者不需要某个模块的功能,也就不用实现相关的Delegate类,那么该模块就不会发挥效用。
Delegate的使用使得自动化测试也非常容易,这些测试需要能直接检测Chromium中的某个特性或功能能不能正常工作,检查新添加的代码对原有的代码有没有影响,但是由于有些功能需要手动干预才能正常工作,比如下载模块中弹出的对话框需要手动选择保存文件的地址和文件名;这些会给自动测试代码带来麻烦,但是有了delegate的设计,我们在测试代码中可以直接实现对应的Test的delegate,继承正常工作的delegate,该类做一些简单的修改事先填好一些数据,从而绕开需要手动输入代码块的执行。这就一方面完成了对已有代码的测试,也同时兼具了自动化。
在Chromium项目中有个Download Manager类(content里面),它负责完成任务的下载功能,当在浏览器中点击某个不能被渲染的链接时,浏览器就认为该链接的文件需要下载,就通过Download Manager来完成下载流程。
当在浏览器中点击某个不能被渲染的链接时,浏览器就认为该链接的文件需要下载,就通过Download Manager来完成下载流程。但是下载文件的实际工作都是在Download Manager Delegate中完成的,比如选择文件的路径,检查文件路径名是否合法,下载时候完成之类等。开发者只需要自己设计一个新的Delegate类来继承Download Manager Delegate,并覆盖相应的方法即可完成下载功能,另外需要通过Set Delegate方法,在程序开始时把自定义类的对象注册到Download Manager中。目前Chrome,Content Shell,CEF3和Crosswalk都有自己的实现。
Chrome基于Download Manager Delegate的UML类图:
下面看看自动化测试中应该怎么使用设置test的delegate:
首先,基于Chrome Download Manager Delegate实现自己的测试的delegate:Delaying Download Manager Delegate。
上面代码就是基于Chrome Download Manager Delegate定义了测试所需要的Delaying Download Manager Delegate类,并重写了方法Should Complete Download 这样就可以绕开真实的delegate里面复杂的Should Complete Download逻辑判断,并简单的返回了false来进行测试。
在对应的测试用例代码里面调用set Delegate替换为测试的delegate。
定义完了测试的delegate类,调用SetDelegate来使得Delaying Download Manager Delegate生效。
长按指纹识别图中的二维码,获取更多测试干货分享!
Original url: Access
Created at: 2018-09-30 13:50:02
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论