Protocols

Class Interface

A class has two parameters:

viMethod is used to pass the method to be executed by the class. The method is passed to the class as a parameter and is directly assigned to the attribute structure to improve readability and ensure upward compatibility. This notation is similar to other object-oriented languages that reference methods using the dot notation; e.g. customer.add().

viSelf is used to pass the calling class base name. Passing this name allows a super-class that inherits a method to call or access the attributes of the subclass for run-time inheritance.

The base name is the name of the logical class. For example, the logical class CustomerTableUI is implemented as zCustomerTableUI (the class) and aCustomerTableUI (the attribute structure) in Zim.

Please review Section 3.6 for an example of run-time inheritance.

The message to an object consists of:

• data values assigned to the attribute structure

• any named sets

• the class call

• method

• self parameter

Class interface consists of the following:

Name

Description

Example

Class Name

The name of the class.

zCustomer

Method

The method to be executed.

add

Self

The child class.

Refer Section 3.6.

Attribute Structure

The attribute structure associated with the class.

aCustomer

Named Set

The named set associated with the class.

sCustomer

 

The interface of a Zim class is:

classname(method, self)

An example call to a Zim class:

zCustomer('add','')

Note: Self is only used for inherited calls, not delegated requests. Please refer to the Inheritance section.

4.1.2 Method Interface

4.1.2.1 Public Methods

Other classes and the owning class can call a public method. Methods are defined in the method dispatcher.

The interface of a public method:

method(self)

An example call to a Zim class:

mAdd(viSelf)

4.1.2.2 Private Methods

The owning class can only call a private method. Private methods can have any number of parameters.

The interface of a private method:

method(<<param>>)

An example of call to private method:

mpGetStatus(viStatus, voMessage)

4.1.3 Exception Handling

Exceptions are passed via the standard exception attribute oException (e.g. aCustomer.oException).

To throw an exception, a string is assigned to the oException attribute and the ’set exception error’ is executed.

method mAddItem (viSelf)

% Some processing here %

if $lastmember('sShoppingCart') = 0

change aMakeAnOrder \ let oException = 'noShoppingCartToUpdate' set exception error endIf % Some more processing here %

endMethod % mAddItem

The client class catches the exception (i.e. the class that called the class that threw the exception). The code that catches all exceptions is as follows:

method mCallMakeAnOrder (viSelf)

% Assign attributes here % zMakeAnOrder(’addItem’,’’)

if (let aMakeAnOrder.oException = aShoppingCart.oException) > '' set exception error endIf

endMethod % mCallMakeAnOrder

The code that catches specific exceptions is as follows:

method mCallMakeAnOrder (viSelf)

% Assign attributes here % zMakeAnOrder(’addItem’,’’)

if (let aMakeAnOrder.oException = aShoppingCart.oException) = \ 'noShoppingCartToUpdate' % do something specific % endIf

endMethod % mCallMakeAnOrder

Naming Conventions

Item

Prefix

Suffix

Example

Notes

Class Items

 

 

 

 

Class Business

z

 

zCustomer

1, 3

Class User Interface

z

UI

zCustomerUI

2, 3

Method

m

mOpen

 

 

Constructor Method

mp

 

mpCustomer

 

Finalize Method

 

 

mpFinalize

 

Method Private

mp

 

mpAutoIncrement

4

Method External

z

<method>

zCustomerAdd

3

Attribute Structure

a

 

aCustomer

 

Attribute Field Name Input

i

 

iAutoIncrement

 

Attribute Field Name Output

o

 

oStatus

 

Attribute Field Name Input/Output

<none>

 

FirstName

 

Attribute FieldName Private

p

 

pMethod

 

Parameter Input

vi

 

viMethod

 

Parameter Output

vo

 

voKey

 

Parameter Input/Output

vt

 

vtFirstName

 

Parameter Local

vl

 

vlIsConnected

 

 

Zim Objects

 

 

 

 

Constant

c

cBlue

 

 

Directory

<none>

 

Framework

 

Display

d

dCustomer

 

 

Document Structured

ds

 

dsCustomer

5

Document Unstructured

du

 

duCustomer

5

Entity

<none>

Customer

 

 

Field

<none>

FirstName

 

 

Form

f

fCustomer

 

 

Menu

mn

mnCustomer

 

 

Menu Item

mi

 

miSave

 

NamedSet

s

 

sCustomer

 

Relationship

<none>

 

Require

 

Role

<none> Cust

 

 

 

Variable

v

vSetting

 

 

Window

w

wCustomer

 

 

Non-data Form Fields

 

 

 

6

Push Button

pb

 

pbCancel

 

Scroll Bar

sb

 

sbCustomer

 

Frame

fr

frGroup

 

 

Image

im

imPhoto

 

 

Arrays implemented with forms and displays

 

 

 

 

 

Form

i

iTabControl

Item or instance

 

Display

r

rTabContorl

Array structure

 

 

4.2.1 Notes

