海滨故人*
A Web App example powered by S3 (Seaside on Smalltalk with Squeak)


February 3, 2008

Abstract

70Smalltalk30 SmalltalkSqueak SeasideWeb SmalltalkAjax30 SeasideSmalltalk对读

使LATEX2ɛFDL(GNU Free Documentation License) http://www.gnu.org/copyleft/fdl.html 由于 广指正

Keywords: Smalltalk, Squeak, Seaside, Web App

Created: 2007 Septempber   2008 Feburary.

1 Introduction

年磨



Figure 1:

便 C++lisp1 写些

头疼–Weekly Report Excel 手时 等等

Weekly report 如人个工 该工40(Monthly report)

使ExcelExcel 个工仍然 西

个工

2 Why Seaside?

样一能呢

  1. 使给工
  2. 各个工
  3. 更改工 更改

解决是数Web应用 Web应用:

  1. 使Mantisbug份符
  2. 使JavadotNet
  3. 使Php/MySQL
  4. 使Ruby On RailsPython

低的1, Bug追踪Bug tracking Mantis 使PHP/MySQL者曾98 99Perl CGI应用仅仅使Perl PHP13并不

2解决Web应用JavaJ2EE解决 dotNet 2

4 定的线 Seaside/Smalltalk

并不SmalltalkRubyPython的对 为我C++ 沿C++脉络[1](GP) 数式lisp SmalltalkSmalltalk, 确认Smalltalk低的

  1. 8090Smalltalk SmalltalkSqueak
  2. 线Smalltalk1014
  3. WebSqueakWeb使Seaside,Web Server库可使MagmaSeasideMagma Smalltalk
  4. 得到Squeak SBE[2][3]Seaside tutorial[4]Squeak 置重方法Monticello Sunit
  5. Smalltalk70使 以业Windows Linux

Seaside on Squeak发非 220079200815 40

3 Hello World

由于TDD 方法HelloWorldWebApp 个功Web

Hello World,Web Squeak+Seaside Seasidewww.seaside.stzip Windows, MacLinux

Squeak调度圾回 GUISBE的第

Hello WorldHelloWorld


1cAp1x1-30003: HelloWorld definition
 
WAComponent subclass: #HelloWorld 
  instanceVariableNames:  
  classVariableNames:  
  poolDictionaries:  
  category: MyLearning

SeasideWAComponentHelloWorldMyLearning Squeak

HelloWorldrenderContentOn:方法


1cAp2x1-30003: in HelloWorld
 
renderContentOn: html 
  html text: Hello World!

Komanche WebHelloWorldSqueak Workspace (do it)Smalltalk


1cAp3x1-30003: in Workspace
 
WAKom  startOn: 8080. 
HelloWorld registerAsApplication: hello

WAKom 1startOn: 80808080Smalltalk 消息消息 HelloWorldregisterAsApplication:消息 ’hello’HelloWorldhelloWeb

HelloWorldWeb(firefoxie) 的地http://localhost:8080/seaside/hello Hello World!

HelloWorldrenderContentOn: 的多Web请求hello KomancheHelloWorld个该 renderContentOn:方法html方法 htmltext方法’Hello World!’

4 Interaction

使SeasideHTMLWeb应用 具就Smalltalk

HelloWorld HelloWorld

动的HelloWorldcounter时设0, counter1,counter 录了

:


1cAp4x1-40004: HelloWorld definition
 
WAComponent subclass: #HelloWorld 
  instanceVariableNames: counter 
  classVariableNames:  
  poolDictionaries:  
  category: MyLearning

HelloWorldinitialize


1cAp5x1-40004: in HelloWorld
 
initialize 
  super initialize. 
  counter:=0

super 方法由于initialize得到调 2Smalltalk Pascal线Smalltalk:=

counterHelloWorld方法increase


1cAp6x1-40004: in HelloWorld
 
increase 
  counter :=  counter  +  1

renderContentOn:


1cAp7x1-40004: in HelloWorld
 
renderContentOn: html 
  html text: Hello World! counter=; 
     text: counter printString; 
     break. 
  html anchor 
     callback: [self increase]; 
     with: counter++

2text:方法’Hello World! counter=’ 使html text:消息counter由于counter 3 counterpringString 方法 htmlbreak方法

htmlanchor方法 callback:方法数是 4 击后self increase句就self C++ this’counter++’

Web访http://localhost:8080/seaside/hello

Hello World! counter=0

counter++

counter++

Hello World! counter=1

counter++

HelloWorld使 counter

counter访setter/getter 5 HelloWorld accessorcounter访


1cAp8x1-40004: in HelloWorld
 
counter 
   counter 
 
counter: anObject 
  counter :=  anObject

C++return renderContentOn:方法


1cAp9x1-40004: in HelloWorld
 
