基于c#的合约式包装器的设计方案研究

来源 :光盘技术 | 被引量 : 0次 | 上传用户:rghaijun23
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘 要:实现了一个C#语言的合约检查工具,用于辅助程序员在用C#语言编写软件的时候运用合约式设计方法。工具将书写在程序注释中的合约提取出来,并转化为类不变式、类方法的前置条件或后置条件的检查代码插入到源文件中。当执行含有合约检查代码的源文件的时候,检查代码将被执行,以确保合约是否被遵守。
  关键词:易测试性;合约式设计;类不变式;前置条件;后置条件
  中图分类号:TP311文献标识码:A
  
  The Research for Contract Wrapper Based on C# Language
  LI Ying-na
  (Kunming University of Science and Technology,Yunnan Kunming 650051)
  Key words: testability;design by contract;class Invariant;precondition;postcondition
  
  软件业的飞速发展,使各行业对软件的依赖性也日益增加。这种依赖,导致软件的使用者对软件的要求越来越高,软件需求更加细致和独立。软件制造业正面临着一些新的课题,如复杂的分布环境、灵活的应用模式、广泛的包容性等,传统的软件设计思想已远远不够。
  面向构件的设计模式为大规模、集成化软件设计带来了极大便利,同时也带来了更多的问题。特别是组成一个新系统的构件的协同性和互操作性问题。合约式设计(Design By Contract)把类和它的客户程序之间的关系看作正式的协议,描述双方的权利和义务。B. Meyer把它称作构建面向对象软件系统方法的核心。B.Meyer在Object-Oriented Software Construction一书中讲到:“对于一个大型系统来说,光保证它的各组成部分的质量是不够的。而最有价值的是确保在任何两个组成部分的交接处设计明晰的彼此义务和权利规范,即所谓合约。”DbC的提出,主要基于软件可靠性方面的考虑。在整个软件过程中,从概念模型的business use case用例规约开始就会有很多前置、后置条件,这些条件被具体化到设计模型后,就是每个对象元素的合约了。
  
  1 实现内容
  
  本文从合约化构件设计入手,实现一个基于C#语言的合约式软件开发工具,在C#语言的基础上,增加支持合约式设计的语法,并能与现有的开发平台(.NET)实现良好的对接,实现支持合约的构件化开发。
  本工具主要功能除支持几种主要类型的合约:前置条件、后置条件、类不变式之外,同时还支持循环变式、循环不变式、量词等。
  合约式设计中将这些条件集中明确的声明,确定职责归属,并由框架辅助进行验证。为了使工具更加的方便实用,更好地发挥合约式设计的优势,在认真的分析了已有的各种基于C#语言的合约检查工具的利弊的基础上,我们提出了工具需求如下:
  合约检查非强制性设计;不进行合约的嵌套检查;合约的描述:除C#语法本身支持的表达式外,在合约中增加全称量词、循环量词,并能够表达蕴涵关系。增加合约关键子,继承和完善C#中断言Assertion的功能;支持合约的继承:合约的继承包括类不变式的继承、前置条件的继承、后置条件的继承;
  注释的描述形式:合约采用注释的形式出现在C#源文件中。所有合约实现的语句全部定义在注释//和/**/中,并以#开头;
  


  2 工具的设计方案
  
  工具的任务是从含有合约的C#源文件中提取合约并对合约进行词法和语法检查,并根据语义在C#源文件中进行合约位置的搜索和插装,形成符合C#语法的代码,该代码可以在诸如.NET平台上进一步优化编译成目标代码。
  


  2.1词法和语法分析器的实现
  ANTLR是ANother Tool for Language Recognition的缩写,其功能是根据给定文法自动生成编译器,本项目采用ANTLR作为主要的开发工具,使用了类似EBNF(Extended Backus-Naur Form)的文法定义方式,需要时也可以利用ANTLR快速实现基于JAVA或C++等语言的DbC工具。
  2.1.1合约部分的词法和语法的ANTLR文法
  /*注释部分词法,$channel=HIDDEN 表示注释在词法分析时放入隐藏频道,以备语法分析时使用*/
  COMMENT :'/*' . *'*/' {$channel=HIDDEN;} ;
  LINE_COMMENT : '//'~ ('\n' | '\r') *'\r'? '\n' {$channel=HIDDEN;} ;
  /*定义合约部分的语法*/
  method-list:method+;
  //定义合约的位置
  method : method-name [ '('para-list')' ] returns return-type
  contract-spec;
  //合约种类的定义,合约都在包含在多行注释:/**/之间的。
  contract-spec:
  /*PreconditionSection|PostconditionSection|InvariantSection|LoopSection|notnullSection*/;
  PreconditionSection:#pre [pre-name:] ContractExpression ; //前置条件的定义
  PostconditionSection:#post [post-name:] ContractExpression ; //后置条件的定义
  InvariantSection:#invariant [invar-name:] ContractExpression;//类不变式的定义
  //循环变式(不变式)的定义
  LoopSection: #loop [loop-name] from (statement)?
  (invariant expression)|(variant expression)
  until ContractExpression
  loop { statement }
  End;
  NotnullSection:#! type ! variable; //非空变量的定义
  //合约表达式的定义,是合约的主要组成部分。
  ContractExpression:
  expression //一般的Boolean表达式
  | forall type VariableDeclarator in collection expression//forall表达式(全称量词)
   |exists type VariableDeclarator in collection expression//exists表达式(存在量词)
   |expression implies expression; //implies表达式(蕴涵表达式)
  collection:(element)+; //集合表达式
  element:
   integer-literal …integer-literal |character-literal …character-literal
  |integer-literal| floating-point- type | character-literal | string-literal;
  其中的黑体的为终结符,引用到的非终结符Expression, Type,VariableDaclarator等为C#语法规范中定义的一致;integer-literal、character-literal、floating-point-type、string-litera分别为整形、字符、浮点和字符串字面。
  2.1.2对ANTLR生成代码的引用
  用ANTLRWorks生成代码,这时目录中会生成三个文件“*Lexer.cs”、“*Parser.cs”、“*.tokens”,其中“*”是“*.g”文法文件的主文件名。*Lexer.cs为词法分析器,*Parser.cs为语法分析器。
  在.NET开发中先新建一个C# WindowApplication项目,将上述生成的文件拷贝并加入到项目中。再将.NET版的ANTLR Runtime的DLL引用到项目中来。本示例需要Antlr3.Runtime.dll和antlr.runtime.dll,这两个文件在antlr-3.1.3.tar.gz解压后的antlr-3.1.3\antlr-3.1.3\ runtime\CSharp\bin\net-2.0目录中可以找到。这些操作都完成之后,在窗体的代码文件Form1.cs中加入:
  using Antlr.Runtime;
  using Antlr.Runtime.Tree;
  编写相应的运行代码编译,添加相关表达式的实现类,这个编译器就可以进行工作了。
  


  2.2合约信息的提取
  利用ANTLR生成的词法和语法程序,对含有合约信息的C#源文件进行词法和语法的分析,如果分析正确,将获得一个源文件的分析树。按照深度优先周游这颗分析树,在周游的过程中提取源文件的所有的信息。
  周游分析树在ReflectVisitor类中完成,由于节点类型繁多所以实现采用了visitor模式。分析树中的任何一种节点类型在ReflectVisitor类中都存在一个与之对应的visit方法对该类型的节点进行访问,获得节点中的有用的信息,并将这些信息保存在已经设计好的结构中,这些结构包括表达式相关类、Class、Method等实体类,以及合约相关类Contract等,合约信息提取将为后面的合约正确性检查(主要是语义的正确性)以及合约的插装做好准备。
  在周游的过程中需要保存前面周游的一些信息,采用了如下的结构:
   public class VInfo {
   public reflect.Class clazz = null; //记录当前所访问的节点所属的类
   public reflect.Method method = null; //记录当前所访问的方法
  /*记录当前访问的类的名字(含有包前缀修饰的全名)*/
   public String unitName = null;
   public Vector fields = new Vector();//记录当前所访问的类中所声明的属性
   /*记录当前所访问的类中所声明的方法(不含构造方法)*/
  public Vector methods = new Vector();
   public Vector constructors = new Vector();//记录当前所访问的类中的构造方法
   public Stack locals = new Stack();/记录当前方法中,节点可以访问的局部变量
   public Vector forall_exists = new Vector();//保存forall/exits表达式
   public int loopCounter = 0; //当前所访问的方法的循环计数
   public int forallCounter = 0; //当前所访问的类中的forall/exits表达式计数
   public boolean inMethod = false; //当前节点是否处于方法体中
   public reflect.Class outerClass = null; //直接包含当前所周游类的外部类
   public boolean inLoop = false; //记录当前是否处于循环体中
   public boolean inContract = false; //当前节点是否是在合约中
   }
  2.3合约的插装
   要正确插装合约,首先需要能够准确地定位合约插入的源文件位置。通过对分析树的周游方法确定插入的位置,能够保证位置的准确,因为所有的C#程序都是遵守C#文法规则的。此处使用的分析树同语法检查的时候使用的分析树为同一棵分析树,也同样将使用观察者模式,将生成合约部分代码放在一个类中。
  
  3 结束语
  
   本文在调研了许多现有的有关合约设计工具的基础上,分析它们的优缺点,由此提出了我们的合约检查工具的设计方案。只是工具目前仅提供命令行使用模式,依赖于其他环境完成编码工作,使用时不是很方便。下一步将开发一个IDE的编辑工具,使得用户能够在编辑工具里面很方便地添加合约,以及进行合约的适时检查。
  
  参考文献:
  [1]Bertrand Meyer. Object-Oriented Software Construction. Prentice Hall, Upper Saddle River, New Jersey, 1997.
  [2]Bertrand Meyer. Design by Contract: The Lessons of Ariane. IEEE Computer,vol.30, no.1,January 1997,pp.129-130.
  [3]ANTLR简介,http://alien1979.e34.163ns.com/Default.aspx
  [4]单锦辉,一种基于合约的构件易测试性设计方法[D].第四届中国测试学术会议第四届中国测试学术会议(CTC 2006)论文集,2006.
  [5]李敏波翻译. C#高级编程[M]. 第4版.北京:清华大学出版社,2006.
