第二章 第一个应用

本章我们会开发一个简单的游戏:点图。随着开发流程我们会演示Squeak开发过程中的大部分工具,演示开发者之间如何交互。还会使用系统查看器,对象查看器,调试器,包管理器等工具。使用Smalltalk进行开发非常高效:其中大部分时间花在编写代码上,开发流程的管理交给Squeak自动完成。Smalltalk的语言简洁性和Squeak编程环境的丰富性。

2.1 点图游戏

通过开发一个简单的点图游戏说明如何使用Squeak的开发工具。这个游戏的面板如图。包含一系列的黄色块组成,点击其中的一个,周围的四个变成蓝色,再次点击,恢复到黄色。这个游戏的目的是尽可能多的转换为蓝色。

game

这个游戏包含两类对象:一个是盒子对象,一个是100个独立的块对象。因此在Squeak需要通过代码实现两个类,一个是游戏盒子,一个是块。接下来我们说明如使用Squeak的开发工具定义这两个类。

2.2 创建新的类分类

我们将会在第一章介绍的系统查看器的基础上,介绍如何定义新的类分类以及其中的类

Doit打开系统查看器,右击分类面板,选择add item

sbe-quinto

在打开的对话框中输入新的分类名字SBE-Quinto。然后点击accept或者输入回车键。新的类分类创建。通常新的分类在最后,如何选择了一个已存在的分类,那么将会创建在选择的分类前面。

2.3 创建SEBCell类

这个新的分类中并没有包含任何Class。在下面的主编辑区域包含了创建类的模板可以用作类快速创建模板

快速浏览其中的代码,可以发现这个模板组织为发送消息给Object类,创建一个名为NameOfSubClass的子类。这个新的子类没有任何变量,并且属于SBE-Quinto类分类

我们就在这个模板的基础上进行修改创建我们需要的类

Doit 修改类创建模板
将Object名字替换为SimpleSwitchMorph
将NameOfSubClass替换为SBECell
添加mouseAction到类的实例变量中
修改结果如下

SBECell

修改的代码包含一个Smalltalk表达式。发送消息给SimpleSwitchMorph类,要求创建一个子类SBECell。因为SBECell并不存在,需要传递一个参数#SBECell作为类的名字。
然后在新创建的类中包含一个mouseAction实例变量,将用来定义块应该采取的动作在受到点击的时候

当前只是输入代码,并没有编译生成任何类。需要使用accept进行编译保存

Doit编译保存创建的类,

accept class

空白地方右击选择accept
创建成功后,新创建的类将会显示在系统查看器的第二栏。编辑区域显示类的定义,下面提示输入一些注释。

这个区域叫做类注释(class comment)。在大型项目开发中代码注释非常重要,Smalltalk高度重视代码的可读性和注释的详细。也就是说代码应该是自说明的。类的注释并不需要太详细的描述,仅仅需要一些用来说明这个类的用途。

SBE ok

Doit 对类进行注释

2.4 为类添加方法

接下来我们为新创建的类添加一些方法

Doit选择协议面板中的all。
在编辑主区域显示一个方法创建模板,选择编辑器区域,修改代码为下

initialize

Doit选择accept保存创建的方法

让我们逐行解释这些代码的意义

这个方法名称是initialize.这个名称的意义非常重要。通常一个类定义个initizlize方法,在创建一个对象后用来初始化对象的数学。所以当执行SBECell new后,将会发生initialize消息给类用来创建新的对象。初始化方法initialize将会用来初始化对象的状态,通常用来设置对象的实例变量,接下来我们将要说明。

这个方法中第一句就是执行父类SimpleSwitchMorph类的初始化方法,因此SimpleSwitchMorph中继承的属性将会被初始化。通常使用super initialize来初始化继承的属性。我们在这里不知道SimpleSwitchMorph的初始化方法我们也不用关心,可以确定的是会初始化一些实例变量来保存默认值,因此最好首先调用父类初始化避免未知的变量

方法的其余语句用来设置对象的数学,self label:''首先设置对象的label为空字符串

表达式0@0 corner:16@16需要一些说明。0@0表示一个xy坐标系的原点未知,事实上这个语句发送@0消息到数字对象0,接下来数字0创建一个点Point类的实例(0,0)坐标。接着发送消息corner:16@16用来创建以0@0和16@16的矩形。然后将这个矩形赋值给bounds变量。这个变量是继承自父类。

需要注意的是Squeak屏幕原点在左上,y轴向下递减。
其余的语句也是用来设置属性。

2.5 探测对象

接下来创建一个对象来进行观察

Doit打开workspce。输入SBECell new右击选择inspect it

打开一个查看器,显示了SBECell的实例变量列表,选择其中的一个如bounds。它的值将会显示在右侧面板。可以使用这个查看器修改实例变量的值

DOit 修改bounds的值为0@0 corner:16@16然后保存accept
查看器下面是一个迷你workspace。经常用来对当前对象进行测试使用

Doit在其中输入se;f openInWorld 然后do it

接下来会在窗口创建一个块,中击显示器控制,缩放大小,观察查看器,可以看见bounds的值也会发生变化

2.6 定义SBEGame类

接下来我们创建另一个游戏类SBEGame

Doit使用系统查看器创建类SBEGame。
选择SBE-Quinto类分类,编辑类创建代码如下

SBEGame

代码意思创建BorderedMorph的子类。Morph是所有图形类的超级父类,而BorderedMorph类是带有边框的子类。
然后在SBEGame中定义一个初始化方法initialize

Doit选择all协议,输入下面的代码

SBEGame-initialize

选择accept it的时候,Squeak会说明其中一些短语缺少定义,其中一个是cellsPerSide。提供了一些建议选项来修正拼写错误。

unknown selector

然而cellsPerSide并不是一个错误,仅仅是一个未定义的方法,接下来选择创建它。

Doit选择第一个选择,确认事宜cellSPerSide.
接着提示cells也是未知的,提供了修正选项

Doit选择declare instance声明一个实例变量

接下来会说明NeCellAt:at:也是未知的,同样确认。
然后再次查看整个对象 会发现修改后的保护cells变量。

那么分析下initialize方法
第一行声明四个临时变量 sampleCell width height n
作用域与生命周期仅仅在这个方法,临时变量有助于代码的可读性。
smalltalk并不会区分常量与变量,事实上这四个变量是常量。接下来的几行定义了这些常量

那么board是多大。需要容纳足够的cells和边界框。那么其中包含多少个块呢,我们并不知道,因此需要使用cellsPerSide来。

这个方法会在后面进行定义,这种编写代码的方式是一种非常良好的方式,因为当我们进行初始化的时候才知道我们需要什么,然后我们给出有意义的方法名称,不需要打断我们的思路

接下来会获取cell的数量赋值给n.
接下来创建SBECell对象,赋值高度与宽度,
接下来设置buonds属性。
最后实则cells变量属性,使用Matrix。
需要使用两个参数i j。
创建一个nxn矩阵初始化元素。初始化值依赖于坐标信息。

接受到初始化方法的时候,需要抓住机会格式化输出。选择more...>prettyprint会进行自动排版,需要再次保存accept

2.7 保存方法到协议中

让我们快速浏览下第三个面板。正如第一个面板用来保存类分类,第三个面板保存方法分类的协议。

如果只有少量的方法,不需要使用特定协议,这也是为什么仅仅提供all协议,

Doit有偶记选择categorize all uncategorized来修正,移动初始化方法到初始化协议中

Squeak如何识别合适的协议接口?通常Squeak并不会进行识别,但是这种情况initialize是一个父类的方法,假设我们的初始化方法应该属于父类的同样协议接口类

可以发现Squeak会自动将initialize方法归类到initialization协议,

smalltalk使用>>来定义一个方法所属的类,可以使用SBEGame>>cellsPerSide。

从现在开始,我们将会使用这种方法说明类的方法,

使用SBEGANME>>initialize方法定义方法

依次定义cellsPerSide ,newCellAt ,toggleNeighboursOfCellAt等方法

Doit将最后一个方法拖放到game logic协议中

2.8 试试运行

到此完成所有代码编写
包含两个类和7个方法

Doit 在workspace中输入SBEGame new openInWorld,然后选择do it

也许可能出现一个错误提示窗口,
这是需要调试器进行修正

Doit点击debug按钮

debug

出现调试器界面,顶层窗口输出运行栈,显示所有调用的方法。
选择其中的一个,将会显示在中间。
其中错误的代码会高亮显示

Doit选择其中的第二条语句

调试器会显示运行的上下文如下。

debugger context

调试器的下方是两个探测窗口,左侧显示接受消息的对象,可以查看对象的各个实例变量的值

右侧查看对象执行当前方法的状态,可以查找方法的参数值与临时变量

使用调试,可以逐行运行代码,查看对象的形参与临时变量,最为惊奇的是可以在调试过程中修改代码。因此编程过程在调试中完成。这种调试方式可以查看编写方法特定运行上下文与形参的运行状态,

分析代码中的bug。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,649评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,621评论 18 399
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,235评论 11 349
  • 重点掌握 3 类对象和方法 对象就是一个物体 类的独特存在就是一个实例,对实例进行操作叫做方法。方法可以应用于类或...
    Coder大雄阅读 1,258评论 0 2
  • 不安分似乎渗透在我的血液中。 99年大学毕业,师范院校的同学们纷纷回到家乡做老师,我却离乡背井从四川大...
    课间操阅读 252评论 2 3