29.11.2014 Views

Smalltalk and Object Orientation: an Introduction - Free

Smalltalk and Object Orientation: an Introduction - Free

Smalltalk and Object Orientation: an Introduction - Free

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

28.3.3 The “aspects” protocol<br />

The next thing we will do is to look at the methods which have been defined for us by the User interface<br />

builder in the “aspects” protocol. If you examine this protocol you should find two methods defined.<br />

One called address <strong><strong>an</strong>d</strong> o ne called name. If you examine these methods you should find that their<br />

definition matches those presented below:<br />

address<br />

"This method was generated by UIDefiner. Any edits made here may be lost whenever<br />

methods are automatically defined. The initialization provided below may have been<br />

preempted by <strong>an</strong> initialize method."<br />

^address isNil<br />

ifTrue: [address := String new asValue]<br />

ifFalse: [address]<br />

We shall stop for a moment <strong><strong>an</strong>d</strong> consider what this method actually says. The method possesses one<br />

expression, the result of which will be returned when the method completes. The value will returned is<br />

dependent on the result of the isNil test. If the contents of the inst<strong>an</strong>ce variable address “is nil”<br />

then the ifTrue: clause will execute, if not then the ifFalse: clause will execute. We shall take<br />

the false case first. If address does not contain nil then the value of address is returned by the<br />

ifFalse: clause. However, if the value of address is nil, then the assignment expression in the<br />

ifTrue: clause is executed. This assignment expression creates a new inst<strong>an</strong>ce of the class String.<br />

It then sends the message asValue to this new string inst<strong>an</strong>ce. This creates a value holder around the<br />

string. This value holder with string construct is then assigned to the inst<strong>an</strong>c e variable address. The<br />

result of this expression is the value of assignment which is returned.<br />

Thus, if the address inst<strong>an</strong>ce variable has not yet been set (indicated by the value nil) <strong>an</strong><br />

appropriate value for it is generated, otherwise its value is return ed. This form of expression is referred<br />

to as lazy initialization . That is, address is initialized appropriately when it is required, rather th<strong>an</strong><br />

when the system is initialized. This c<strong>an</strong> be useful sometimes, however it does me<strong>an</strong> that every time the<br />

value of address is obtained <strong>an</strong> extra expression must be considered (i.e. isNil). This me<strong>an</strong>s that is<br />

less efficient th<strong>an</strong> initializing the value of address appropriately in <strong>an</strong> initialize method. The<br />

accessor method for the inst<strong>an</strong>ce variable name is defined in a similar m<strong>an</strong>ner.<br />

28.3.4 The “initialize” protocol<br />

Now let us define the “initialize” method protocol. This method protocol will only possess one method,<br />

initialize. This method is presented below. It inst<strong>an</strong>tiates a Dictionary object to use with the<br />

addressBook insta nce variable. Notice that once again we do not access the inst<strong>an</strong>ce variable<br />

directly. Instead we use <strong>an</strong> updater method.<br />

initialize<br />

"This method is called whenever <strong>an</strong> inst<strong>an</strong>ce of Org<strong>an</strong>izer is created"<br />

| adBook |<br />

"ApplicationModel defines its own initialize so send a message to super"<br />

super initialize.<br />

"Next we set up the address book inst<strong>an</strong>ce variable"<br />

adBook := Dictionary new.<br />

self addressBook: adBook<br />

As we are currently using lazy initialization with the ‘aspect’ methods name <strong><strong>an</strong>d</strong> address we have<br />

not init ialized them here. However, as was indicated above, it would be more efficient to do so.<br />

However, it must be remembered that they are “aspect” variables rather th<strong>an</strong> plain inst<strong>an</strong>ce variables.<br />

This me<strong>an</strong>s that for the windowing operations to work correctly they must contain a value holder, which<br />

acts as a wrapper around the actual value they represent (see the last chapter for more details).<br />

A common mistake (<strong><strong>an</strong>d</strong> the cause of much frustration) is to initialize the aspects in <strong>an</strong> initialize<br />

method as a String or a Number (with no value holder). This me<strong>an</strong>s that the “aspect” method<br />

isNil test fails <strong><strong>an</strong>d</strong> the String or Number etc. is returned. The problem is that this is not a value<br />

holder <strong><strong>an</strong>d</strong> thus c<strong>an</strong>not respond to input <strong><strong>an</strong>d</strong> output properly. Often this m<strong>an</strong>ifests itse lf when values fail<br />

to update themselves or updates from the user fail to propagate to the inst<strong>an</strong>ces etc. Thus appropriate<br />

initialization should follow that used in the aspect methods, e.g.<br />

address := String new asValue.<br />

name := String new asValue.<br />

240

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!