其他文献
摘 要:SSL服务是目前互联网上常用的安全信息传输服务,尤其在电子商务、电子银行中更是普遍采用,本文介绍了在Windows环境下配置SSL服务的步骤。  关键词:SSL;服务器;数字证书  中图分类号:TP368.5文献标识码:A    How to Configure SSL Servers  CHEN Gang  (Huaiyin engineering,Jiangsu Huaian 2230
期刊
摘 要:伴随着电脑软硬件技术及网络技术的发展,计算机病毒技术、黑客技术及木马技术也取得了很大的发展,这就使得电脑系统随时都有可能出现故障,甚至于瘫痪,这将极大地影响到我们学习、生活、娱乐、办公的效率及质量!WinPE电脑系统维护基本上都是在图形化的窗口下进行,通过"傻瓜式"的点击几下鼠标就可以进行电脑系统的维护操作。  关键词:WinPE;系统;维护  中图分类号:TP393.08    WinP
期刊
在上一期《校园招聘:一场企业与人才的营销战》的专题中,我们给企业提供了如何进行成功校园招聘的理念与实务,让企业有了一个好的开始,可是在人才流动越来越频繁的今天,也许如何留住企业辛辛苦苦招来的人才更重要。  社会新鲜人是企业的新鲜血液,是保持企业活力的源泉,不仅可以解决企业人才缺乏的问题,还能保证企业的长久发展。据统计,全球500强每年都要吸纳几千名社会新鲜人进入企业,有时甚至不惜以高薪提前从名校挖
期刊
语境做好时间管理,不如改正工作习惯    要做好时间管理,与其花时间烦恼如何拟定规划,把最多的工作塞进有限的时间表里,还不如彻底检讨、修正你的工作习惯或方式,减少时间的浪费。  时间管理的第一守则,就是“Do the right thing right.”(用对的方法做对的事情)。  但是多数人只做到前半段,却忘了后半段。翻开许多谈论时间管理的书籍或文章,内容一定是告诉你,如何依据事情的轻重缓急,
期刊
摘 要:介绍基于CAN总线的船舶监控系统的基本结构。重点论述智能测控单元CAN通讯接口设计、CAN控制器外围硬件电路和CAN通信软件的实现。  关键词:现场总线;控制局域网;船舶监控系统;应用  中图分类号:TP273文献标识码:A    The CAN Fieldbus Technology Application in Ship Monitoring System  MA Li,XU Shan
期刊
摘 要:在系统上有许多类型的侵袭,我们一般把侵袭分为三种基本类型:入侵、拒绝服务(DOS)和盗窃信息。网络诞生以来遭受攻击事件不断发生,全球许多著名网站都遭到不名身份的黑客攻击,本文针对几种常见的DOS攻击提出在LINUX环境下的一些防御看法。  关键词:拒绝服务;攻击原理;Linux环境;防御  中图分类号:TP393.08 文献标识码:A    DOS attack principle and
期刊
摘 要:随着Red Hat Linux的迅速发展,Linux系统安全中的可信计算问题显得日益重要,虽然Linux kernel从版本2.6.13开始已经包含了对可信计算的支持,并已有许多Linux项目开始支持可信计算。但可信计算包括的:认证密钥、安全输入输出、内存屏蔽/受保护执行、封装存储、远程证明概念这5个核心技术在一个完全可信的系统中仍是必须的。研究和应用可信计算技术在系统安全方面具有重要意义
期刊
摘 要:针对数量庞大的教育网FTP资源检索困难的问题,提出一种基于开源软件NCFTP和Lucene实现对教育网FTP服务器进行索引并提供检索服务的FTP搜索引擎的设计及实现的方法。用开源软件NCFTP从FTP服务器上抓取FTP站点信息,并把抓取的信息转化为Lucene数据接口规定的文档(Document)类型,作为Lucene的数据源,并且采用基于字典的正向最大匹配中文分词法进行索引的建立及信息的
期刊
摘 要:MPICH是国内常用的集群计算消息传递系统。本文描述了MPI的基本概念及实现软件MPICH2,介绍了在Linux环境下如何构架基于MPICH的高性能计算集群系统的方法,给出了具体的步骤和基本配置过程。实验结果表明:在现有并行集群系统下能有效地利用现有计算机资源,大幅度提高计算效率,为一些复杂问题的求解提供可行方案。  关键词:并行计算;MPI;MPICH;集群  中图分类号:TP393.0
期刊
摘 要:本文理论结合实际,依据RS232串行通信标准、CAN2.0技术规范,由浅入深的论述了基于AT89S52和SJA1000的CAN-232智能通信模块的软硬件设计及实现。给出了整体设计思路、软件流程以及软件初始化程序。并结合实际测试中出现的问题对设计中存在的优缺点以及应用前景做了介绍。  关键词:通信模块;CAN-bus;SJA1000;AT89S52  中图分类号:TP302.1 文献标识码
期刊