




已阅读5页,还剩90页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Swarm用户指南Swarm开发组Paul Johnson堪萨斯州大学政治科学系Alex Lanchaster圣塔菲研究所译者 柳泉波北京师范大学信息学院Swarm用户指南Swarm开发组Paul Hohnson 和 Alex Lancaster2000年4月10日出版Copyright 1999-2000 Swarm开发组Swarm仿真系统的用户指南本文档是由CASA有限公司的Benedikt Stefansson(以前在UCLA的经济系工作)在1998和1999年的SwarmFest上发表的Swarm教程材料发展而来的。分三个阶段逐步深入的讨论了Swarm工具:第一部分是Swarm的简介;第二部分深入地剖析了Swarm程序;第三部分则详细讨论了用户在使用Swarm开发程序时可那遇到的种种问题。鼓励用户探索Swarm提供的样例程序,并访问Swarm站点()来了解最新消息和加入Swarm邮件列表。Paul Johnson的工作,由国家科学基金会的基金(SBR-9709404)部分支持。Paul是主要的作者,提供了指南的主要材料。Alex Lancaster负责有关SGML的大部分工作即在DocBook(见书末)中的锤炼和标记问题,并提供了补充材料和正文。有关Swarm用户指南的许可说明复制本文档需要预先获得版权持有者(Swarm开发组)的书面版权许可,合理的个人使用或者用于教育目的不在此禁。不允许大量分发本文的复制品或者将之用于牟利。生成本文档的SGML源文件以及相关程序在文件包userbook-0.9.tar.gz(/pub/swarm/userbook-0.9.tar.gz)。只要遵循GNU一般公共许可(GPL,/copyleft/gnu.html),那么使用、复制、修改和分发swarmdocs包及其生成的文档(包括HTML、TeX、dvi、PostScript和RTF格式)是允许的。目 录PART I 基本概念4第一章 介绍4第二章 程序设计和仿真7第三章 面向对象程序设计详论11第四章 Swarm的开发思想19第五章 图形用户接口23PARTII Swarm应用:样例演示27第六章 Swarm教程27附录A. Swarm工具90附录B Objective C-Swarm风格93PART I 基本概念第一章 介绍Swarm项目由Chris Langton于1994年在新墨西哥州的圣塔菲研究所(Santa Fe Institute,,SFI)启动。现在由圣塔菲研究所的非盈利性组织Swarm开发组()负责。目的是为基于多主体仿真模型(即所谓的ABMs,Agent-Based Models的缩写)的开发提供一系列标准的计算机工具并成为研究者交流的中介。有了Swarm,研究者可以专心于建模任务的本质,避免编程的某些复杂细节。有很多程序员对Swarm项目作出了贡献:Roger Burkhart,Nelson Minar,Manor Askenazi,Glen Ropella,Sven Thommesen,Marcus Daniels,Alex Lancaster,Vladimir Jojic,和Irene Lee。1.1 有关Swarm的基本事实Swarm提供了一系列支持仿真程序设计的软件库。最显著的特点包括:l Swarm的代码是面向对象的。Swarm库由名为“Objective-C”的计算机语言编写而成,这种语言是C语言的超集。Objective-C提供了创建软件“类”的能力,进而可以创建实例个体,实例是自包含的实体。面向对象程序设计的术语非常适合基于主体模型的讨论。l Swarm程序是层次结构的。大部分swarm应用程序大体具有如下的结构。首先,创建最顶层的一级,通常叫做“observer swarm”。“observer swarm”负责屏幕的显示,以及创建下一层,叫做“model swarm”。然后,“model swarm”创建主体个体,调度主体的活动,搜集有关主体的信息,并在“observer swarm”需要的时候提供。l Swarm提供了很多方便的工具。在手册的后续部分不难发现,Swarm库提供了很多有利于基于主体模型设计的代码。这些工具方便了内存的管理,表的维护,活动的调度以及其他很多琐碎工作。用户通过将Swarm对象集成在自己的程序中创建仿真应用。建议用户仔细研究提供很多的样例程序,以便充分的利用Swarm库的功能,充分体会个中蕴含的建模策略。1.2 Swarm是一个动态平台Swarm是自由软件(/philosophy/free-sw.html)1 有时也指“开源”(open source)软件,有关开源的定义参看/osd.html。当前版本的Swarm,遵循2 Swarm库的核心遵循LGPL(/copyleft/lgpl.html)许可,但是标准的二进制发布包括了遵守GPL许可的部件,这意味着Swarm是遵守GPL的。GNU General Public License(GPL,/copyleft/gpl.html)许可。无论是从理论或实际方面考虑,软件开发的自由软件模式都对像Swarm这样的工具特别有效。l 完全可观察。由于提供了完全的源代码,因此在必要时,建模者可以在操作系统级别上跟踪方针的执行。这对于可重复性是很重要的,最终使得建模者可以(在抽象的数学意义上)证明仿真的正确性。l 共享开发者的智慧。更实际的原因是,由于Swarm是开源的,我们可以利用开发者的智慧:技术水平比较高的开发者能找出Swarm的缺陷,编写补丁程序,实现新的特性等。GNU/Linux操作系统能够快速而健壮的成长也是由于类似的原因DiBona等,1999。随着Swarm的发展,越来越多的程序员和建模者将参与进来。Swarm的开发工作目前由位于新墨西哥州圣塔菲的Swarm开发组()负责。开发结果定期发布在Internet上,用户可以访问相应的源代码。Swarm的开发者们特别希望用户下载代码,进行试验,改进和增强Swarm的功能。采取开源策略的目的是能够综合整个研究社区的贡献。当Swarm的用户对库做了改进,我们鼓励他宣布出来并供他人使用。社区和Swarm团队的这种交互,使得Swarm库可以经常被修订。为了对此有所了解,简要介绍一下本项目的历史。原先Swarm的目的是用于支持X Windows系统的Unix操作系统的。Swarm的第一个测试版发布于1995年。1997年1月,Swarm 1.0正式发布,必须运行在Solaris和Linux操作系统上。不久,改进版的Swarm支持DEC Alpha平台以及其他Unix的变体。1998年4月,Swarm 1.1发布,其应用范围进一步扩展。在Cygnus Win32软件包的支持下,Swarm可以在微软Windows 95/NT(现在是98)上运行。1999年下半年,Swarm 2.0和2.0.1发布,增加了Java层使得Java程序员可以调用Swarm库,支持数据输出为NSCA HDF51 层次数据格式,适用于科学数据的存储,详情参考/。格式。由于Swarm仍在发展当中,因此很难精确的预测它的开发路径。目前Swarm开发组的工作重点是使得Swarm可以工作在更多的平台上,有更多的计算机语言支持。例如,Swarm的XML和Schema层原型已经通过测试。1.3 成功使用Swarm的前提Swarm的出发点是为设计多主体模型提供一系列的标准化方法。Swarm库的用户并不需要是一个技术高超的程序员2 这里的英文原文是“One need not be a highly accomplished computer program to user the Swarm libraries”,疑为“One need not be a highly accomplished programmer to use the Swarm libraries”的误写。实际上,由于Swarm的安装过程非常的流水线化,因此只要有合适的硬件平台,任何人都可以轻松的测试Swarm的样例应用程序。对于使用Windows 98/NT或Linux操作系统的用户来说,已经有编译好的Swarm库可用,安装就更加轻松了。然而,要创建新的Swarm应用并非易事。因为此时需要生成一个计算机程序。即使Swarm用户不是一个专家级的程序员,他也必须对重要的计算概念有根本的理解。所需要的知识因要创建的模型而异,但至少,必须具备:l 对计算机程序设计的基本理解。l 对下列两种面向对象程序设计语言之一有基本的理解:Java或Objective C3 如果要使用Objective C,由于它是C语言的超集,因此具有C语言的经验会很有帮助。Java学习起来很简单,是一种具有良好的开发工具和文档支持的主流语言。Objective-C也是相当一流的语言,学过C的人学习起来会很简单。因此,没有编程经验的人在创建基于Swarm的模型之前,需要做一些背景准备。如果想用Objective-C实现模型,建议先去找一本有关C语言的基础指南,例如“The C Programming Language”Ketnighan & Ritchie,1988。两位作者是C语言的实现者,因此本书具有相当的可读性,是所有人都应该拜读的信息手册。如果选择Java语言实现模型,市面上有数以万计的Java程序设计介绍性材料,包括印刷版的和电子出版物(参看A.1部分)。带有例子和练习的手册是很重要的,里面解释了编写代码并编译成可执行程序的基础知识。Objective-C语言最好是按照在线书籍“Object Oriented Programming and the Objective C Language”NeXT,1993学习第二章 程序设计和仿真设计Swarm的目的是帮助用户创建低层主体在其中交互的模型(通常称为“复杂系统”)。研究者必须对主体赋以内容,例如将主体想象成蜜蜂、投资者、树木或者臭虫等。研究目标是从个体水平行为中涌现出的总体模式。图2-1 基于主体建模面向对象程序设计特别适合表示此类模型。正如我们即将看到的,对象是自包含的实体。对象可传递来自于其它对象的信息,还可以保持、分类和总结信息。2.1 什么是对象?想创建具有重要意义Swarm模型,就必须仔细研究Java和Objective C两种面向对象语言的一种。这里的材料只是起总结和补充的作用,并非完整的教程。对象有两部分信息组成:l 变量。系列的变量表示了主体的“状态”年龄,财富,能力,诸如此类。这些变量可以是在C语言中允许的变量类型,如整型(int)、浮点型(float),数组,指针等。还可以是某种类型标识,这意味着该变量是类的实例。l 方法。方法决定了对象的行为。通常,要具备从“外部世界”接受信息的方法,向外部发送消息的方法以及处理信息的方法。变量和方法被赋以有意义的名字,从而提高了代码的可读性,例如,goToStore或goHome。对象通过名为“实例化”的过程被创建。简单地说,代码被写成“类”,对象作为类的实例被创建。类的实例或者说是对象内部的变量被称为“实例变量”。包含于实例变量中的信息对于对象所有的方法都可用。如果对象的某个方法需要具有别的方法不能使用的“私有”信息,此时需要创建“方法变量”。在Objective-C和Java中,术语“消息”经常代表指示对象执行某个方法的指令。(对于那些对C+比较熟悉的读者,术语“成员函数”与“方法”是同样的东西)。下面是指示对象bobDole执行方法runForPresident的消息例子。Objective C例子Java例子bobDole runForPresident;bobDole.runForPresident();在Objective C中,方法的参数在方法名字之后用冒号(:)引入;在Java中,方法的名字完全列在参数之前。例如,假定方法runForPresident需要一些参数,如参选年份和竞选伙伴名字等,则对应的消息应写成:Objective CJavabobDole runForPresident:2000 with:bobDole.runForPresident$with (2000,RossPerot);RossPerot;2.2 对象的种类在Swarm中,有很多类型的主体(见图2-1)。显然,如果某个模型要描述蜜蜂,那么模型中必须包含蜜蜂主体。此外还必须有其他角色的对象,而且这些对象并不全都是有生命的。例如,蜜蜂模型中可能有表示其他昆虫和熊的对象,还包括表示环境(树木,暴风雨等)的对象。通常,模型中还应该包含如下功能的对象:使得建模过程更加方便,搜集有关仿真的信息并传递给研究者。2.3 面向对象程序设计的好处面向对象程序设计(OOP)特别适合描述自治性主体,因此对于科学家和建模者来说,以OOP作为基础是再显然不过的事情。不仅如此,OOP对于计算机程序员也特别重要。Objective C中的OOP与C+或Java中的OOP并非完全一致,但是这些语言具有某些意义重大的相似。这里我们强调的是封装和继承。2.3.1 封装对象内的变量的值是私有的,只能通过特别编写的方法将信息传递到对象外部。封装既具有实在的意义又具有实际的意义。实在的意义是指现在对单个角色的表示已经假定角色是自包含的实体,其他角色并不能自动访问该角色内部的信息。就像人类之间那样,对象之间必须相互传递自己内部状态的信息。封装的实际意义也很重要。计算机项目可以分解为独立的部件(写成类的代码),当代码编写完成以后,每一个对象的内部细节对于程序员来说有时并不重要。例如,如果对象groceryStore能够对消息takeMoney响应,并完成了被要求的工作,我们可能并不在乎它如何做到的。这通常被称为“接口”和“实现”的分离。接口声明了对象可以执行的方法,而实现的细节则被隐藏起来(见图 2-2),用户只需熟悉对象的接口,而不是它的实现。2.3.2 继承每一个子类都继承了其超类的变量和方法。继承能够发挥作用,是因为每一个代码类都被设计为某个超类的子类。例如,在Swarm项目使用的GNU Objective C编译器中,有一个最基本的类“object”。Swarm库在object类的基础上创建子类,再创建子类的子类,如此反复,直到Swarm项目的程序员可以创建角色的新类为止,新类是SwarmObject的子类。如果程序员需要创建几种不同的类,并不需要重新编写每一个类的。子类可以自动拥有父类的所有变量和方法,同时还可以增加新的方法和变量。已知有一个名为Store的类,拥有方法takeMoney,创建Store类的子类GroceryStore。那么类GroceryStore的所有实例都会对takeMoney响应。如果程序设计者想重写GroceryStore的方法takeMoney,那么需要修订子类内的相关代码,这样,类GroceryStore的所有实例都将以新的特殊方式对takeMoney作出反应。在子类GroceryStore中的方法将重载超类中对该方法的定义。2.4 离散事件仿真基于Swarm的仿真是以离散步骤持续的。对象被创建出来,然后根据某种调度机制进行交互。在仿真运行的过程中,主体更新实例变量的值,并可能被要求向仿真的ObserverSwarm层汇报自己的状态。所以,Swarm中的建模过程与使用非面向对象语言如Fortran或Pascal的仿真建模具有很大的不同。这些所谓的过程式语言不允许建模者通过继承复用类或通过封装保护数据。下面是用过程语言编写的仿真样例:过程语言编写的仿真样例 伪代码1. 获得参数2. 初始化 一般是设置数据结构以及对输出的支持。3. for 1 to 时间步骤总数 do :a. for 1 to 主体总数 do :主体i进行某些活动 这里必须提供保存主体状态和实行行为的数据结构。b. 呈现状态 输出的实现通常留给程序设计者自己。4. 退出第三章 面向对象程序设计详论3.1 Swarm及其多语言支持Swarm不是一个拿来使用的应用程序。Swarm是一系列可以从中选取特性的库。3.1.1 Objective C一直以来,使用Swarm特性的方法是用Objective C来编写和编译程序。用Objective C编写的模型都具有良好得性能,因为它是使用本地化的具有代码优化功能编译器即GCC编译的。Obective C是Brad Cox设计的NeXT,1993,目的是为C语言提供一种优雅、面向对象的具有Smalltalk语言Goldberg & Robson,1989风格的扩展。Objective C最主要是用于NeXT计算机操作系统的设计,目前这种系统由Apple公司所拥有,并且是Apple的运行时环境WebObjects的基础。3.1.2 Java从Swarm 2.0开始,建模者可以使用Java。Java由Sun Microsystems公司所创建,开始的目的是为嵌入式设备(如数字电视的机顶盒)提供与平台无关的层或接口,原先被称为Oak。1992年以后随着WWW的发展,Oak被重新命名为Java,目标也调整为Web市场。“Write once, run anywhere”是Java开始者们的座右铭,其思想是在程序设计者和内部的芯片体系结构(ix86,Sparc,Alpha)之间增加一个抽象层,叫做虚拟机(或解释器)。Swarm(实际上,Swarm还可以扩展到如Scheme或C+这样的语言)的Java层将Swarm库的协议(protocol)映射为Java接口(interface)。备注:想要了解将Swarm与其他语言和仿真技术如XML和Scheme集成在一起的最新工作进展,参看论文“Integrating Simulation Technologies With Swarm”Daniels,1999。3.1.3 为什么用Objective C编写Swarm?Objective C并非一种主流程序设计语言,因此很自然地要问为什么选择Objective C来实现Swarm。原因如下:l Objective C易于学习。Objective C在大家都很熟悉的C语言的基础上增加了一些简单的特性。Objective C不允许类重载或者多继承(虽然使用协议可以间接达到这一目的)。l Objective C允许运行时绑定。其他的语言,在程序被编译的时候检查所接受的命令与程序的功能是否匹配;Objective C则将这种检查推迟到程序运行时。这意味着,例如,可以编写这样的程序:首先创建一个对象列表,然后给每个对象都发送一条消息。在Objective C中,编译器不会理会列表中对象的类型。这样处理的好处是,无需知道命令接收者的详细情况,就可以在代码加入要求接受者执行的命令,如此得到的代码,允许环境和对象集合变化和演化。不利之处在于如果对象接收到消息后要执行自己没有的方法,程序会崩溃。由于Swarm被组织成协议的形式,这减少了程序崩溃的可能性,因为编译器在检查的时候发现声明某个协议的类中并没有实现指定的方法,会提出警告。3.2 Objective C基础3.2.1 变量类型idObjective C中增加的变量类型是id,这是Objective C中对象的缺省类型。可将之视为一种特殊的变量类型(实际上是指向一个特殊数据结构对象的指针)。所有的对象都可以用标识self代表自己。如果在代码中定义了某个对象,程序设计者想要该对象执行某种方法,标识self就显得很有必要。例如,假定某个对象有一个名为updateRecords的方法,则当接收到命令self updateRecords;时,updateRecords命令将被执行,从而更新了所有的实例变量。所有的对象都可以通过super引用自己的超类。例如:super updateRecords3.2.2 接口文件:类的声明查看有Objective C代码的目录就会发现,文件总是成对出现的,如ObserverSwarm.h和ObserverSwarm.m,ModelSwarm.h和ModelSwarm.m等。以“h”为扩展名的文件是接口文件(通常被称为头文件),以“m”为扩展名的文件是实现文件。图3.1 Objective C基础如图3.1所示,接口声明了类的名字和超类的名字,然后给出了包含在大括号内的变量列表,然后是该类实现的方法列表。定义的变量可以在方法中使用(这经常被叫做“ivars”,即实例变量的简写)。样例3-1 Objective C类(1)interface Bug (2) : SwarmObject (3)int xPos, yPos;int worldXSize, worldYSize; (4)int foodSpace;- set X: (int) x Y: (int) y; (5)- step; (6)- (return_type) look : (direction_type) d; (7)end在上面的代码中,(1) 实例变量和方法的声明(2) 子类(3) 超类(4) 实例变量(5) 声明方法set,有两个参数(6) 声明方法step(7) 声明方法look,有一个类型为direction_type的参数,返回值类型为return_type3.2.3 实现文件:定义一个类每一个实现文件都必须输入对应的头文件。以上面定义的头文件Bug.h为例,对应的实现文件大体如下所示:#import Bug.himplementation Bug- set X: (int) x Y: (int) yxPos = x;yPos = y;return self;- step/bodyreturn self;- (return_type) look : (direction_type) dreturn_type returnval;/body of methodreturn returnval;以上的样例代码演示了很多重要的特性。首先,注意方法look指定了返回类型为(return_type)。在本例中,return_type应该被某种变量类型所取代,如int,float等。当方法look被调用时,调用方法的代码必须能够接收所返回类型的变量。与之相比,方法step没有指定返回类型。这意味着将返回缺省类型id。调用该方法的代码必须与返回类型一致。命令return self一般用于两种情况。假定方法的目的不是产生某些输出而是修改某些实例变量。例如,假设某个程序创建了类Bug的实例aBug。然后发送了如下的消息:aBug step此时,调用方法的代码不应该预期从代码中返回任何东西。不像在C语言中一般返回void,程序员可以返回self。在另外一种情况,程序员可能确实想要返回对象到一个列表或另外一个对象中,此时也要返回self。例如下面的代码:collectBugs addLast: aBug look: aDirection ;3.2.4 C函数 vs. Objective C方法由于Objective C是C语言的超集,因此Objective C方法可以包含任何合法的C命令。一种方法可以返回C函数可以返回的任何类型,此外,方法还可以返回id(严格地说,是对象的指针)。在Objective C中方法具有如下的结构:- (type) name: (type) arg1 argName2: (type) arg2(body)return returnval;与之相比,C函数一般如下所示:(type) name ( (type) arg1, (type) arg2) )(body)return returnval;看下面的比较代码:代码样例3_2 C vs Objective CCObjective Cvoid rnd_move(int i) int tmp_loc; do - rand_move: p id loc; do loc = self tmp_loc = get_rand_loc(); getRandLoc; while ( world at: loc!=nil); pwhile (valtmp_loc!=0) ; va;locationi=0;moveTo: loc; return self; valtmp_loc=i;3.3 Java基础Objective C和Java之间的最主要区别是Java并不类分成“声明”(头文件)和“实现”(实现文件)两部分。一个Java类的所有信息都包含在同一个.java文件中。下面的Java代码等同于样例3-1中的Objective C代码。样例3_3 Java类(1)public class Bug(2) extends SwarmObject(3)int xPos, yPos;int worldXsize, worldYSize;(4)FoodSpace foodSpace;public Object setX$Y (int x,int y) (5)xPos = x;yPos = y;return this;public Object step()(6)/ body of step() codereturn this;public return_type look(direction_type d) (7)return_type returnval;/ body of look() codereturn returnval;(1) 完整的类定义(2) 子类(3) 超类(4) 实例变量(5) 声明方法setX$Y(),有两个参数(6) 声明方法step(),无参数(7) 声明方法look(),有一个类型为direction_type的参数,返回值类型为return_type注意在Java中并没有id这种类型或其他一般的数据类型。所有的变量都必须被分配一种类型,在上例中,实例变量foodSpace被声明为FoodSpace。这是由于Java语言是强类型语言。编译器会检查所有变量的所有类型,以确保所有的接收代码能够对得到的消息进行响应。除此之外,Objective C和Java代码之间的最主要区别纯粹是因为语法的不同。例如,l 在Objective C中,方法名字和参数是散布的;在Java中完整的方法名字必须列在参数之前。l 在Java中,使用this而不是self(super在两种语言中的含义和语法都是相同的)。3.4 类的实例化实现类的代码(也就是Objective C的.h和.m文件,Java的.java文件)后,还要做的工作就是创建类的实例。3.4.1 实例化:Objective C风格仿真中的角色对象通常是SwarmObject类的子类。通常使用一对命令来创建对象:createBegin和createEnd,这不属于Objective C语法,是Swarm特有的。假定已经存在Bug.h和Bug.m,现在想创建类的实例。在文件ModelSwarm.m中,建立一个典型的方法buildObjects,在其中完成所有的对象创建。例如:/ 摘自ModelSwarm.m,创建Bug的实例#import Bug.h/ 其它的输入和代码- buildObjectsid aBug;bug = Bug createBegin: self;/ 设置主体的永久特性的代码bug = Bug createEnd;类工厂对象Bug被告知在ModelSwarm提供的内存区中创建一个对象(ModelSwarm就是self)。然后对象aBug被创建,可选的属性被加入。在后面的部分将深入讨论上述细节(也可参考附录B)。创建对象的实例不一定要用createBegin/createEnd对,可以简单地处理为:aBug = Bug crate: self在基于老版本的Swarm的代码中,语法有所不同:aBug = Bug create: self getZone;在Objective C中,这种用法仍然是有效的,但是不鼓励这么做。由于现在属于Swarm类型的对象,跟ModelSwarm一样,都是内存区域,因此无需再申请一个放置Bug对象的区域了。3.4.2 实例化:Java风格Java使用构造函数来创建类的实例。创建Java对象Bug的最简单方法如下所示:aBug = Bug (this.getZone();这等价于前面所述的Objective C样例。Objective CJavaaBug = Bug create: self getZone;aBug = Bug (this.getZone();注意在Objective C需要明确指出的create:方法在Java中是隐含的。备注:在Java中仍然可能使用create和createBegin/createEnd这种模式,但由于Java是强类型的语言,因而需要更多的工作才能使用上述模式。详细情况将在后续版本的指南中讨论。3.5 简要的澄清:Objective C中的类和协议读者需要仔细研究的一点,是Objective C允许创建叫做协议的实体。协议,是一个对象可以执行的方法列表。Swarm的结构由协议组成,因此在Swarm的参考材料中,将库看作是类的集合,每一个类又与给定的协议集保持一致。对Swarm用户来说,很多情况下都不必区分类和协议。最重要的Swarm协议,如类型Swarm(来自objectbase/Swarm.h)或Swarmobject(来自objectbase/SwarmObject.h),可以将之当作类一样的使用。在Swarm的参考指南中,有所有的协议的列表。采用CREATABLE协议的协议,可以将之视为类工厂对象。例如,EZGraph协议采用了CREATABLE协议,因此当用户要创建该协议的实例时,就可以直接使用。这样,observer swarm文件就可以用EZGraph创建图。几乎所有的Swarm协议都采用了CREATABLE协议,因此可以将之视为类一样的使用。例如协议SwarmObject,采用的协议包括Create,Drop和CREATABLE。这意味着SwarmObject可以被视为一个类,SwarmObject将响应createBegin消息,SwarmObject创建的实例对象将能响应createEnd,drop以及协议中列出的其他方法。使用协议的一个原则性好处是在编译的过程中,如果用户代码试图向对象发送非法的消息,编译器将发挥警告信息。例如,有消息通知对象执行方法goOutside,但是主体所采用的所有协议中都没有该方法,此时编译器将对此给出警告。粗略地说,采用协议就好比广而告之了某个类所能完成的功能,随后编译器确保了个中的“诚信”。如果编译的标志中包含-WERROR,也就是将警告视为错误,那么出现的警告信息将停止编译过程。事实上,Swarm库的很多重要部件都组织为协议,但是早期版本的Swarm不如当前版本在这方面那么突出。由于协议的引入,使用约定发生了改变。在Swarm中,有一个可用于创建集合的类List。使用老版本的Swarm,程序设计者可以创建属于List类的静态类型对象,如下的代码所示:List * listofPuppies;lisofPuppies = List create: self getZone;Swarm已经不允许用户采用上述方式静态的定位对象。这样的代码将使得编译器崩溃,因为在Swarm中没有名为List的类,只有上述命名的协议。从Swarm参考指南中我们知道协议List采用了CREATABLE协议,因此错误不是由于使用List创建listOfPuppies引起的。实际上,错误源自listOfPuppies的声明本身。如果需要定义的变量listOfPuppies由List类项目组成,推荐的方法是创建一个类型为id的变量,然后用尖括号指明对象所采用的协议:id listOfPuppies;listOfPuppies=List create: self getZone;将listOfPuppies定义为为一般对象也是合法的:id listOfPuppies;listOfPuppies=List create: self getZone;这种用法是合法的,编译也不会存在任何问题。唯一的缺点是如果往listOfPuppies中的对象发送了任何不正确的消息都不会得到警告。由于几乎所有的Swarm库重要功能都以协议的形式实现并且采用了CREATABLE,因此了解上述细节就显得尤其重要。但是,这并没有对程序设计的方法进行大的改变。Swarm的实体仍然可以被视为类。第四章 Swarm的开发思想如前所述,设计Swarm的目的是创建层次化的计算机对象。首先,observer类的swarm被创建,从而创建了用户接口并实例化model类swarrn,后者创建了后续层次的对象,并对主体的活动进行调度。Swarm项目的初始目的之一就是帮助用户方便地创建高质量的代码。Swarm库提供了一系列的类:创建仿真对象,管理内存以及调度主体的活动。4.1 主要主体和辅助主体由于计算机程序员使用“主体”的方式与科学家不一样,因此需要对术语的含义进行澄清。对于科学家来说,主体是指仿真中被建模的具有重要理论意义的实体;对于程序员来说,主体的用法就比较广泛了,有时候含义等同于对象。这样,在对“基于主体建模”的讨论中有时会发生错位的现象,因此大家对术语“主体”的理解不一样。为此,我们定义类两类主体:主要主体和辅助主体,以有利于进行相关的讨论。所谓的主要主体是指研究中首先要建模的东西,在理论中得到了描述,并具有实在的重要性。通常在这个意义上,可以对重要的“角色”以及角色之间在其中进行交互的世界进行表示。让很多新手感到惊讶的是,为了方便主要主体的工作,还需要创建辅助主体。例如,在一个遵守多数票当选的选举模型中,可以有像投票者和候选人这样的主要主体,还可能需要名为计票员的辅助主体,以便对选票进行计数。在大多数情况下,我们提到多主体系统时,是指主要主体。4.2 (Swarm)面向对象程序设计方式在Swarm中,ObserverSwarm和ModelSwarm的设计方式大致一样。在大多数类中都会出现的方法,包括:Objective C Java- createBegin; - createEnd; - buildObjects;createBegin(); createEnd(); buildObjects();- buildActions; -activateIn;buildActions(); activateIn();此外还有涉及对象的信息的输入/输出的方法。习惯上,这些方法的名字都有前缀get或set。例如:Objective C Java-setParameterValue: (int) value; - (int)Object setParameterValue (int value); intgetParameterValue;getParameterValue();方法setParameterValue能够对对象的内部参数进行赋值;而getParameterValue则使得主体汇报自己的参数值。除此之外,还应该有针对于研究问题本质的方法。ModelSwarm对象通常直接子类化于Swarm,是负责创建主体的主要对象,还给主体提供了内存区域,嗯并能对主体的活动进行调度。4.3 Swarm中的内存管理在任何仿真项目中,内存的申请和释放都是必需的特性,也是软件设计中最容易出问题的地方。Swarm在内存管理方面性能比较卓越,提供了对用户透明的相关库。在Swarm中,对象的创建和销毁涉及一个概念是内存区域,申请内存的“脏活”由库来处理。在下一部分中,我们将讨论对象的创建方式以及对存储区域的占用。当不再需要这些对象时,程序可以对对象发送drop消息,将之从内存中卸载。4.4 buildObjects方法中要做些什么?用户只须查看几个Swarm样例程序,就会清楚地发现创建对象的重要性。在buildObjects方法中,人们可以发现不仅有创建在当前类中使用的对象的命令,还有指示下一层主体创建其对象的命令。以Arborgames模型为例,在其ObserverSwarm的buildObjects方法中,首先是很多用于创建图形显示对象的命令,接着是创建仿真控制面板的命令,仿真控制面板呈现在屏幕上,为用户提供了开始和停止仿真的能力。需要特别指出的是,在ObserverSwarm的buildObjects方法还触发了下一层主体的创建创建了一个内存区域,并在区域中创建了一个ModelSwarm。代码的样子大体如下:Objective C JavaforestModelSwarm = ForestModelSwarm create: self;forestModelSwarm = ForestModelSwarm forestModelSwarm buildObjects;( this.getZone () );forestModelSwarm.buildObjects();在Objective C中,用户可以发现旧风格的代码,没有考虑ObserverSwarm本身就是一个内存区域的事实。modelZone = Zone create: self getZone;forestModelSwarm = ForestModelSwarm create: modelZone;forestModelSwarm buildObjects;注意上述代码最后一行的重要性。第一行代码创建了ModelSwarm对象(即forestModelSwarm),最后一行代码则通知forestModelSwarm执行其buildObjects方法。4.5 在buildActions方法中要做些什么?在标准情况下,buildActions有两个重要的部件,创建了两类对象:l ActionGroup:“刺激”事件序列l Schedule:决定了如何执行在ActionGroup中的事件在Arborgames模型的buildActions方法中,有很多有趣的例子。例如,在ObserverSwarm中,有刷新图形显示的命令,也有命令指示下一级的主体执行其自己的buildActions方法。在ModelSwarm的buildActions中,通常可以发现仿真的本质性动作。通知主体或系列主体执行各自方法的命令被放在ActionGroup类对象中,这意味着只要重复动作组,这些命令就会被重复执行。这种重复是由创建调度以及指定重复次数的命令控制的。4.6 调度的合并如上所提到的,在很多不同的类中都可以有buildActions方法。由于在每一个buildActions方法中都可以创建动作组和调度,因此如何以一种合乎逻辑的方式协调这些活动就显得尤为重要。Swarm的一个优点就是维护了一个一致的主调度。每一个子swarm的调度都被合并到高一层的调度中。最后所有的调度都被合并到最顶层的Swarm。当每一层swarm的activateIn方法被调用时,活动的同步是由Swarm Activity库管理的。调度的多级合并意味着模型实际上可以被视为多级模型的嵌套。图4-1 swarm的嵌套体系结构将Swarm视为一个虚拟计算机图4-2 Swarm虚拟计算机在更抽象的层次上讲,Swarm库可以被看作是在操作系统内核之上的一层。这种观点在下列情况时
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 计算机三级题库检测试题打印【必刷】附答案详解
- OT网络安全解决方案市场分析:预计2031年全球市场规模将为 206.5亿美元
- 辽宁省凌源市中考数学试题(预热题)附答案详解
- 2024-2025学年护士资格证考前冲刺练习【轻巧夺冠】附答案详解
- 2025安庆师范大学单招《英语》每日一练试卷附完整答案详解【历年真题】
- 交房物业收合同(标准版)
- 墓地占用土地合同(标准版)
- 2025执法资格能力检测试卷含完整答案详解【易错题】
- 养老院医疗应急预案(30篇)
- 2025年工业互联网平台光通信技术升级关键技术与案例分析报告
- 室内墙体拆除合同全文
- 2025年中国移动初级解决方案经理学习考试题库大全-上(单选题)
- 江苏苏州历年中考语文现代文之散文阅读13篇(截至2024年)
- 临床用血管理制度课件
- 体育行业反兴奋剂管理制度
- 护理管理的发展史
- 《以产地命名中药》课件
- 广西恒镒矿业贸易有限公司广西苍梧县古木口矿区金矿矿山地质环境保护与土地复垦方案
- 有限元模拟与磨损寿命预测结合-洞察分析
- 配音课件资源教学课件
- 191118-锂离子电池专业术语英语对照大全
评论
0/150
提交评论