1. Tables are named with a singular noun. The business class name that encapsulates a table(s) is a concatenation of the letter "z" and the table or named set name. The filename would have a ".z" file type e.g. customer.z

2. The user interface class filename would have a ".zui" file type e.g. customer.zui

3. Class names should be as short as possible and not more than 15 characters (including the "z"). This will leave a space for a type suffix e.g. zCustomerUI or a method name on an externalised method e.g. zCustomerPrint.

4. Private methods can have variable number of parameters.

5. It is recommended to use these prefixes for data storage documents. For example, an entity set Customer requires a temporary data storage document that is named duCustomer. Filenames for structured and unstructured documents are ".ds" and ".du" respectively. There may be times where a developer needs to use a document for persistent storage rather than an entity set. It would be permissible to omit the prefix in this case.

6. Prefixes are used for form fields that do not represent data attributes. For example the save button is labelled pbSave, not the prefix ”pb”. The form field firstName, which represents an attribute of Customer, has no prefixed.

Layout and Style

Feature

Rule

method dih

The structure of a method dispatcher follows this template:

 

dispatcher

Class z<ClassName>(viMethod, viSelf)
mp<ClassName>(viMethod, viSelf)
case
 when a<ClassName>.pMethod = ’method1’
    m<Method1>
 when a<ClassName>.pMethod = ’method2’
    m<Method2>
endCase
mpFinalise(viSelf)
endClass

the method name in the case statement matches the

case

Zim commands, functions and system variables are in mixed case with the first alphabetic character in lower case

quitTransaction

$currentMember('sCustomer')

$setCount

object names are in mixed case with the first alphanumeric character upper case; name prefixes are in lower case

FirstName

mpAutoIncrement

aCustomer

method names are in mixed case with the first alphabetic character in lower case

where aCustomer.Method = ’setCreditLimit’

breaking and indenting lines

use spaces, not tab characters

indent 2 spaces (or logical multiples of) e.g. lining up components of a let statement requires 4 spaces

let aCustomer.FirstName = 'Gordon' \
aCustomer.LastName = 'Downie'

subcommands start on a new line

find all Customer Buy Product \
where LastName = 'Cohen' \

 

sorted by ProductName \
keep Product \
evaluate (let vlTotal = $total(Price)) \
-> sProduct

subcommands in set specifications are indented 4 spaces

find all Customer \
where FirstName = 'Robbie' and LastName = 'Robertson' -> sCustomer

when boolean expressions are broken, try to indent by logic

find 1 Customer \
where LastName = 'Cummings' \
and FirstName = 'Burton' or LastName = 'Cochrane' \
and FirstName = 'Tom'

code in a class or local class is indented

the local variable declaration is indented

on/endon exception handler statements are not indented

method mpCalculateTotal(voTotal) \
local (vlDownTo)
on error
return
endOn
let vlDownTo = $currentMember('sLineItem') – 1
top sLineItem
compute all sLineItem \
evaluate (let voTotal = $total(Price))
down vlDownTo sLineItem
endMethod

quoting

use single quotes, except where double quotes are required

when aUI.iMethod = 'Add'
let aCustomer.CompanyName = "Ted's Recycled CDs"

quote character strings

let aCustomer.LastName = 'Lightfoot'

spacing

no spacing before the parentheses on class or function calls

zCustomer('add', 'CustomerUI')

$trim(LastName)

 

one space after evaluate subcommand

compute 1 Customer \
where FirstName in ('Brad', 'Dan') and LastName = 'Roberts' \
evaluate (let vlTotal = Salary)

one space before a parentheses in a operator, no space after

evaluate (let vlCredit = Credit + (5 * Level))

single space surrounding operators

if vlSum > (5 * 3 + (4 + vlAmount))

single space after each comma in a call or list

$concat('Roch', ' ', 'Voisine')

LastName in ('Morissette', 'Murray', 'Dion', 'Lang', 'McLachlan')

single space before the line continuation backslash

find 1 Customer \
where FirstName = 'Neil'

Abbreviation Rules

Currently Zim limits the name of an object to 18 characters. With the addition of prefixes this can reduce the root of the object name 15-17 characters. This section specifies how to obtain a meaningful object name when shortening an identifier that exceeds this limit.

Abbreviation Guide

Apply each question to the word that you are trying to shorten until a readable abbreviation is identified [McConnell 93].

• Does a standard abbreviation exist? – check the dictionary.

• Can nonleading vowels be removed? (Customer becomes Cstmr, Product becomes Prdct, Order becomes Ordr)

• Can an acronym be created?

• Can each word be reduced to three or less letters?

• Can suffixes be removed? - such as ing, ed.

• Can the word be reduced to the first and last letters?

Translation Descriptions

To clarify abbreviations a translation description is invaluable. The translation is stored in DDDescriptions for an object defined in the Object Dictionary. For parameter names, a translation is incorporated in description of the parameter name in the ”@param” sequence.

%
% @param CstmrID the Customer ID is a unique identifier
% for the Shopping Cart
%

For more information on documentation please refer to the next section.