renderContentOn: html 
  html form: [ 
    html text: Hello World! counter=. 
    html textInput on: #counter of: self. 
    html submitButton 
      callback: [self inform: conter changed to:, 
        counter printString ]; 
      value: Set]. 
  html anchor 
    callback: [self increase]; 
    with: counter++

等等 FormhtmltextInput消息 on:of: 消息的动accessor on:数是accessor#counter 6 htmlsubmitButton消息 value:方法’Set’ callback:HelloWorld inform方法counter

Web访hello



Figure 2: hello world


Setcounter 后会counter++counter 1.

5 MVC

SeasideWeb应用一样 MVC WebSmalltalkMVCGoFDesign Pattern[5]

Web (task)用于viewer,taskmodel controller

task类来task


2cAp1x1-50005: definition of MyTaskItem
 
Object subclass: #MyTaskItem 
  instanceVariableNames: id component description state owner startDate endDate 
  classVariableNames:  
  poolDictionaries:  
  category: MyLearning

各个idcomponent IOGUI等等description段对 state 等等owner责这startDate endData

使accessor

viewermodel 方法HelloWorld使HelloWorld MyTaskEditorcounteraccessormodel renderContentOn:方法


2cAp2x1-50005: in MyTaskEditor
 
renderContentOn: html 
  html table attributeAt: border put: 1; with: [ 
    self renderTableHeaderOn: html. 
    html form: [ 
      html tableData:[html textInput on: #id of: model]. 
      html tableData: [ 
        html select list: #(#IO #GUI #Engine ); 
           on: #component of: model]. 
      html tableData: [ 
        html textArea on: #description of: model]. 
      html tableData: [ 
        html select list: #(#ongoing #complete #pending); 
           on: #state of: model]. 
      html tableData: [ 
        html select list: #(#ZhangSan #LiSi #WangWu); 
           on: #owner of: model]. 
      html tableData: [ 
        html dateInput 
          callback: [:v | model startDate: v]; 
          value: model startDate]. 
      html tableData: [ 
        html dateInput 
          callback: [:v | model endDate: v]; 
          value: model endDate]. 
      html tableData: [ 
        html submitButton 
          callback: []; 
          value: Save]]]

HelloWord 使atrributeAt:put:方法框宽 1使with:方法renderTableHeaderOn:方法 使 本编等等使方法 model),accessor

Smalltalk使 #( 1, 2, 3)数数1, 2, 3单词串

Save

renderTableHeaderOn:消息仅仅


2cAp3x1-50005: in MyTaskEditor
 
renderTableHeaderOn: html 
  html tableRow: 
    [html tableHeading: ID. 
    html tableHeading: Component. 
    html tableHeading: Description. 
    html tableHeading: State. 
    html tableHeading: Owner. 
    html tableHeading: Start Date. 
    html tableHeading: End Date. 
    html tableHeading: Action].

ControllerMyTaskController拥有 modelviewerControllermodelcontroller 使

MyTaskController


2cAp4x1-50005: definition of MyTaskController
 
WAComponent subclass: #MyTaskController 
  instanceVariableNames: model viewer 
  classVariableNames:  
  poolDictionaries:  
  category: MyLearning

WACmoponent方法


2cAp5x1-50005: in MyTaskController
 
initialize 
  super initialize. 
  model :=  MyTaskItem new. 
  viewer :=  MyTaskEditor new. 
  viewer model: model.

ControllerrenderContentOn:击后 task


2cAp6x1-50005: in MyTaskController
 
renderContentOn: html 
  (html anchor) 
    callback: [self call: viewer]; 
    with: edit task

controllerseasideMVCWeb workspacedo it”。


2cAp7x1-50005: in Workspace
 
MyTaskController registerAsApplication: mytask.

访http://localhost:8080/seaside/mytask edit tasktask



Figure 3: mvc


Saveviewercontroller

6 More MVC

在这task task list

MyTaskList拥有MyTaskController task用于 taskMyTaskEditorSaveMyTaskListTask

MyTaskList的定


3cAp1x1-60006: definition of MyTaskList
 
WAComponent subclass: #MyTaskList 
  instanceVariableNames: controllers newTaskController 
  classVariableNames:  
  poolDictionaries:  
  category: MyLearning

controllers),task newTaskControllercontroller用于

MyTaskList


3cAp2x1-60006: in MyTaskList
 
initialize 
  super initialize. 
  controllers :=  OrderedCollection new. 
  newTaskController :=  MyTaskController new initialize; observer: self.

controllers() newTaskController使Observer 便controllercontroller

MyTaskList得到


3cAp3x1-60006: in MyTaskList
 
notify: aTaskItem 
  controllers add: (MyTaskController new initialize; model: aTaskItem; observer: self). 
  newTaskController initialize.

controller modelMyTaskList

SeasideWAComponent WAComponentchildern WAComponentMyTaskListchildern


3cAp4x1-60006: in MyTaskList
 
children 
  |array| 
  array :=  OrderedCollection new. 
  controllers do: [:x | array add: x viewer]. 
  array add: newTaskController viewer. 
  array

controller OrderedCollection

使childernWeb


3cAp5x1-60006: in MyTaskList
 
renderContentOn: html 
  html table attributeAt: border put: 1; 
    with: [ 
      self renderTableHeaderOn: html. 
      controllers do: [:x | html tableRow: [html render: x viewer]]. 
      html tableRow: [html render: newTaskController viewer]]

renderTableHeaderOn:MyTaskEdtior MyTaskListcontrollers htmlrender:方法viewer

由于MyTaskListMyTaskController


3cAp6x1-60006: definition of MyTaskController
 
WAComponent subclass: #MyTaskController 
  instanceVariableNames: model viewer observer 
        ...

助重accessor方法 MVCviewermodel controlleraccessorviewer访model controller访


3cAp7x1-60006: in MyTaskEditor
 
model 
  self controller model

MyTaskController


3cAp8x1-60006: in MyTaskController
 
initialize 
  super initialize. 
  model :=  MyTaskItem new. 
  viewer :=  MyTaskEditor new controller: self.

MyTaskEditorsaveviewer controllerobservertask


3cAp9x1-60006: in MyTaskEditor
 
renderContentOn: html 
  html form: [ 
    html tableData: [html textInput on: #id of: (self model)]. 
    ... 
    ... 
    html tableData: [html submitButton 
      callback: [self controller observer notify: self model]; 
           value: Save]]

使MVC使 访3

些信Save入任


 

Figure 4: 入任


7 Database

存储 MyTaskList 访 存储方法 Magma可靠

MagmaSmalltalk的对使SQL 使Squeak Magma便[4]persistence 者在由于解决方法 http://www.squeaksource.com/Magma/seaside package-cacheMonticello Monticello

magma testermcmSqueak Monticellopackage-cache底的Repositorymcm squeakMagma

访问网它所访库控 singletonSmalltalk义一 Instance


4cAp1x1-70007: definition of MagmaTaskDatabase
 
AbstractTaskDatabase subclass: #MagmaTaskDatabase 
  instanceVariableNames: session 
  classVariableNames: Instance 
  poolDictionaries:  
  category: MyLearning

方法(C++static方法)


4cAp2x1-70007: in MagmaTaskDatabase class
 
instance 
  Instance ifNil: [Instance :=  super new. Instance initialize.]. 
  Instance

的对方法task


4cAp3x1-70007: in MagmaTaskDatabase
 
initialize 
  self tasks ifNil:[self createTasks]. 
 
createTasks 
  self session 
    commit: [self session root at: tasks put: OrderedCollection new]

Session[4]

task


4cAp4x1-70007: in MyTaskList
 
notify: aTaskItem 
  MagmaTaskDatabase instance add: aTaskItem. 
  ...

MagmaTaskDatabaseadd:方法


4cAp5x1-70007: in MagmaTaskDatabase
 
add: item 
  self session commit: [self tasks add: item]

8 Furthur works

Web应用 一一

  1. 改功 改功2方法controller isAddingnotify 方法viewertasktaskid controller
  2. 5 task task解决 taskuser Smalltalk
  3. 得到
  4. Seasidesession[4]
  5. AjaxSeasideAjax使JavascriptXML

Web的读 HTML,CSS,XML应用

References

[1]   Liu Xinyu. “” http://baredog.at.infoseek.co.jp/intl/chn/softdev/book1/essay7.htm

[2]   Alec Sharp. “Smalltalk By Example.” McGraw-Hill, 1997. PDF version. http://www.iam.unibe.ch/ ducasse/WebPages/FreeBooks.html

[3]   Andrew P.Black, St閜hane Ducasse, Oscar Nierstrasz, Damien Pollet, with Damien Cassou and Marcus Denker. “Squeak By Example.” www.squeakbyexample.org

[4]   Software Architecture Group Hasso-Plattner-Institut (Michael Perscheid, Martin Beck, Stefan Berger, Peter Osburg, Michael Haupt, Robert Hirschfeld). “Seaside tutorial”. http://www.hpi.uni-potsdam.de/swa/????

[5]   Gamma, Erich; Richard Helm, Ralph Johnson, and John Vlissides. “Design Patterns: Elements of Reusable Object-Oriented Software.”, Addison-Wesley. 1995.

*

Liu Xinyu
5-2-201, ShiZiPo, Xi, DongZhiMenWai, DongCheng district, Beijing, 100027, P.R.China
Email: liuxinyu95@gmail.com
Tel: +86-1305-196-8666
Fax: N.A.

1 Smalltalk方法C++Java方法

2 Smalltalk方法C++动调

3 SmalltalkJavaprimitive

4 Smalltalkblock

5 Smalltalk”、”

6 C++指针