📄 ch03s05.html
字号:
[win] whileFalse: [ numinput _ WANumberInput new. numinput addMessage: 'Guess a number [0, 100]: '. guess _ (self call: numinput) asInteger. (guess < answer) ifTrue: [self inform: 'Number too small.']. (guess > answer) ifTrue: [self inform: 'Number too big.']. (guess = answer) ifTrue: [win _ true].]. self inform: 'Congratulations!'.</pre><p>用Java风格语法来写,上面的代码相当于(下列代码不符合任何语言):</p><pre class="programlisting">public class WAGuessNumber extends WATask{ public void go() { Object answer, win, guess, numinput; answer = new Random().nextInt(100); win = false; while (!win) { numinput = new WANumberInput(); numinput.addMessage( “Guess a number [0, 100]: “); guess = call(numinput).toInteger(); if (guess < answer) inform(“Number too small.”); if (guess > answer) inform(“Number too big.”); if (guess = answer) win = true; } inform(“Congratulations!”); }}</pre><p>这里用到的inform是WAComponent提供的一个便利方法,我们可以察看它的代码:</p><pre class="programlisting">inform: aString self call: (WAFormDialog new addMessage: aString)</pre><p>相应的Java风格代码(下列代码不符合任何语言):</p><pre class="programlisting">public void inform(Object aString) { Object dialog = new WAFormDialog(); dialog.addMessage(aString); this.call(dialog);}</pre><p>这个用法和我们之前使用WAYesOrNoDialog的方法是一模一样的,只不过这次我们只需要一个OK按钮。事实上,WAComponent也提供了另一个便利方法confirm用来调用WAYesOrNoDialog,其效果和我们刚才的例子非常相似。</p><p>您可以看看现在的WAGuessNumber代码,是不是和我们用C写的第一个猜数字游戏几乎一样?另外,您还可以把它加入任何Seaside页面,它不会影响其他部件。</p><p>要在Seaside中真正运行WAGuessNumber,我们还有几个步骤要完成。首先,我们要为WAGuessNumber加入一个class method,如下:</p><pre class="programlisting">canBeRoot ^ true</pre><p>用Java风格语法写,就是(以下代码不符合任何语言):</p><pre class="programlisting">public class WAGuessNumber{ public static boolean canBeRoot() { return true; } . . . .}</pre><p>这是通知Seaside我们的WAGuessNumber是一个顶级部件。然后我们到Seaside config,加入一个新的entry point叫做guessnum。这个名字将成为WAGuessNumber的URL。</p><div class="screenshot"><div class="mediaobject"><img src="resources/config-guessnum.png"></div></div><p>点击Add后,我们就可以配制这个页面了。找到Root Component一栏,您会看到所有canBeRoot返回true的WAComponent子类。选中WAGuessNum并按下done。</p><div class="screenshot"><div class="mediaobject"><img src="resources/guessnum-root.png"></div></div><p>好了,现在到<code class="uri">http://localhost:9090/Seaside/guessnum</code>,您就能看到我们刚刚写好的猜数字游戏:</p><div class="screenshot"><div class="mediaobject"><img src="resources/guessnum.png"></div></div><p>我们的猜数字游戏到这里就完成了。如果您有兴趣,您还可以把WAMultiCounter稍作修改,把WACounter new改为WAGuessNum new:</p><pre class="programlisting">initialize counters _ (1 to: 5) collect: [:i | WAGuessNum new]</pre><p>回到<code class="uri">http://localhost:9090/seaside/multi</code>,您就可以同时玩五个相互独立的猜数字游戏:</p><div class="screenshot"><div class="mediaobject"><img src="resources/multi-guessnum.png"></div></div><p>在我们结束这个例子之前,我希望您能注意到Seaside中的层次结构和传统的网络程序不一样。PHP smarty和Spring MVC等等都将不混合HTML代码和逻辑代码作为目标,但在Seaside中HTML都是由程序生成的,每个component既是controller又是view。Seaside的核心则在于部件之间在时间和空间上的组合。时间上Seaside突出可以重复使用的简单WAComponent,以及集中表现逻辑的WATask之间的call/answer分层;空间上Seaside突出一个页面内部件之间的套用。而这两种分层在传统结构中不是很复杂就是几乎不可能。</p><p>我们的Seaside之旅就到这里结束了,在此我们回顾一下Seaside主页上注明的Seaside四大特点:</p><div class="orderedlist"><ol type="1"><li><p>程序性生成HTML代码;</p></li><li><p>基于callback的链接。我们不必为每个链接想一个独特的名字,然后再根据用户提交回来的名字进行下一步操作。Seaside中代码可以直接放在链接里;</p></li><li><p>以部件为核心。Java网络程序员对这点一定不会陌生了,但是 Seaside的干净简洁很可能会让您耳目一新。没有XML,不需要阅读“如何创建自己的部件”,没有小小的无意义的不便之处(如tapestry的页面二次展开,或需要重新学习OGNL等小“语言”),也没有厚厚的specification。您只需要记住:一、WAComponent的子类就是部件,二、母部件需要在child函数中返回自己的所有子部件;</p></li><li><p>连续的事件逻辑。一次用户操作的完整逻辑可以放在一个单独的函数里,就算在整个过程中用户会看到若干个页面。</p></li></ol></div><p>到这里我希望您已经对Seaside的这些特点有了相当的认识,也希望这里简单的例子已经激起了您进一步了解Seaside以及其他continuation框架的兴趣。</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03s04.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch03.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4. 部件之间的call和answer </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 4. Continuation的实现</td></tr></table></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -