Seaside Tutorial
Software Architecture Group

3 - ToDo Application

What you are going to learn

Model Overview

We have discussed the basic features of Seaside and demonstrated their use. Now, we will start to develop our ToDo Application. First of all, Seaside implements a precise separation between the model and the view of data. So before we can start to build the Web site (view), we need to think about the model. This chapter describes the two main classes StUser and StTask, which we derive from our description (see chapter "Introduction"). Figure 3.1 shows a UML (Unified Modeling Language) chart with the dependency between the two classes.

Figure 3.1: ToDo Application (UML Diagram)

The user can administer tasks in our application. This short specification suggests to us the UML chart in figure 3.1. The system is used by different users, each of whom has a set of individual tasks (aggregation in figure 3.1). The data model is deliberately kept very simple because we do not want to distract the reader's attention from Seaside. It is easily possible to integrate your own (possibly more sophisticated) data models into a Seaside application.

In the following, we explain the attributes and methods of the classes StUser and StTask in detail. The topic Persistence is the content of chapter 8.

User Model

The user class is the most important class in our data model. An arbitrary number of users will be created in our application and saved in the database later on. Users will be identified in distinct sessions after the log in process. Based on the user's session, all further data, their tasks for instance, will be found, so that only their owner can manage them. The following class definition shows the StUser class with its instance variables required for identification, authentication, registration and application-specific properties.

Object subclass: #StUser
 
instanceVariableNames: 'id userName email tasks password'
 
classVariableNames: ''
 
poolDictionaries: ''
 
category: 'STTutTodoApp'
StUser

After the creation of the class StUser, it is highly recommended that you perform automatic creation of instance variable accessors. One possible way to do this in Squeak is to use the context menu on a class among the entry more.... There, you can find create inst var accessors. Select this command to have all accessors created. In different browsers or environments, this feature may be accessed differently, so consult your system documentation in case you are not using Squeak and its standard browser. When all else fails, you will have to use hand-written accessor methods.

If you look at the source code, you can see the super class of StUser is Object. That is, the entire model of the application is independent from Seaside. This implies that reusing existing models is also possible. Later on, we will use Seaside to link the model and view to a dynamic Web page.

The class StUser provides the following instance variables:

id
A unique key for identifying persistent objects primarily used in databases as primary key.
userName
A String object, which is used for addressing the user.
email
For uniqueness of registration and usernames we require their email address (String). Additionally, we can contact the user personally.
tasks
This attribute reflects the aggregation of the UML chart. An OrderedCollection consists of task objects and is assigned to every user individually.
password
Based on standard security mechanisms, the password is encrypted with a hash function (for example SHA-1) and stored in this attribute as a String. This way, we guarantee that no password string is saved directly.

In addition to the accessor methods, this class has two extra methods:

initialize
 

 
self tasks: OrderedCollection new.
StUser>>#initialize

The initialize method creates a new OrderedCollection for tasks of every new user object.

addTask: aTask
 

 
^ self tasks add: aTask
StUser>>#addTask:

The method just adds a task object to the collection. It may be surprising that there is no #removeTask: method. The reason for this is in our specification: we want to show completed tasks, so we do not require a delete function. This may seem like an example of bad practice for application development, but the simplification has a few advantages. If you develop your own applications, remember to delete your obsolete objects.

Task Model

The class StTask shows our task's data model. A task always belongs to an ordered collection of tasks maintained by its owning user. However, it does not need to know about the user object and can be seen as a unit of its own. Its properties give the task the ability to describe and file itself and to deposit its state in time and process. It is important to mention not to mix it up with the WATask of Seaside. Both are completely different classes and have nothing in common.

Object subclass: #StTask
 
instanceVariableNames: 'completed deadline taskDescription id taskName'
 
classVariableNames: ''
 
poolDictionaries: ''
 
category: 'STTutTodoApp'
StTask

The StTask inherits from Object and so it does not have a direct connection to Seaside. Again, the accessor methods can be generated automatically. There is nothing mysterious about the class, the instance variables are the following:

completed
The state whether a task is finished or not. Only the Boolean value is saved.
deadline
The date by which the task should be completed. This value is used in subsequent computations by the two test methods (see below).
taskDescription
A text describing the task in detail.
id
Analogous to the StUser, a primary key is required for database storage.
taskName
A name that briefly describes the task.
You should not use the variable names name and description instead of taskName and taskDescription because both names are used internally in Squeak.

Analogous to StUser, there are again two special methods that, this time, test the completion state of a task.

isPending

 
^ self completed not and: [self deadline >= Date today]
StTask>>#isPending

This method tests whether the state of the task has been completed or not. If the deadline is still ahead and if the task has not yet been completed, it will be pending.

hasBeenMissed

 
^ self completed not and: [self deadline < Date today]
StTask>>#hasBeenMissed

This method describes a logical value that shows whether the deadline has been crossed without the task having been finished by the user.

Remember to initialize the task with a default state for completed and for the deadline:

initialize

 
self
 
 
deadline: Date tomorrow;
 
 
completed: false.
StTask>>#initialize

Summary

This chapter, relatively independent from Seaside, should be the basis for the application thus the main model of a simple ToDo list for multiple users is introduced here. It is easy to understand and stores only the most necessary objects (tasks and users). The important component concept is the content of the next chapter.