SMALLTALK
BEST PRACTICE
PATTERNS

<figure><img src="image_1.png" /></figure>

KENT BECK
Smalltalk
Best Practice
Patterns

Kent Beck
Library of Congress Cataloging-in-Publication Data

Beck, Kent.

Smalltalk best practice patterns / Kent Beck.

p. cm.

Includes index.

ISBN 0-13-476904-X (pbk.)

1. Smalltalk (Computer program language) I. Title.

QA76.73.S59B43 1997

005.13'3--dc20

96-29411

CIP

Editorial/Production Supervision: Joe Czerwinski

Acquisitions Editor: Paul Becker

Manufacturing Manager: Alexis R. Heydt

Cover Design Director: Jerry Votta

Cover Design: Design Source

©1997 by Prentice Hall PTR
Prentice-Hall, Inc.
A Division of Simon and Schuster
Upper Saddle River, NJ 07458

The publisher offers discounts on this book when ordered
in bulk quantities. For more information, contact:

Corporate Sales Department
Prentice Hall PTR
One Lake Street
Upper Saddle River, NJ 07458

Phone: 800-382-3419

Fax: 201-236-7141

E-mail: corpsales@prenhall.com

All rights reserved. No part of this book may be reproduced
in any form or by any means, without permission in writing
from the publisher.

Printed in the United States of America

10 9 8 7 6 5 4 3 2 1

ISBN: 0-13-476904-X

Prentice-Hall International (UK) Limited, London

Prentice-Hall of Australia Pty. Limited, Sydney

Prentice-Hall of Canada Inc., Toronto

Prentice-Hall Hispanoamericana, S.A., Mexico

Prentice-Hall of India Pte. Ltd., New Delhi

Prentice-Hall of Japan, Inc., Tokyo

Simon & Schuster Asia Pte. Ltd., Singapore

Editora Prentice-Hall do Brasil, Ltda., Rio de Janeiro
# Contents

## PREFACE vii

### 1. INTRODUCTION 1

CODING 1
*Talking Programs*. 3

GOOD SOFTWARE 4

STYLE 6

WHAT'S MISSING? 7

BOOK ORGANIZATION 9

ADOPTION 9

LEARNING A PATTERN 10

### 2. PATTERNS 13

WHY PATTERNS WORK 14

ROLE OF PATTERNS 15

*Reading*. 15

*Development*. 15

*Review*. 16

*Documentation*. 16

*Clean Up*. 16

FORMAT 16
3. BEHAVIOR..................................................19

<table><tr><td>METHODS</td><td>20</td></tr><tr><td>Composed Method</td><td>21</td></tr><tr><td>Constructor Method</td><td>23</td></tr><tr><td>Constructor Parameter Method</td><td>25</td></tr><tr><td>Shortcut Constructor Method</td><td>26</td></tr><tr><td>Conversion</td><td>28</td></tr><tr><td>Converter Method</td><td>28</td></tr><tr><td>Converter Constructor Method</td><td>29</td></tr><tr><td>Query Method</td><td>30</td></tr><tr><td>Comparing Method</td><td>32</td></tr><tr><td>Reversing Method</td><td>33</td></tr><tr><td>Method Object</td><td>34</td></tr><tr><td>Execute Around Method</td><td>37</td></tr><tr><td>Debug Printing Method</td><td>39</td></tr><tr><td>Method Comment</td><td>40</td></tr><tr><td>MESSAGES</td><td>43</td></tr><tr><td>Message</td><td>43</td></tr><tr><td>Choosing Message</td><td>45</td></tr><tr><td>Decomposing Message</td><td>47</td></tr><tr><td>Intention Revealing Message</td><td>48</td></tr><tr><td>Intention Revealing Selector</td><td>49</td></tr><tr><td>Dispatched Interpretation</td><td>51</td></tr><tr><td>Double Dispatch</td><td>55</td></tr><tr><td>Mediating Protocol</td><td>57</td></tr><tr><td>Super</td><td>59</td></tr><tr><td>Extending Super</td><td>60</td></tr><tr><td>Modifying Super</td><td>62</td></tr><tr><td>Delegation</td><td>64</td></tr><tr><td>Simple Delegation</td><td>65</td></tr><tr><td>Self Delegation</td><td>67</td></tr><tr><td>Pluggable Behavior</td><td>69</td></tr><tr><td>Pluggable Selector</td><td>70</td></tr><tr><td>Pluggable Block</td><td>73</td></tr><tr><td>Collecting Parameter</td><td>75</td></tr></table>

4. STATE......................................................79

<table><tr><td>INSTANCE VARIABLES</td><td>80</td></tr><tr><td>Common State</td><td>80</td></tr><tr><td>Variable State</td><td>82</td></tr><tr><td>Explicit Initialization</td><td>83</td></tr><tr><td>Lazy Initialization</td><td>85</td></tr><tr><td>Default Value Method</td><td>86</td></tr><tr><td>Constant Method</td><td>87</td></tr><tr><td>Direct Variable Access</td><td>89</td></tr><tr><td>Indirect Variable Access</td><td>91</td></tr></table>
<table><tbody><tr><td>Getting Method</td><td>93</td></tr><tr><td>Setting Method</td><td>95</td></tr><tr><td>Collection Accessor Method</td><td>96</td></tr><tr><td>Enumeration Method</td><td>99</td></tr><tr><td>Boolean Property Setting Method</td><td>100</td></tr><tr><td>Role Suggesting Instance Variable Name</td><td>102</td></tr><tr><td>TEMPORARY VARIABLES</td><td>103</td></tr><tr><td>Temporary Variable</td><td>103</td></tr><tr><td>Collecting Temporary Variable</td><td>105</td></tr><tr><td>Caching Temporary Variable</td><td>106</td></tr><tr><td>Explaining Temporary Variable</td><td>108</td></tr><tr><td>Reusing Temporary Variable</td><td>109</td></tr><tr><td>Role Suggesting Temporary Variable Name</td><td>110</td></tr><tr><td>5. COLLECTIONS</td><td>113</td></tr><tr><td>CLASSES</td><td>114</td></tr><tr><td>Collection</td><td>115</td></tr><tr><td>OrderedCollection</td><td>116</td></tr><tr><td>RunArray</td><td>118</td></tr><tr><td>Set</td><td>119</td></tr><tr><td>Equality Method</td><td>124</td></tr><tr><td>Hashing Method</td><td>126</td></tr><tr><td>Dictionary</td><td>128</td></tr><tr><td>SortedCollection</td><td>131</td></tr><tr><td>Array</td><td>133</td></tr><tr><td>ByteArray</td><td>135</td></tr><tr><td>Interval</td><td>137</td></tr><tr><td>COLLECTION PROTOCOL</td><td>139</td></tr><tr><td>IsEmpty</td><td>139</td></tr><tr><td>Includes:</td><td>141</td></tr><tr><td>Concatentation</td><td>143</td></tr><tr><td>Enumeration</td><td>144</td></tr><tr><td>Do</td><td>146</td></tr><tr><td>Collect</td><td>147</td></tr><tr><td>Select/Reject</td><td>149</td></tr><tr><td>Detect</td><td>150</td></tr><tr><td>Inject:into:</td><td>152</td></tr><tr><td>COLLECTION IDIOMS</td><td>153</td></tr><tr><td>Duplicate Removing Set</td><td>154</td></tr><tr><td>Temporarily Sorted Collection</td><td>155</td></tr><tr><td>Stack</td><td>156</td></tr><tr><td>Queue</td><td>157</td></tr><tr><td>Searching Literal</td><td>159</td></tr><tr><td>Lookup Cache</td><td>161</td></tr><tr><td>Parsing Stream</td><td>164</td></tr><tr><td>Concatenating Stream</td><td>165</td></tr></tbody></table>
<table><tr><td><strong>6. CLASSES</strong></td><td><strong>167</strong></td></tr><tr><td>Simple Superclass Name</td><td>168</td></tr><tr><td>Qualified Subclass Name</td><td>169</td></tr><tr><td><strong>7. FORMATTING</strong></td><td><strong>171</strong></td></tr><tr><td>Inline Message Pattern</td><td>172</td></tr><tr><td>Type Suggesting Parameter Name</td><td>174</td></tr><tr><td>Indented Control Flow</td><td>175</td></tr><tr><td>Rectangular Block</td><td>177</td></tr><tr><td>Guard Clause</td><td>178</td></tr><tr><td>Conditional Expression</td><td>180</td></tr><tr><td>Simple Enumeration Parameter</td><td>182</td></tr><tr><td>Cascade</td><td>183</td></tr><tr><td>Yourself</td><td>186</td></tr><tr><td>Interesting Return Value</td><td>188</td></tr><tr><td><strong>8. DEVELOPMENT EXAMPLE</strong></td><td><strong>191</strong></td></tr><tr><td>PROBLEM</td><td>191</td></tr><tr><td>START</td><td>192</td></tr><tr><td>ARITHMETIC</td><td>194</td></tr><tr><td>INTEGRATION</td><td>198</td></tr><tr><td>SUMMARY</td><td>201</td></tr><tr><td><strong>APPENDIX A: QUICK REFERENCE</strong></td><td><strong>203</strong></td></tr><tr><td><strong>INDEX</strong></td><td><strong>217</strong></td></tr></table>
# Preface

This preface will explain what this book is about. It will convince you to buy this book, or you will know why you shouldn't (more of the former than the latter, I hope).

## What's it all about?

This book is about the simple things experienced, successful Smalltalkers do that beginners don't. In a sense, it is a style guide. I have tried to penetrate beneath the surface, though, to get at the human realities that make the rules work instead of focusing solely on the rules themselves.

The topics covered are the daily tactics of programming:

* How do you choose names for objects, variables, and methods?

* How do you break logic into methods?

* How do you communicate most clearly through your code?

These are small scale issues. There are also many bigger technical reasons why projects fail (and many more nontechnical reasons).
The attraction of this set of issues is that they are so tractable. You don't have to be a programming wizard to pick good names, you just have to have good advice.

The advice is broken into 92 patterns. Each pattern presents:

* a recurring daily programming problem;

* the tradeoffs that affect solutions to the problem; and

* a concrete recipe to create a solution for the problem.

For example, here is a summary of a pattern called "Role Suggesting Temporary Variable Name":

**Problem:** What do you name a temporary variable?

**Tradeoffs:**

* You want to include lots of information in the name.

* You want the name to be short so it is easy to type and doesn't make formatting difficult.

* You don't want redundant information in the name.

* You want to communicate why the variable exists.

* You want to communicate the type of the variable (i.e. what messages it is sent).

**Solution:** Name the variable after the role it plays. The type can be inferred from context, and so doesn't need to be part of the name.

You will see in the body of the book that each pattern occupies a page or two. Each pattern includes examples (and counter-examples) from the standard Smalltalk images. Each pattern also talks about related patterns.

The patterns don't stand in isolation, 92 independent bits of advice. Patterns work together, leading you from larger problems to smaller. Together they form a system or language. The system, as a whole, allows you to focus on the problem at hand, confident that tomorrow you can deal with tomorrow's problems.

## Why should you read it?

Learning—If you are just learning Smalltalk, these patterns will give you a big jump start on making effective use of the system. Because the patterns aren't just rules, you can smoothly go from merely following the patterns, to understanding why they are the way they are, to formulating your own patterns. You will need a good basic introduction to Smalltalk in addition to this book, but reading them together will greatly accelerate your learning.
Programming—If you program in Smalltalk, these patterns will give you a catalog of techniques that work well. You will have discovered or invented many of them yourself, but the patterns may give you a fresh perspective on why they work or present nuances you hadn't considered.

Teaching—If you teach Smalltalkers, either as a mentor or in classroom training, these patterns will give you large bag of instructional material. If you are trying to explain why code should be different, it is much more satisfying for you and the learner to be able to discuss the pattern and how it applies to the particular situation.

Managing—If you manage Smalltalk projects, you may be struggling with how to apply good software engineering principles to Smalltalk. These patterns don't address that topic directly, but they can become the basis of a common vocabulary for your developers.

## What isn't it about?

This is not a book of methodology. It will not guide your entire development process. You can use it with your existing process, whether you invented it or it came out of a book. This book is about making code that works for you.

This is not a book of philosophy. If you want to understand what makes programs good in the abstract, if you want to learn to write patterns yourself, or understand their philosophical or psychological basis, you won't find any help here. This book is for people who have programs to write and want to do so as quickly, safely, and effectively as possible.

This is not a book of design. If design is the process of defining the relationships among small families of objects, the resulting problems repeat just as surely as do implementation problems. Design patterns are very effective at capturing that commonality. They just aren't the topic of this book. This book is about making Smalltalk work for you. Making objects work for you is an entirely different topic.

## Acknowledgments

I would like to thank the many people who contributed to this volume. First I would like to thank the Xerox PARC Learning Research Group (Alan Kay, Adele Goldberg, Dan Ingalls, Diana Merry-Shapiro, Ted Kaehler, Larry Tesler, and Bob Flegel) for having the insights in the first place, so I had something to write down. I would like to thank my mentor and intellectual partner, Ward Cunningham, for showing me the way and sharing his insights. Many of the patterns here he identified and/or named. Thanks to my reviewers (Dirk Riehle, David N. Smith, Mitchell Model, Bill Reynolds, Dave Smith, Trygve
Reenskaug, Ralph Johnson, John Brant, Don Roberts, Brian Foote, Brian Marick, Joe Yoder, Ian Chai, Mark Kendrat, Eric Scouten, Charles Herring, Haidong Ye, Kevin Powell, Rob Brown, Kyle Brown, Bobby Woolf, Harald Mueller, Steve Hayes, Bob Biros, David Warren, Gert Florijn, Mark L. Fussell, Martin Fowler, Chuck Siska, Chris Bird, Ron Jefferies, Volker Wurst, Peter Epstein, Thomas Murphy, Michel Brassard, Ron Jefferies, John Sellers, Steve Messick, Darrow Kirkpatrick, Phoenix Tong, Doug Lea, Randy Stafford, Sharry Fealk and all the reviewers who didn't put their names on their comments) for reading early rough drafts carefully. Finally, this book would never have been finished without my ever patient but gently prodding editor, Paul Becker.
1

Introduction

Let's start by taking a close look at the title: *Smalltalk Best Practice Patterns*. That's a mouthful. What does it mean?

*Smalltalk*—That part is easy. I assume you know at least something about Smalltalk or you wouldn't be reading this book.

*Best Practice*—Best practice is a legal term. Looked at positively, best practice is the set of procedures and skills that professionals recognize and use. Looked at negatively, if you can prove that you were using the current best practice when you did a piece of work, you can't be sued for negligence. I prefer to look at it positively. At least, I hope this book is never held up in court!

*Patterns*—A pattern is a decision an expert makes over and over. For example, naming an instance variable after the role it plays is a pattern. Even though all the results (in this case, all the variable names) are different, they have a quality that is constant. The heart of this book is 92 such patterns.

Coding

I'd like to say a bit about coding to give you a clearer idea of the activities covered by the patterns.
When computers were the province of the physics department or the math department, there was no such thing as coding as a separate activity. People had ideas, they implemented them, they looked at the results.

Developer castes appeared with the advent of commercial software development. At the top were the systems analysts, lofty intellects too important to actually use computers. Below them were the programmers, who knew how to turn the vague mutterings of the analysts into something the assembler or (later) compiler could recognize. At the bottom were coders, who took the sheets, filled out by the programmers, and created punched cards.

Better interface technology has long rendered the coder-as-typist obsolete. The word has come to mean all the low level activities of programming. The stigma remains, however. When I became a consultant, I was told, "Don't let them know you can code, or you'll never be able to charge premium rates."

I think the time has come for a redefinition of coding. Not really redefinition, I suppose, but a rehabilitation. I like the definition just fine. I think the stigma attached to it is short-sighted and dangerous.

To me, development consists of two processes that feed each other. First, you figure out what you want the computer to do. Then, you instruct the computer to do it. Trying to write those instructions inevitably changes what you want the computer to do, and so it goes.

In this model, coding isn't the poor handmaiden of design or analysis. Coding is where your fuzzy, comfortable ideas awaken in the harsh dawn of reality. It is where you learn what your computer can do. If you stop coding, you stop learning.

We aren't always good at guessing where responsibilities should go. Coding is where our design guesses are tested. Being prepared to be flexible about making design changes during coding results in programs that get better and better over time. Insisting that early design ideas be carried through is short sighted. Often, I see some ugly code in an object. Based on the patterns in this book (most often Composed Method), I'll suggest that the code be moved to another object. For example, I saw code that looked like this:

Station>>computePart: aPart

^self multiplyPartTimesRate: aPart

Station>>multiplyPartTimesRate: aPart

^Part

amount: aPart amount * self rate

date: aPart date
I said, “we seem to be using a lot of the Part’s data in multiplyPartTimesRate: Why don’t we move this code into Part?” “But we didn’t design Parts to do arithmetic!” “Since the code seems to be telling us to do this, let’s try it.”

```
Part>>* aRate
    ^Part
        amount: amount * aRate
        date: date
Station>>computePart: aPart
    ^aPart * self rate
```

The result is simpler, shorter, and exposes less of a Part’s details to the Station. Being open to design insights during coding, we learned something that made our whole system simpler.

My inspiration for the material in this book is my experience reviewing code. As I write, I remember more and more incidents, “Oh, yeah. That client was doing that wrong and it was really killing them. What can I say about that?” The advice I give in such situations is tactical, coding advice of necessity. I don’t have time for a deep understanding of their problem. I’m constantly amazed at how even a little help cleaning up small problems reveals the source and solution of much bigger problems.

## n Talking Programs

Did you know that your program talks to you? I don’t mean those “Buy more Jolt Cola” messages. I mean important stuff about how your system ought to be structured.

If you’re programming along, doing nicely, and all of a sudden your program gets balky, makes things hard for you, it’s talking. It’s telling you there is something important missing.

Many of the patterns tell you what to do when your program talks to you. Sometimes you need to create a new method, sometimes a new object, sometimes a new variable. Whatever the needed response, you have to be listening before you can react.

As programmers, we have all been through terrible experiences with systems that seemed designed to make life difficult (this word processor, for instance). It is easy to get numbed to pain and frustration, or treat it as if it
were part of the territory. Your programs don't have to be like that. You can
make them clean and simple and easy to read.

"It looks like we need to put this over here."

"We can't do that. That's not how it works."

"Wait a minute. The code would be easier to read and more flexible if we did it this way."

"But that's not what that object does."

"Let's just do it and see if we like it."

...murmel, murmela, murmela...

"Hey, that is better."

I can't begin to count how many times I've been through this scenario.
The good news is, it's not that I'm any smarter than my clients or that I can
see how to improve code where they can't. It's just that I know what to pay
attention to (what patterns to look for) and I have the confidence to simply fol-
low where the code leads.

Some of the biggest improvements come from figuring out how to eliminate:

* Duplicate code (even little bits of it)

* Conditional logic

• Complex methods

* Structural code (where one object treats another as a data structure)

These patterns will give you a toolbox of problems to look for and ways to
fix them. As time goes on, you'll find yourself creating fewer and fewer prob-
lems in the first place. I hope you get better than me, though, at writing pat-
terns correctly the first time. I still get myself into a pickle far too often.

Good Software

The patterns here form a system; one that I have developed during my
years as a Smalltalk programmer. Most of it is really the work of the
Smalltalkers who came before me and left their wisdom in the image. Some
small part is my own invention. I consider myself part of a culture. As with any
culture, there is a core set of values that drives what the culture sees as good
and what it sees as bad. What are those values?

Well, what makes a good program? There are, of course, lots of definitions
of what makes a good program, and even lots of valid definitions. In telecommu-
nications or medical instrumentation, an absolutely reliable program is a good
program. In derivatives trading, a quickly shipped program is a good program.
Most commercial software isn't so extreme. The life of most programs goes like this:

1. It is developed in a hurry by a team of developers. Time to market is critical for reducing the business risk of a new product. The product itself is technically challenging to build but doesn't break new ground in lots of areas at once.

2. The product lives for several years, during which time its capabilities are refined and extended, often by developers who weren't part of the original team.

3. Bits and pieces of the product are cannibalized for new projects, again, not by the original developers.

A good program balances the needs of these activities. No one phase can be allowed to dominate the others without risking the business viability of a system.

Sometimes, you will find a pattern supports all the phases—you will be able to develop code faster, with less risk and have it be easier to maintain and reuse. Often, though, you have to rob Peter to pay Paul. Most of the patterns are designed to preserve a balance between short-term and long-term needs.

I can't say it often enough—the bottlenecks throughout development come from limitations in human communication. Over and over in the patterns, you will read “You could do this or you could do that, but this over here communicates best, so that's what you should do.” If there's a radical thought here, that's it; that when you program, you have to think about how someone will read your code, not just how a computer will interpret it.

Here are the criteria I considered in writing these patterns, and the accommodation I made to them.

* **Productivity**—You can spend productivity gains any way you'd like—shorter time to market, reduced development cost, reduced technical risk, or improved quality. I wrote the patterns so developers of all skill levels could learn more quickly and spend less time on the mechanics of engineering good software in Smalltalk.

* **Lifecycle Cost**—If there is one driving force behind these patterns, it is the reduction of the lifecycle costs of software. Too many development organizations get into a deadly embrace with their own projects, where they are spending so much time and energy just keeping the last system alive and limping that they can't meet the needs of today's market, much less tomorrow's. I wrote the patterns so they could be taught to developers and maintainers, used day to day
in development and documentation, so that throughout the life of a project it remains easy to enhance.

*   **Time to Market**—When pressure becomes intense to get a product to market, it is tempting to cut corners. However, the very act of deciding what corners to cut slows down development. Using these patterns lets you program flat out, applying patterns as fast as your fingers will go, and get results as quickly as possible, without paying an exorbitant cost in the long run.

*   **Risk**—Risk is the great taboo in software. Everybody knows that lots of projects fail. Everybody knows that you can't really schedule software development reliably and still produce interesting products. Everybody knows that software development is risky, but nobody talks about it. When I review a project at risk, I am amazed at how often the big picture is in place, but a slew of little mistakes are gumming up the works. I wrote these patterns from my experience of seeing which little things most often hurt projects.

## Style

Good programming style is one of those things that everyone knows when they see it but is very hard to articulate precisely. The capitalist's cant—a good programming style is one that makes money—is objectively measurable but hard to apply day to day.

There are a few things I look for that are good predictors of whether a project is in good shape. These are also properties I strive for in my code.

*   **Once and only once**—If I only have one minute to describe good style, I reduce it to a simple rule: In a program written with good style, everything is said once and only once. This isn't much help in creating good code, but it's a darned good analytic tool. If I see several methods with the same logic, several objects with the same methods, or several systems with similar objects, I know this rule isn't satisfied. This leads us to the second property:

*   **Lots of little pieces**—Good code invariably has small methods and small objects. Only by factoring the system into many small pieces of state and function can you hope to satisfy the "once and only once" rule. I get lots of resistance to this idea, especially from experienced developers, but no one thing I do to systems provides as much help as breaking it into more pieces. When you are doing this, however, you must always be certain that you communicate the big picture effectively. Otherwise, you'll find yourself in a big
bowl of “Pasta à la Smalltalk,” which is every bit as nasty a dish as
“Fettucine à la C.”

*   **Replacing objects**—Good style leads to easily replaceable objects. In a really good system, every time the user says “I want to do this radically different thing,” the developer says, “Oh, I’ll have to make a new kind of X and plug it in.” When you can extend a system solely by adding new objects without modifying any existing objects, then you have a system that is flexible and cheap to maintain. You can’t do this if you don’t have lots of little pieces.

*   **Moving objects**—Another property of systems with good style is that their objects can be easily moved to new contexts. You should be able to say, “This object in this system does the same job in that system.” Warning—the first time you try to move an object, you will discover you have done it wrong, that it doesn’t generalize well. Don’t try to move it too early in the game. Ship a couple of systems first. Then, if you have a system built with lots of little pieces, you will be able to make the necessary modifications and generalizations fairly easily.

*   **Rates of change**—A simple criteria I use all the time is checking rates of change. I learned this criteria from something Brad Cox said a long time ago. I’ve since generalized it to—don’t put two rates of change together. Don’t have part of a method that changes in every subclass with parts that don’t change. Don’t have some instance variables whose values change every second in the same object with instance variables whose values change once a month. Don’t have a collection where some elements are added and removed every second and some elements are added and removed once a month. Don’t have code in an object that has to change for every piece of hardware, and code that has to change for every operating system. How do you avoid this problem? You got it, lots of little pieces.

## What's Missing?

There are a few coding topics I don't cover here; not because they aren't important, but because I don't yet understand them well enough to turn them into patterns. I hope I learn enough about them to include them in a second edition. Here are the topics I deliberately do not cover:

*   Exception handling—I use exception handling as sparingly as possible, generally, only around the highest level invocation of objects
from the user interface. Lots of handlers make debugging difficult, because the code just runs to completion but provides the wrong answer. When you use exception handling, you have to think like the writer of a new programming language, not just an application developer.

* Copying—Fixing bugs by making copies of objects before operating on them is nice and simple. Unfortunately, when copying becomes a habit, you can end up slowing down your system by making unnecessary copies or introducing bugs by not changing objects that need to be changed.

* Become—There are legitimate uses of become, but debugging code that uses it is so difficult already, if you have any other option for solving your problem, you're probably better off. If you are experienced enough to be an exception to this rule, then you won't be taking what I write as gospel anyway, so I'm not afraid to be doctrinaire on this point.

* Performance—Performance tuning is a whole topic unto itself. Its biggest problem in this context is that all the patterns here maximize the communication value of code. Performance tuning often sacrifices clarity for speed.

The definition of “coding” in the first section of this chapter, namely tactical programming decisions, excludes many topics. Here are some of the topics I hope to cover in future volumes:

* Design—There are a host of techniques that are just upstream (to my view) of the material covered here. They are the patterns whereby two objects can do a better job than one, or when turning a method or set of methods into an object provides leverage. For now, I will refer you to “Design Patterns” by Gamma et. al.

* Modeling—The patterns here resolve constraints imposed by Smalltalk. Many of the most important decisions you make must also resolve constraints imposed by the problem you are modeling.

* Requirements—How you agree with the client about what must be done, and more importantly what need not be done, has an enormous impact on the success of your development. If you don't do what's needed, the client will not be satisfied with the result. If you do what isn't needed, you add cost, time, and most importantly, risk to your project.

* User Interface Design and Implementation—Designing interfaces that users find valuable is an art. Implementing them simply, flexibly, and reusably is the test of a solid Smalltalker.
## Book Organization

Here are the chapters:

* Patterns—The philosophy behind patterns.

* Behavior—Patterns for methods and messages. The problems you can solve by creating a new method. You will also find method patterns scattered throughout the remainder of the patterns, if a particular kind of method (like accessors) is tied to another pattern. The quick reference guide gathers all the method patterns together for easy reference.

* State—Patterns for using instance and temporary variables. You will find a discussion of the pros and cons of using accessor methods and direct variable access.

* Collections—The major collection classes and messages in the form of patterns. You will also find common tricks using collections.

* Classes—A brief introduction to how to use classes, since most of the topics regarding class creation are outside the scope of this book.

* Formatting—My rules of code formatting, cast as patterns.

* Development Example—An example of developing objects with explicit reference to the patterns, as they apply.

## Adoption

How can you learn and use these patterns?

* Bag of tricks—This is the toe-dipper's approach to these patterns. If you feel like you already have a pretty good handle on Smalltalk but you want to make sure your golf bag is full of clubs, you can skim these patterns looking for new techniques. I suggest the sections on Collection Idioms and Messages as a starting point.

* Custom style guide—I've seen many development organizations, recently, where one or two experienced Smalltalkers are asked to provide leadership for a group of new Smalltalk developers. One of the first tasks of the gurus is generally to educate the troops and develop a style guide. You gurus can pick your favorite patterns from the ones presented here, add important ones that I left out, or fix ones I messed up, and use your new list as the basis for training and standards.

* Whole hog—Read the patterns through once quickly. Then set this book on your lap as you program. Every time you are about to do
anything—write a method, name a variable, name a message—look it up first. When you are sure you are following a pattern, you can quit looking it up. At first, this is sure to be frustrating, and the more experience you have before you start, the more frustrating it will be.

My experience going “whole hog” was that I spent a couple of frustrating weeks programming at less than full speed. After that, I memorized enough patterns to get back up to my old productivity, but the code I was producing was cleaner than before. After a couple more weeks, I no longer had to look up any patterns, and my productivity shot up while my code kept getting cleaner and cleaner.

Why does this work? I think it is because when I used to program, I would constantly have two parallel conversations going on in my head—what should I name this variable and how should I approach naming this variable. I was always looking for exceptions to my rules, trying to gain some small advantage. When I chose to follow the patterns explicitly, that second conver- sation disappeared and I paid more attention to the problem I was solving.

Learning a Pattern

If you’ve programmed before, whether in Smalltalk or another language, you will certainly recognize some of the patterns immediately. However, some patterns will present material that is new to you, or at least present it in a way that is unfamiliar. What do you do when faced with a pattern you don’t imme- diately understand? The following suggestions are in no particular order.

• Context—Have a look at the preceding and following patterns. Each pattern solves a small part of the problem of building good systems. Sometimes, putting a pattern in context helps you understand what part of the problem the pattern is solving.

• Example—Each pattern has an example towards the end. Look at the example and see if you can guess what rule created it. Then, check with the pattern’s solution to see if your answer is the same as mine.

• Problem/Solution—I like reading the patterns just as problems and solutions. The Quick Reference Card is organized like that. The intervening material supports the pattern, but sometimes it can be distracting. Once you understand the problem and solution, the dis- cussion may clarify your understanding.

• Look for Examples—Go through your Smalltalk image looking for examples or counter-examples to a pattern. When you see a possi-
ble example, try to understand whether the purpose of the pattern
is the same as the purpose of the writer of the code.

* Try to Write an Example—Apply the pattern to some of your own code. Use your best understanding of the pattern.
*This page intentionally left blank*
2

Patterns

Developers don't ever develop from scratch. Many problems
recur in various guises throughout development. Mature engineer-
ing disciplines capitalize on the repetitive nature of development by
collecting handbooks of adequate solutions to recurring problems. A
bridge designer designs using the solutions in the handbook, like I-
beams, not the laws of physics.

Interest in software reuse reveals a recognition that software
engineering is just as repetitious as other engineering disciplines. If
leveraging the commonality in software development is the prob-
lem, though, large scale code reuse has not proven to be the answer.

Patterns form a more flexible basis for producing systematic
variations on the common themes of software engineering. Each
pattern records a solution to a single recurring problem, including
how to recognize the presence of the problem and how to generate
the solution so that it fits the context. Patterns lead naturally one
to the other, forming a kind of flexible fabric of decisions that can
solve large scale problems.
## Why Patterns Work

Here is the Big Assumption: There are only so many things objects can do. Not in the sense that there are a limited number of applications, because there will always be new domains to model, but in the sense that the same structures of objects keep appearing over and over, regardless of the application. The problems in the construction of objects are universal. You have to name classes, relate classes via inheritance and delegation, relate methods in the same class and different classes, name variables, and so on. Patterns record these problems and how to approach solving them.

Communicating with our computers used to be the hardest thing about developing systems. It has taken years, but advances in programming languages, programming environments, and programming style have largely eliminated the barriers to instructing the computer.

When the hardest problem is solved, something else becomes the hardest problem. The next bottleneck in software engineering is human communication. When we say that 70 percent of the development budget is spent on maintenance, we mean that the poor maintainers have to wade through piles of documentation and code to discover the intent of the original programmer. The advent of widespread reuse exacerbates the problem. No longer is one maintainer the audience for one develope., Hundreds, thousands, or hundreds of thousands of elaborators are trying to understand the intent of an abstractor.

When you want to improve communication, you have two choices; either increase the bandwidth so you can communicate more bits or increase the context shared between sender and receiver so the same number of bits mean more. The first is impractical, especially in the presence of reuse (one developer can only be sliced into so many pieces), so we must find some way to make our words mean more.

When you want to optimize any process, the first strategy to employ is to find how the common case is simpler than the general case. For software engineering, the general case is the programming language. Commonly, though, we don't go all the way back to the programming language to solve problems. We look at what we did last week and last year, and what our friends did last week and last year, and do something similar.

Small, tightly knit development organizations demonstrate the cumulative effects of this kind of optimization. Because everyone shares the same experiences, a simple word or phrase takes on a big meaning. "I've got this problem, how am I going to solve it?" "Well, you could try that graphics editor trick." "Exactly. That should work great." Small organizations become dramatically more productive when they gather a critical mass of these "catch phrases."
There are two problems with relying on an oral tradition to transmit this information. First, members of the team become almost incomprehensible to someone not initiated into the dialect. Second, the process doesn't scale. The team can't grow big without losing the benefits of its private language, and one team's experience can't transfer easily to another.

Patterns are a literary form for capturing and transmitting common practice. Each pattern records a recurring problem, how to construct a solution for the problem, and why the solution is appropriate. By carrying along their justification, patterns avoid the problem of most “style guides” that simply prescribe solutions without discussing why or when the solution is appropriate. If you are faced with the recurring problem named in a pattern, after you read the pattern, you should be convinced that the solution called for in the pattern is appropriate—or you should know why it isn't.

Patterns exist and can be articulated at all levels of development. There are patterns that tell you how to schedule and sequence system development, how to create an application with a particular class library, how to design new objects, and how to format source code so that it communicates as clearly as possible.

Individual patterns become valuable when they are woven together to form a sort of flexible recipe for development. Expertise in development often hinges on knowing what problems should be solved first and what problems can be safely ignored. When each pattern names patterns that precede and complete it, the result is a rich language for capturing software engineering expertise.

## Role of Patterns

### n Reading

These patterns are used (sometimes not in precisely the form they appear here) in the construction of the Smalltalk images sold by the vendors. Early in your Small talking career, you will spend most of your time reading code from the image. If you know what to expect and you understand why the code is the way it is, you will be able to read and understand more quickly and thoroughly.

### n Development

During development, you will run into the same Smalltalk problems over and over. You can use these patterns as a guide for how to solve these problems. “What should I name this instance variable?” —flip to Role Suggesting
Instance Variable Name and follow the solution. After you use a pattern a few times, you will internalize it, so you won't have to go continuously looking up the details. You can put the quick reference guide up so you don't have to program with this whole book on your lap.

n **Review**

Group reviews will go much more smoothly if everyone knows and uses the patterns. You can use the patterns to point out opportunities for improvement in code—"I see, you need a Constructor Method for that class so these three methods can be simpler."

n **Documentation**

You can describe a system using patterns much more simply than if you use ordinary prose. A few words can take the place of many paragraphs and do a better job because so much is implied by the patterns. If I say, "#x:y: and #r:theta: are the Constructor Methods for Point," you know exactly what I am talking about (or will when you read Constructor Method on page 23).

n **Clean Up**

When I am consulting, I clean up code using the patterns as a way of both understanding what is there and preparing for making quick changes once I understand what's wrong and what's required. I generally start with the formatting patterns (page 171), then simplify methods with Composed Method (page 21) and Explaining Temporary Variable (page 108). Once I am done with this, it is easy to see where there is duplicated code, the sign of an opportunity for improvement.

**Format**

Each pattern records an atomic decision made repeatedly by experienced Smalltalk developers. They are written so you can follow them almost blindly, as just "good advice." As your understanding matures, each pattern gives you enough information that you can begin to delve into the "why" of the pattern. After you have used a pattern enough, you should begin to understand its limitations and when you should break the rule.

Each pattern has the same format, so you can quickly scan them when you are looking for a solution to a particular problem. The following elements appear in every pattern:
<table><thead><tr><td>Element</td><td>Purpose</td></tr></thead><tbody><tr><td>Title</td><td>Names the thing created as a result of executing the pattern. Intended to be used conversationally to refer to the pattern—"Oh, I think you need a State Object here."</td></tr><tr><td>Preceding patterns</td><td>Briefly describes which pattern precedes this one and why. Some patterns are non-sense taken out of order. Other orderings are the result of experience about which problems are most important and which can be safely deferred. <strong>Appears in Avant Garde Bold Italic.</strong></td></tr><tr><td>Problem</td><td>Stated as a question. Reading the problem will quickly tell you whether you are interested in the rest of the pattern. <strong>Appears in Avant Garde.</strong></td></tr><tr><td>Forces</td><td>Describes the constraints on any solution to the problem and argues for the solution called for in this pattern. After reading the forces section, you should either be convinced that the solution is valid for your situation or you should know why the solution isn't valid. Sometimes it takes the form of a description of alternatives and why they don't work, sometimes it's just a discussion of the influences on the design decision.</td></tr><tr><td>Solution</td><td>Gives you an unambiguous, concrete recipe for creating the thing named by the title of the pattern. These will typically be development environment actions—subclass this, name this variable thus-and-so, etc. <strong>Appears in Avant Garde Italic.</strong></td></tr><tr><td>Discussion</td><td>Tells you how to make practical use of the pattern. May contain an example of use or give you issues to watch out for. <strong>Appears in Avant Garde.</strong></td></tr><tr><td>Following patterns</td><td>Tells you what patterns should be considered next. <strong>Appears in Avant Garde Bold Italic.</strong></td></tr></tbody></table>
You can learn a lot about the patterns by just reading the titles, prob-
lems, and solutions. Indeed, that is what the quick reference card contains.
When you want to go beyond the simple recipes, though, you will need to study
the forces section and the links between patterns to understand their intent.
3

Behavior

Objects model the world through behavior and state. Behavior is the dynamic, active, computational part of the model. State is what is left after behavior is done, how the model is represented before, after, and during a computation.

Of the two, behavior is the more important to get right. The primacy of behavior is one of the odd truths of objects; odd because it flies in the face of so much accumulated experience. Back in the bad old days, you wanted to get the representation right as quickly as possible because every change to the representation bred changes in many different computations.

Objects (done right) change all that. No longer is your system a slave of its representation. Because objects can hide their representation behind a wall of messages, you are free to change representation and only affect one object.

Behavior in systems of objects is specified in two ways; with messages and methods. I saw a great comment at OOPSLA (the Object Oriented Programming Languages, Systems and Applications conference). It said, "This seems an awful fuss for a fancy procedure call." Well, separating computation into messages and methods and binding the message to the method at run time,
based on the class of the receiver, may seem like a small change from an ordinary procedure call, but it is a small change that makes a big difference.

This section tells you how to specify behavior so that your intent is clearly communicated to your reader. Many constraints affect your choices when specifying behavior. The more centralized the flow of control, the easier it is to follow in the sense that you don't have to go bouncing around all over the place to understand how work is accomplished. However, centralizing control kills flexibility. You want to have lots of objects involved so you have many opportunities to replace objects to change the system, and so you can completely factor code.

## Methods

Methods are important to the system because they are how work gets done in Smalltalk. Just as important, methods are the way you communicate to readers how you intended for work to get done. You must write your methods with both of these audiences in mind. Methods must do the work they are supposed to do but they must also communicate the intent of the work to be done.

Methods decompose the function of your program into easily digestible chunks. Carefully breaking a computation into methods and carefully choosing their names communicates more about your intentions to a reader than any other programming decision, besides class naming.

Methods are the granularity of overriding. A well factored superclass can always be specialized by overriding a single method, without having to copy part of the superclass code into the subclass.

Methods don't come for free. Managing all those bits and pieces of code—writing them in the first place, naming them, remembering, rediscovering, and communicating how they all fit together—all take time. If there is no benefit to be gained, bigger methods would be better than small because of the reduced management overhead.

Methods cost in performance as well. Each method invocation takes precious computer cycles. The trick to getting good performance is using methods as a lever to make your performance measurement and tuning more effective. In my experience, better factored code, with lots of small methods, both allows more accurate and concise performance measurement (because there aren't little snippets of code duplicated all over) and provides leverage for tuning (through techniques like Caching Instance Variable).

Overall, the goal of breaking your program into methods is to communicate your intent clearly with your reader, provide for future flexibility, and set yourself up for effective performance tuning where necessary.
# Composed Method

*You are implementing a method named with an Intention Revealing Selector (p. 49).*

* How do you divide a program into methods?

Programs need to do more than just instruct a computer, they need to communicate to people as well. How your program is broken into methods (as well as how big those methods are) is one of the most important decisions you will make as you refine your code so that it communicates as clearly as possible. The decision is complicated by the many factors affecting it and the history of programming practice that has traditionally optimized machine resources at the cost of people's time.

Messages take time. The more small methods you create, the more messages you will execute. If all you were worried about was how fast your program would run, you would arrange all of your code in a single method. This radical approach to performance tuning invokes enormous human costs and ignores the realities of performance tuning well-structured code, which often results in several order-of-magnitude improvements.

Simple minded performance tuning is not the only factor suggesting that large methods are best. Following the flow of control in programs with many small methods can be difficult. Novice Smalltalk programmers often complain that they can't figure out where any "real" work is getting done. As you gain experience, you will need to understand the flow of control through several objects less often. Well chosen message names let you correctly assume the meaning of invoked code.

The opportunity to communicate through intention revealing message names is the most compelling reason to keep methods small. People can read your programs much more quickly and accurately if they can understand them in detail, then chunk those details into higher level structures. Dividing a program into methods gives you an opportunity to guide that chunking. It is a way for you to subtly communicate the structure of your system.

Small methods ease maintenance. They let you isolate assumptions. Code that has been written with the right small methods requires the change of only a few methods to correct or enhance its operation. This is true whether you are fixing bugs, adding features, or tuning performance.

Small methods also make inheritance work smoothly. If you decide to specialize the behavior of a class written with large methods, you will often find yourself copying the code from the superclass into the subclass and changing a few lines. You have introduced a multiple update problem between the
superclass method and the subclass method. With small methods, overriding behavior is always a case of overriding a single method.

* Divide your program into methods that perform one identifiable task. Keep all of the operations in a method at the same level of abstraction. This will naturally result in programs with many small methods, each a few lines long.

You can use Composed Method top-down. While you are writing a method, you can (without having an implementation yet) invoke several smaller methods. Composed Method becomes a thought tool for breaking your development into pieces. Here is an example of a top-down Composed Method:

```java
Controller->controlActivity
    self controllInitialize.
    self controlLoop.
    self controlTerminate
```

You can also use Composed Method bottom-up, to factor common code in a single place. If you find yourself using the same expression (which might be only 3 or 2 or even 1 line of code), you can improve your code by putting the expression in its own method and invoking it as needed.

Perhaps most importantly, you can use Composed Method to discover new responsibilities while you are implementing. Any time you are sending two or more messages from one object to another in a single method, you may be able to create a Composed Method in the receiver that combines those messages. Such methods are invariably useful from other parts of your system.

**Create objects with a Constructor Method (p. 23). Put boolean expressions into a Query Method (p. 30). Invoke Messages to get work done elsewhere, sometimes by Delegation (p. 64). Use a Temporary Variable (p. 103) for temporary storage. Represent constants with a Constant Method (p. 87).**
<figure><img src="image_2.png" /></figure>

# Constructor Method

*A Composed Method (p. 21) has had to create an object.*

* How do you represent instance creation?

The most flexible way to represent instance creation is by a simple “new” method, followed by a series of messages from the client to the new instance. That way, if there are different combinations of parameters that make sense, the client can take advantage of just those parameters it needs.

Creating a Point in this style looks like this:

Point new x: 0; y: 0

Further flexibility is provided in this approach to half-way construct an object in one place, and then pass it off to another to finish construction. This can simplify communications if you don't have to modify the design to put all the creation parameters in one place.

On the other hand, what is the first thing you want to know about a class, once you've decided it may do what you want it to do? The first question is “What does it take to create an instance?” As a class provider, you'd like the answer to this question to be as simple as possible. With the style described above, you have to track down references to the class and read the code before you get an inkling of how to create a useable instance. If the code is complex, it may take a while before you figure out what is required and what is optional in creating an instance.

The alternative is to make sure that there is a method to represent each valid way to create an instance. Does this result in a proliferation of instance creation methods? Almost never. Most classes only have a single way to create an instance. Almost all of the exceptions only have a handful of variations. For the rare case where there really are hundreds or thousands of possible correct combinations of parameters, use Constructor Methods for the common cases and provide Accessor Methods for the remainder.

With this style of instance creation, the question “How can I create a valid instance?” can be simply answered by looking at the “instance creation” protocol of the class methods. The Intention Revealing Selectors communicate
what the instance will do for you, while the Type Suggesting Parameter Names communicate the parameters required.

* Provide methods that create well-formed instances. Pass all required parameters to them.

Point class>>x:y: is a Constructor Method because it takes both of the required numbers as parameters.

Some people think that the keywords in the Constructor Method have to be named the same as the instance variables that will eventually be initialized while constructing an instance. You should always look for a way of expressing more intention with a selector (Intention Revealing Selector). For example, Point class>>r:theta: is a Constructor Method I add when I am working in polar coordinates:

```java
Point class>>r: radiusNumber theta: thetaNumber
    ^self
    x: radiusNumber * thetaNumber cos
    y: radiusNumber * thetaNumber sin
```

SortedCollection class>>sortBlock: aBlock is a Constructor Method because it returns a SortedCollection that is ready to use. SortedCollection class>>new is also a Constructor Method because it returns a SortedCollection that is ready to use, too. It just has a default sort block.

Put Constructor Methods into a method protocol called "instance creation."

If the method takes parameters, you will need a Constructor Parameter Method (p. 25). Give your method an Intention Revealing Selector (p. 49) that describes the roles of the parameters, not their type. A Constructor Method that is used extensively may deserve a Shortcut Constructor Method (p. 26).
<figure><img src="image_3.png" /></figure>

# Constructor Parameter Method

A Constructor Method (p. 23) needs to pass parameters on to the new instance.
You need to initialize Common State (p. 80).

* How do you set instance variables from the parameters to a Constructor Method?

Once you have the parameters of a Constructor Method to the class, how
do you get them to the newly created instance?

The most flexible and consistent method is to use Setting Methods to set
all the variables. Thus, a Point would be initialized with two messages:

Point class>>x: xNumber y: yNumber
^self new
x: xNumber;
y: yNumber;
yourself

The problem I have run into with this approach is that Setting Methods can
become complex. I have had to add special logic to the Setting Methods to check
whether they are being sent during initialization; if so I just set the variable.

Remember the rule that says "Say things once and only once?" Special
casing a Setting Method for use during initialization is a violation of the first
part of that rule. You have two circumstances—state initialization during
instance creation and state change during computation—but only one method.
You have two things to say and you've only said one thing.

The Setting Method solution also has the drawback that if you want to
see the types of all the variables, you have to look at the Type Suggesting
Parameter Names in several methods. You'd like the reader to be able to look
at your code and quickly understand the types of the Instance Variables.

* Code a single method that sets all the variables. Preface its name with "set," then the names of the variables.

Using this pattern, the code above becomes:
```ksharp
Point class>>x: xNumber y: yNumber
    ^self new
        setX: xNumber
        y: yNumber
Point>>setX: xNumber y: yNumber
    x := xNumber.
    y := yNumber.
    ^self
```

Note the Interesting Return Value in `setX:y:`. It is there because the return value of the method will be used as the return value of the caller.

Put Constructor Parameters Methods in a method protocol called "private."

*If you are using Explicit Initialization (p. 83), now is a good time to invoke it, to communicate that initialization is part of instance creation.*

FORWARD

## Shortcut Constructor Method

*You have identified a pervasive Constructor Method (p. 23).*

BACK

* What is the external interface for creating a new object when a `Constructor Method` is too wordy?

The typical way you create a new object is to send a message to the class that creates a new instance for you; “Point x: width y: height”. This is good because it is very explicit about what object is being created. If you want to find out what happens as a result of this expression, you know just where to look.

There are two problems with this style of interface for object creation. The most important is that it is wordy. If `Point class>>x:y:` were the only interface for creating points, I dare say the Smalltalk source file would grow by a few percent. For very commonly used objects, you can create a more concise interface by sending a message to one of the arguments that then turns around and sends the longer form.
The second problem with an explicit class-based interface for object creation is that it can be misleading. There are times when differences in the classes of the arguments change the concrete class returned by the message. For example, different kinds of Collections might need different kinds of Streams.

The very conciseness of representing object creation as a message to one of the arguments is also its weakness. Such a message can easily be mistaken for built in language syntax (“@” is the classic example). It puts a burden on the programmer to remember the message. It cannot be easily looked up by looking at the instance creation methods of the class. However, the clarity or concision gains for a constructor method can be substantial.

* Represent object creation as a message to one of the arguments to the Constructor Method. Add no more than three of these Shortcut Constructor Methods per system you develop.

The classic example in Smalltalk is Point creation. The Constructor Method is:

```java
Point class>>x: xNumber y: yNumber
    ^self new
    setX: xNumber
    y: yNumber
```

The Shortcut Constructor Method is:

```java
Number>>@ aNumber
    ^Point
        x: self
        y: aNumber
```

Interestingly, the ParcPlace image has been moving away from using Point>>extent: and Point>>corner: as Shortcut Constructor Methods for Rectangles.

*Put Shortcut Constructor Methods in a method protocol called "converting."*

FORWARD
## Conversion

* How do you convert information from one object's format to another's?

Different clients may need the same information presented with different protocol. For example, one object may need to look at a Collection sorted, another with duplicates removed.

The simplest solution is to add all of the possible protocol needed to every object that may be asked of it. This might result in unnecessarily large public protocols with the resulting difficulty in publication and understanding. The same selector might need to mean different things to different clients, making this approach simply unworkable.

* Convert from one object to another rather than overwhelm any one object's protocol.

Some conversions are between similar objects, like changing a String of 8-bit ASCII characters to a String of 16-bit ISO characters. Some conversions are between different objects, like changing a String to a Date or a Number to a Pointer.

FORWARD

Conversions that return objects with similar responsibilities should use a Converter Method (p. 28). To convert to an object with different protocol use a Converter Constructor Method (p. 29).

BACK

## Converter Method

You are implementing a Conversion.

* How do you represent simple conversion of an object to another object with the same protocol but different format?

For a long time, it bothered me that there was a `String>>asDate` method. I couldn't quite put my finger on what it was that bothered me about it, though. Then, I walked into a project where they had taken the idea of conversion to extremes. Every domain object had twenty or thirty different conversion methods. Every time a new object was added, it had to have all twenty or thirty methods before it would start working with the rest of the system.
One problem with representing conversion as methods in the object to be converted is that there is no limit to the number of methods that can be added. The protocol grows and grows without limit. Another is that it ties the receiver, however tenuously, with a class of which it would otherwise be oblivious.

I avoid the protocol explosion problem by only representing conversions with a message to the object to be converted when:

* The source and destination of conversion share the same protocol.

* There is only one reasonable way to implement the conversion.

* Provide a method in the object to be converted that converts to the new object. Name the method by prepending "as" to the class of the object returned.

Here are some examples. Notice that the object returned has the same protocol as the receiver (Sets act like Collections, Floats act like Numbers).

Collection>>asSet

Number>>asFloat

Put Converter Methods in a method protocol called "private."

*Choose an Intention Revealing Selector (p. 49) for your conversion.*

FORWARD

## Converter Constructor Method

BACK

*You need to implement Conversion (p. 28) to a new kind of object.*

* How do you represent the conversion of an object to another with different protocol?

In many ways, the simplest way to communicate the presence of a conversion is a Converter Method. If I am explaining Date to you and you already know about Strings, it is tempting to say, "You can just convert a String to a Date by sending asDate to the String."
This solution risks cluttering common sources of conversion like Strings and Numbers with protocol that is irrelevant to their primary mission. The Visual Smalltalk implementation of String has 36 as... methods, half of which return objects with completely different protocols. I have seen applications where String has been “enhanced” with more than 100 Conversion Methods.

* Make a Constructor Method that takes the object to be converted as an argument.

For example, `Date class>>fromString:` is a Converter Constructor Method. It takes the String to be converted as an argument and returns a Date.

Put Converter Constructor Methods in a protocol called "instance creation."

**You need to choose an Intention Revealing Selector (p. 49) for the method.**

FORWARD

## Query Method

BACK

**A Composed Method (p. 21) has had to execute a boolean expression.**

* How do you represent testing a property of an object?

There are actually two decisions here. The first is deciding what to return from a method that tests a property. The second is what you should name the method.

Designing the protocol for a Query Method provides you with two alternatives. The first is to return one of two objects. For example, if you have a switch that can be either on or off, you could return either `#on` or `#off`.

```
Switch>>>makeOn
    status := #on
Switch>>>makeOff
    status := #off
Switch>>>status
    ^status
```
That leaves clients needing to know how Switch stores its status:

```kotlin
WallPlate>>update
    self switch status = #on ifTrue: [self light makeOn].
    self switch status = #off ifTrue: [self light makeOff]
```

A maintenance programmer who innocently decides to change the Symbols to `#On` and `#Off` will break the client.

It is far easier to maintain a relationship based solely on messages. Rather than status returning a Symbol, it is better for Switch to provide a single method that returns a Boolean; true if the Switch is on and false if the Switch is off.

Whether this is represented in the Switch as a variable holding a Boolean or a variable holding one of two Symbols is irrelevant to designing the protocol.

The naming question is a bit more sticky. The simplest name for a method that tests a property and returns a Boolean is just a simple name. In the example above, I'd be tempted to call the method `on`:

```kotlin
Switch>>on
    "Return true if the receiver is on, otherwise return false."
```

However, this leads to confusion. Does `on` mean "is it on?" or "make it on?"

* Provide a method that returns a Boolean. Name it by prefacing the property name with a form of "be"—is, was, will, etc.

Here are some examples from Smalltalk:

```
isNil
isControlWanted
isEmpty
```
If you use the logical inverse of a Query Method a lot, also provide an inverse method, like notNil or notEmpty. Actually, if you can find a positive way of saying the inverse, that's even better. On the other hand, isUseful and isFull don't make much sense.

Put Query Methods in a protocol called "testing."

## Comparing Method

* How do you order objects with respect to each other?

The comparison messages `<`, `<=`, `>`, `>=` are implemented mostly in Magnitude and its subclasses. They are used for all sorts of purposes—sorting, filtering, and checking for thresholds.

When you create new objects, you have the option of implementing comparison methods yourself. When I was a year or two into Smalltalk, I seem to remember implementing comparison methods any time I put a kind of object into a SortedCollection. As time went on, I used the sort block (see SortedCollection) more and more and implemented `<=` "less and less.

I still implement `<=` when there is one overwhelming way to order a new object. That way, those using it can take a collection containing those objects and sort them just by saying `asSortedCollection.`

Most uses of sorting in the user interface require more flexibility than can be provided by a single comparison order. Expect to use sort blocks with Temporarily Sorted Collection.

* Implement `<=` to return true if the receiver should be ordered before the argument.

Numbers are the obvious example of Comparing Methods. Characters and Strings also implement Comparing Methods.

If you had a Collection of timed Events, the Comparing Method could order them by time:

Event>><= anEvent
^self timestamp <= anEvent timestamp

Put Comparing Methods in a protocol called "comparing."
FORWARD

Ordering is often done in terms of *Simple Delegation* (p. 65) to the ordering of
*other objects*. For multiple orderings, use a *Temporarily Sorted Collection* (p. 155).

BACK

Reversing Method

*A Composed Method* (p. 21) may not read right because messages are going to too many receivers. You may have a *Cascade* (p. 183) that doesn't look quite right because several different objects need to receive messages.

* How do you code a smooth flow of messages?

Good code has a rhythm that makes it easy to understand. Code that breaks the rhythm is harder to read and understand.

Point>>printOn: aStream
x printOn: aStream.
aStream nextPutAll: ' @ '.
y printOn: aStream

Here we have messages going to three different objects. We want to read
this as a three part operation, but because the operations are on three differ-
ent objects it is hard to put the pieces together.

We can solve the problem by making sure that all messages go through a
single object. However, creating new selectors just for the fun of it is a bad
idea. Each selector in the system must justify its existence by solving a real
problem; encoding an important decision.

Adding a new method with a new selector to make code read more
smoothly is a good use of the selector namespace.

* Code a method on the parameter. Derive its name from the original message. Take the original receiver as a parameter to the new method. Implement the method by sending the original message to the original receiver.

By defining `Stream>>print:`, we can smooth out the above method:
```java
Stream>>print: anObject
anObject printOn: self
Point>>printOn: aStream
aStream
print: x;
nextPutAll: ' @ ';
print: y
```

This pattern seems to veer perilously close to the realm of pure aesthetics. However, I often find that the desire to use it is followed closely by the absolute need to use it. As soon as you have all the messages going to a single object, that object can easily vary without affecting any of the parameters.

Put Reversing Methods in a method protocol named after the message being reversed. For example, `Stream>>print:` is in the method protocol "printing."

## Method Object

*You have a method that does not simplify well with Composed Method (p. 21).*

* How do you code a method where many lines of code share many arguments and temporary variables?

The behavior at the center of a complex system is often complicated. That complexity is generally not recognized at first, so the behavior is represented as a single method. Gradually that method grows and grows, gaining more lines, more parameters, and more temporary variables, until it is a monstrous mess.

Far from improving communications, applying Composed Method to such a method only obscures the situation. Since all the parts of such a method generally need all the temporary variables and parameters, any piece of the method you break off requires six or eight parameters.

The solution is to create an object to represent an invocation of the method and use the shared namespace of instance variables in the object to
enable further simplification using Composed Method. However, these
objects have a very different flavor than most objects. Most objects are
nouns, these are verbs. Most objects are easily explainable to clients, these
are not because they have no analog in the real world. However, Method
Objects are worth their strange nature. Because they represent such an
important part of the behavior of the system, they often end up at the cen-
ter of the architecture.

* Create a class named after the method. Give it an instance vari-
able for the receiver of the original method, each argument, and
each temporary variable. Give it a Constructor Method that takes
the original receiver and the method arguments. Give it one
instance method, #compute, implemented by copying the body
of the original method. Replace the method with one that creates
an instance of the new class and sends it #compute.

This is the last pattern I added to this book. I wasn't going to include
it because I use it so seldom. Then it convinced an important client
to give me a big contract. I realized that when you need it, you
REALLY need it.

The code looked like this:

Obligation>>sendTask: aTask job: aJob
| notProcessed processed copied executed |
...150 lines of heavily commented code...

First, I tried Composed Method. Every time I tried to break off a
piece of the method, I realized I would have to send it both para-
meters and all four temps:

Obligation>>prepareTask: aTask job: aJob notProcessed:
notProcessedCollection processed: processedCollection
copied: copiedCollection executed: executedCollection

Not only was this ugly, but the resulting invocation didn't save any
lines of code (see Indented Control Flow, below). After fifteen min-
utes or so of struggle, I went back to the original method and used
Method Object. First I created the class:
Class: TaskSender
superclass: Object
instance variables: obligation task job notProcessed
processed copied executed

Notice that the name of the class is taken directly from the selector of the original method. Notice also that the original receiver, both arguments, and all four temps became instance variables.

The Constructor Method took the original receiver and both arguments as parameters:

TaskSender class>>obligation: anObligation task: aTask
job: aJob
^self new
setObligation: anObligation
task: aTask
job: aJob

Next I copied the code from the original method. The only change I made was textually replacing `aTask` with `task` and `aJob` with `job`, since parameters are named differently than instance variables. Oh, I also deleted the declaration of the temps, since they were now instance variables.

TaskSender>>compute
...150 lines of heavily commented code...

Then I changed the original method to create and invoke a TaskSender:
Obligation>>>sendTask: aTask job: aJob
 TaskSender
 obligation: self
 task: aTask
 job: aJob) compute

I tried out the method to make sure I hadn't broken anything. Since all I had been doing was moving text around, and I did it carefully, the revised method and its associated object worked the first time.

Now came the fun part. Since all the pieces of the method now
shared the same instance variables, I could use Composed
Method without having to pass any parameters. For example, the
piece of code that prepared a Task became a method called
#prepareTask.

The whole job took about two hours, but by the time I was done the
#compute method read like documentation; I had eliminated
three of the instance variables, the code as a whole was half of its
original length, and I'd found and fixed a bug in the original code.

Execute Around Method

* How do you represent pairs of actions that have to be taken together?

It is common for two messages to an object to have to be invoked in tandem. When a file is opened, it has to be closed. When a context is pushed, it has to be popped.

The obvious way to represent this is by publishing both methods as part
of the external protocol of the object. Clients need to explicitly invoke both, in
the right order, and make sure that if the first is called, the second is called as
well. This makes learning and using the object more difficult and leads to
many defects, such as file descriptor leaks.

* Code a method that takes a Block as an argument. Name the method by appending "During: aBlock" to the name of the first
method that needs to be invoked. In the body of the `Execute Around Method`, invoke the first method, evaluate the block, then invoke the second method.

I learned this pattern from `Cursor->>showWhile`:

```python
Cursor->>showWhile: aBlock
    | old |
    old := Cursor currentCursor.
    self show.
    aBlock value.
    old show
```

I use it lots of places. For example, I use it for making sure files get closed.

```python
File->>openDuring: aBlock
    self open.
    aBlock value.
    self close
```

You will often want to wrap the Block evaluation in an exception handler so you are assured the second message gets sent.

```python
File->>openDuring: aBlock
    self open.
    [aBlock value] ensure: [self close]
```
<figure><img src="image_4.png" /></figure>

Put Execute Around Methods in a method protocol named after the operations they encapsulate. For example, `File>>openDuring:` goes in the method protocol "opening."

*You need to give your method an Intention Revealing Selector (p. 49).*

Debug Printing Method

* How do you code the default printing method?

Smalltalk provides a single mechanism for turning objects into printable strings; `printOn:`. Strings are great because they fit nicely into generic interface components; lists display strings; tables display strings; text editors and input fields display strings.

Strings are also useful in generic programming tools, like the Inspector. As a programmer, you can often look at the string generated by an object and instantly diagnose a problem.

The two audiences for strings generated by objects, you and your client, are often in conflict. You want all the internal, structural details of your object laid out in one place so you don't have to go searching layers and layers of objects to find what you want. Your client assumes the object is working correctly and just wants to see externally relevant aspects of the object in the string.

VisualWorks has taken the valuable step of separating these two uses of object-to-string conversion. If you want a client-consumable string, you send `displayString.` If you want a programmer-consumable string, you send `printString.` For Smalltalks with a single message for printing, you need to choose which audience you will address.

* Override `printOn:` to provide information about an object's structure to the programmer.

Associations print so that programmers can read them:
Association>> printOn: aStream
aStream
  print: self key;
  nextPutAll: '->';
  print: self value

The saving grace of this pattern is that all the user interface builders have ways of parameterizing which message they will send to objects to get strings. Thus, when you create a list and send it some objects, you can also say, "...and send the message 'userString' to the objects to get strings."

Put Printing Methods in the method protocol "printing."

## Method Comment

BACK

*You have written a Composed Method (p. 21).*

* How do you comment methods?

Back in the days of assembly language programming, the distance between what you intended as a programmer and how the computer forced you to express that intention was enormous. Every few lines (sometimes on every line), you needed a little story to help you understand what the next few instructions really meant.

As programming languages progressed, moving the expression closer to what it really meant, the habit of commenting every few lines relaxed somewhat. Many commenting standards settled on a comment at the beginning of a procedure, explaining the purpose of the procedure and describing the arguments and return value.

I find no value in this kind of "template" comment. Someone recently asked me point blank, "What percentage of your methods have comments?" I answered, "Between 0 and 1 percent." Oh the uproar! As a sanity check, I asked a developer at one of my clients (where I had taught Smalltalk based on an earlier version of these patterns) what percentage of the methods of their 200 class system had comments. His answer, "between 0 and 1 percent." "Has that ever been a problem?" "No, never."
I have certainly heard extravagant claims of “self documenting” code over the years. Shoot, Forth was supposed to be self documenting. What is it about Smalltalk code written with these patterns that lets it communicate tactical information without any supporting prose?

The information in the “template” comment is captured in the code with various patterns; Intention Revealing Selector communicates what the method does; Type Suggesting Parameter Name says what the arguments are expected to be; and various types of method patterns suggest return types, like Query Method for methods returning Booleans.

There is another important topic to communicate about a procedure— how it handles the various cases it is coded for. In Smalltalk, important cases become objects in their own right (see Choosing Message below), so each method only computes a single case. The result is code that communicates all the necessary tactical information to the reader.

Regardless of how well the system as a whole is put together, the big picture cannot easily be read method by method. There has to be another way of teaching the reader about the system as a whole. I use literate programs, although class and package comments will do in a pinch. However, trying to shoehorn a description of the architecture into a method comment is unlikely to work well, if only because the reader most likely won’t stumble across it.

* *Communicate important information that is not obvious from the code in a comment at the beginning of the method.*

Here are examples of information that can be difficult to communicate solely through the code:

* **Method dependencies**—Sometimes one method must be invoked before another can execute correctly. A comment can warn the reader not to invoke one without the other. Sometimes you can use Composed Method or Execute Around Method to communicate the same information.

* **To-do**—I often write comments while I am prototyping to remind myself of some thought I don’t want to lose. “Look at using a Dictionary later for efficiency,” for example. When I reconsider the thought later, I delete the comment after choosing whether to follow it.

* **Reasons for change, particularly base class**—If you need to change something, the reason for the change is often not immediately apparent in the code. This often occurs when
changing a method supplied by a Smalltalk vendor. A comment helps a reader understand why you did what you did if you can't make the code say it.

Here is my favorite example of a useless comment:

```
(self flags bitAnd: 2r1000) = 1 "Am I visible?"
ifTrue: [...]
```

A quick look at Composed Method yields:

```
isVisible
^(self flags bitAnd: 2r1000) = 1
```

And the original code turns into:

```
self isVisible
ifTrue: [...]
```

I expect you to be skeptical of this pattern. Here's an experiment you can perform in the privacy of your own workstation. Write code with comments for every method. Go through your methods one by one and delete only those comments that duplicate exactly what the code says. If you can't delete a comment, see if you can refactor the code using these patterns (Composed Method and Intention Revealing Selector are especially useful) to communicate the same thing. I will be willing to bet that when you are done you will have almost no comments left.

One last example from client code:
Bin>>run

“Tell my station to process me.”

self station process: self

You can translate the code directly into the comment:

<table><thead><tr><td>English</td><td>Code</td></tr></thead><tbody><tr><td>Tell my station to process me</td><td>self station process: self</td></tr></tbody></table>

## Messages

Messages are the heartbeat of a Smalltalk program. Without messages, there would be no program. Deftly managing this heartbeat is the first skill of the expert Smalltalk programmer. When you learn to see your program in terms of patterns of messages and you learn what can be done to that stream of messages to solve problems, then you will be able to solve any problem you can imagine in Smalltalk.

Procedural languages explicitly make choices. When you code up a case statement, you say once and for all what all the possibilities are. In Smalltalk, you use messages to make choices for you. The extra added bonus is that the set of choices is not set in concrete. You can come along later and add new choices without affecting the existing choices just by defining a new class.

This section talks about the tactical ways you can use the message stream. It gives you a toolbox of techniques for solving problems by manipulating the communication between objects.

## Message

BACK

*A Composed Method (p. 21) needs work done.*

* How do you invoke computation?

In the earliest days of computing, this wasn't even a question. A program was one big routine that executed from start to finish.
As soon as programs got at all complicated, “program-as-a-routine” broke down. Conceptually, it was just too hard to manipulate the whole program at once. The limited resources of the era also came into play. When you had the same code duplicated in many places, you could save space by using a single copy of the code and invoking it everywhere you needed. The two factors, mental overload and memory overload, worked with each other. By giving the broken-out parts of the routine names, you saved space and you got a convenient tool for understanding the program a piece at a time.

Here things stood for a number of years. The client would invoke a subroutine. The subroutine would run. The client would regain control.

At the same time, there was a growing realization that a disciplined use of control structures was critical to the quality and cost of a program. If-then-else and case statements were invented to capture common ways to vary the execution of a program.

Simula brilliantly combined these two ideas. Conditional code says “execute this part of the routine or that part.” A subroutine call says “execute that code over there.” A message says “execute this routine over here or that routine over there, I don’t really care.”

Smalltalk went a step further by making messages the sole control structure in the system. All procedural control structures, conditionals and loops, are implemented in terms of messages. For the most part, explicit conditional logic plays a much smaller role in a Smalltalk program than a procedural program. Messages do most of the work.

* Send a named message and let the receiving object decide what to do with it.

Since everything in Smalltalk happens as a result of a message, it's tough to pick out one or two examples. #size is a message you can send to any object to get the number of elements (exclusive of named variables) it contains.

**Use Delegation (p. 64) to get another object to do work for you. A Choosing Message (p. 45) invokes one of several alternatives. A Decomposing Message (p. 47) documents intent and provides for later refinement. An Intention Revealing Message (p. 48) maps intention to implementation. Use Super (p. 59) to invoke behavior in a superclass.**
# Choosing Message

*You are using a Message* (p. 43).

* How do you execute one of several alternatives?

The long term health of a system is all about managing themes and variations. When you first write a program, you have a particular theme in mind. Setting the program free in the world inevitably suggests all sorts of variations on what you first thought was a simple task.

Procedural programs implement variations with conditional logic, either if-then-else or case statements. Two problems arise from such hard-coded logic. First, you cannot add a new variation without modifying the logic. This can be a ticklish operation, getting the new variation in without disturbing the existing variations. Second, such logic tends to propagate. You do not have to account for the variation in one place, you have to account for it in several. Adding a new variation means tickling all of the places where the logic lives.

Messages provide a disciplined way to handle theme-and-variation programming. Because the variations live in different objects, they have much less opportunity to interfere with each other than just putting the variations in different parts of the same routine. The client, the object invoking the variations, is also isolated from what variation is currently active.

Adding a new variation is as simple as adding a new object that provides the same set of messages the other variations provide and introducing it to the object that wants to invoke the variations.

Sometimes, even when beginners have several kinds of objects, they still resort to conditional logic:

```
responsible := (anEntry isKindOf: Film)
ifTrue: [anEntry producer]
ifFalse: [anEntry author]
```

Code like this can always be transformed into communicative, flexible code by using a Choosing Message:
Film>>responsible
^self producer
Entry>>responsible
^self author

Now you can write:

responsible := anEntry responsible

But you probably don't need the Explaining Temporary Variable any more.

* Send a message to one of several different kinds of objects, each of which executes one alternative.

When you begin a program, you won't be able to anticipate the variations. As your program matures, you will see explicit conditional logic creep in. When you can see the same logic repeated in several places, it is time to find a way to represent the alternatives as objects and invoke them with a choosing message.

Here are some examples of choosing messages:

<table><thead><tr><td>Message</td><td>Alternatives</td></tr></thead><tbody><tr><td>Number>>+ aNumber</td><td>Different code will be invoked depending on what kind of Number the receiver is. Floats add differently than Integers, which add differently than Fractions.</td></tr><tr><td>Object>>printOn: aStream</td><td>Every object has the opportunity to change how it is represented to the programmer as a String.</td></tr><tr><td>Collection>>includes:</td><td>Different collections implement this very differently. The default implementation takes time proportional to the size of the collection. Others take</td></tr></tbody></table>
constant time.

FORWARD

If a Choosing Message is sent to self, it is done so in anticipation of
future refinement by inheritance.

*Give the message an Intention Revealing Selector (p. 49). Look at the section on Methods (p. 20) for examples of the kind of code that can be invoked as variations.*

BACK

Decomposing Message

*You are using a Message (p. 43) to break a computation into parts.*

* How do you invoke parts of a computation?

A Choosing Message gets work done. It is the equivalent of a case statement in procedural languages. Depending on the circumstance, different code is invoked.

Another way messages are used is to break a computation down into
pieces. As you are writing the code, you don't think about possible variations.
A method is getting too big and you need to break it into parts so you can
understand it better. Alternatively, you may have noticed that two or more
methods have similar parts and you'd like to put the parts in a single method.

This is very similar to the way subroutines are used in procedural programming. You take a big routine and break it into pieces.

Smalltalk code reveals a much more aggressive attitude towards decomposing code than other languages. Most style guides say, "Keep the code for a routine on one page." Most good Smalltalk methods fit into a few lines, certainly less than ten and often three or four.

Partly this is possible because the abstractions Smalltalk provides are
higher level than what you find in most languages. You don't spend three or
four lines expressing iteration, you spend one word. Partly, it is possible
because Smalltalk's programming tools let you manage smaller pieces easily.

* Send several messages to "self."

The classic example of this from the original Smalltalk image was:
```kotlin
Controller->controlActivity
    self
        controllInitialize;
        controlLoop;
        controlTerminate
```

Later, these messages all became Choosing Messages because they were all overridden a hundred different ways.

**Use Composed Method (p. 21) to break the method into pieces. Give each method an Intention Revealing Selector (p. 49). Use Intention Revealing Messages (p. 48) to communicate intent separate from implementation.**

FORWARD

BACK

## Intention Revealing Message

**You are using a Message (p. 43) to invoke a computation. You may be hiding the use of Pluggable Behavior (p. 69).**

* How do you communicate your intent when the implementation is simple?

These messages have to be the most frustrating part of learning Smalltalk. You see a message like "highlight:" and you think, "This has to be something interesting." Instead, you see:

```kotlin
ParagraphEditor->highlight: aRectangle
    self reverse: aRectangle
```

What's going on?

Communication. Most importantly, one line methods are there to communicate. If I have the above method, the rest of the code in the object can be written in terms of highlighting. I want to highlight an area, so I send highlight. Makes sense.
I could mechanically replace all the invocations of `highlight` with invocations of `reverse`. The code would run the same. However, all the invoking code reveals the implementation—"I highlight by reversing a Rectangle."

The other advantage of code written to reveal intention and conceal implementation is that it is much easier to refine by inheritance. If I want a `ParagraphEditor` that highlights in color, I can make a subclass of `ParagraphEditor` and override a single method—`highlight`:

Intention Revealing Messages are the most extreme case of writing for readers instead of the computer. As far as the computer is concerned, both versions are fine. The one that separates intention (what you want done) from implementation (how it is done) communicates better to a person.

* Send a message to "self." Name the message so it communicates what is to be done rather than how it is to be done. Code a simple method for the message.

Here are some examples of Intention Revealing Messages and their implementation:

Collection>>empty
^self size = 0
Number>>reciprocal
^1 / self
Object>>= anObject
^self == anObject

FORWARD

Give the message an Intention Revealing Selector (p. 49).

## Intention Revealing Selector

You may be naming a method: a Constructor Method (p. 23), Conversion Method (p. 28), Converter Constructor Method (p. 26), or Execute Around Method (p. 37).
You may be naming a message: Decomposing Message (p. 47), Choosing Message (p. 45), or Intention Revealing Message (p. 48). You may be implementing Double Dispatch (p. 55).

BACK
* What do you name a method?

You have two options in naming methods. The first is to name the method after how it accomplishes its task. Thus, searching methods would be called:

Array>>linearSearchFor:

Set>>hashedSearchFor:

BTree>>treeSearchFor:

The most important argument against this style of naming is that it doesn't communicate well. If I have code that invokes three other objects, I have to read and understand three different pieces of implementation before I can understand the code.

Also, naming methods this way results in code that knows what kind of object it is dealing with. If I have code that works with an Array, I can't substitute a BTree or a Set.

The second option is to name a method after what it is supposed to accomplish and leave "how" to the various method bodies. This is hard work, especially when you only have a single implementation. Your mind is filled with how you are about to accomplish the task, so it's natural that the name follow "how." The effort of moving the names of method from "how" to "what" is worth it, both long term and short term. The resulting code will be easier to read and more flexible.

* Name methods after what they accomplish.

Applying this to the example above, we would name all of the messages `searchFor:.`

Collection>>searchFor:

Really, though, searching is a way of implementing a more general concept, inclusion. Trying to name the message after this more general "what" leads us to "includes:" as a selector.
Collection>>includes:

Here's a simple exercise that will help you generalize names of messages with a single implementation. Imagine a second, very different implementation. Then, ask yourself if you'd give that method the same name. If so, you've probably abstracted the name as much as you know how to at the moment.

Once you name a method, write its body using Composed Method (p. 21). Format the selector in the method with an Inline Message Pattern (p. 172). Add a Collecting Parameter (p. 75)if necessary to collect results.

FORWARD

## Dispatched Interpretation

* How can two objects cooperate when one wishes to conceal its representation?

Encoding is inevitable in programming. At some point you say, “Here is some information. How am I going to represent it?” This decision to encode information happens a hundred times a day.

Back in the days when data was separated from computation, and seldom the twain should meet, encoding decisions were critical. Any encoding decision you made was propagated to many different parts of the computation. If you got the encoding wrong, the cost of change was enormous. The longer it took to find the mistake, the more ridiculous the bill.

Objects change all this. How you distribute responsibility among objects is the critical decision, encoding is a distant second. For the most part, in well factored programs, only a single object is interested in a piece of information. That object directly references the information and privately performs all the needed encoding and decoding.

Sometimes, however, information in one object must influence the behavior of another. When the uses of the information are simple, or the possible choices based on the information limited, it is sufficient to send a message to the encoded object. Thus, the fact that boolean values are represented as instances of one of two classes, True and False, is hidden behind the message #ifTrue:ifFalse:.
True>>ifTrue: trueBlock ifFalse: falseBlock
^trueBlock value
False>>ifTrue: trueBlock ifFalse: falseBlock
^falseBlock value

We could encode boolean values some other way, and as long as we provided the same protocol, no client would be the wiser.

Sets interact with their elements like this. Regardless of how an object is represented, as long it can respond to #= and #hash, it can be put in a Set.

Sometimes, encoding decisions can be hidden behind intermediate objects. An ASCII String encoded as eight-bit bytes hides that fact by conversing with the outside world in terms of Characters:

String>>at: anInteger
^Character asciiValue: (self basicAt: anInteger)

When there are many different types of information to be encoded, and the behavior of clients changes based on the information, these simple strategies won't work. The problem is that you don't want each of a hundred clients to explicitly record in a case statement what all the types of information are.

For example, consider a graphical Shape represented by a sequence of line, curve, stroke, and fill commands. Regardless of how the Shape is represented internally, it can provide a message #commandAt: anInteger that returns a Symbol representing the command and #argumentsAt: anInteger that returns an array of arguments. We could use these messages to write a PostScriptShapePrinter that would convert a Shape to PostScript:
```pascal
PostScriptShapePrinter>>display: aShape
1 to: aShape size do:
    [each || command arguments |
     command := aShape commandAt: each.
     arguments := aShape argumentsAt: each.
     command = #line ifTrue:
        [self
          printPoint: (arguments at: 1);
          space;
          printPoint: (arguments at: 2);
          space;
          nextPutAll: 'line'].
     command = #curve...
    ...]
```

Every client that wanted to make decisions based on what commands were in a Shape would have to have the same case statement, violating the “once and only once” rule. We need a solution where the case statement is hidden inside of the encoded object.

* Have the client send a message to the encoded object. Pass a parameter to which the encoded object will send decoded messages.

The simplest example of this is `Collection>>do:`. No matter what kind of collection you have, you can always send it `#do:`. By passing a one argument Block (or any other object that responds to `#value:`), you are assured that the code will work, no matter whether the Collection is encoded as a linear list, an array, a hash table, or a balanced tree.

This is a simplified case of Dispatched Interpretation because there is only a single message coming back. For the most part, there will be several messages. For example, we can use this pattern with the Shape example. Rather than have a case statement for every command, we have a method in `PostScriptShapePrinter` for every command. For example:
```java
PostScriptShapePrinter>>lineFrom: fromPoint to: toPoint
self
    printPoint: fromPoint;
    space;
    printPoint: toPoint;
    space;
    nextPutAll: 'line'
```

Rather than Shapes providing `#commandAt:` and `#argumentsAt:`, they provide `#sendCommandAt:` an `Integer` to: an `Object`, where `#lineFrom:to:` is one of the messages that could be sent back. Then, the original display code could read:

```java
PostScriptShapePrinter>>display: aShape
1 to: aShape size do:
    [:each |
     aShape
        sendCommandAt: each
        to: self]
```

This could be further simplified by giving Shapes the responsibility to iterate over themselves:

```java
Shape>>sendCommandsTo: anObject
1 to: self size do:
    [:each |
     self
        sendCommandAt: each
        to: anObject]
```

With this, the original display code becomes:
PostScriptShapePrinter>>display: aShape
aShape sendCommandsTo: self

The name "dispatched interpretation" comes from the distribution of responsibility. The encoded object "dispatches" a message to the client. The client "interprets" the message. Thus, the Shape dispatches messages like `#lineFrom:to:` and `#curveFrom:mid:to:`. It's up to the clients to interpret the messages, with the PostScriptShapePrinter creating PostScript and the ShapeDisplayler displaying on the screen.

FORWARD

You will have to design a Mediating Protocol (p. 57) of messages to be sent back.
Computations where both objects have decoding to do need Double Dispatch (p. 55).

Double Dispatch

BACK

You have a Dispatched Interpretation (p. 51) between two families of objects. You
may be implementing a complex Equality Method (p. 124).

* How can you code a computation that has many cases, the cross product of two families of classes?

This pattern helps manage another of Smalltalk's engineering compromises—method dispatch. When you send a message to an object, and you include an argument, only the class of the receiver is taken into account when looking for a corresponding method. Ninety-nine percent of the time this causes you no trouble. There are a few cases, though, where the logic to be invoked really depends not just on the class of the receiver, but the class of one of the arguments as well. In fact, which object is the receiver and which is the argument may be entirely arbitrary.

<table><thead><tr><th></th><th colspan="2">Argument</th></tr><tr><th></th><th>C</th><th>D</th></tr></thead><tbody><tr><th>Receiver</th><td>A Method 1</td><td>Method 2</td></tr><tr><th></th><td>B Method 3</td><td>Method 4</td></tr></tbody></table>

One classic example where this relationship exists is arithmetic. When you add an Integer to an Integer you want one method, when you add a Float
to a `Float` you want another, an `Integer` and a `Float` another, and a `Float` and an `Integer` another.

The procedural solution to this situation is to have a big case statement. Like all explicit case logic, this is difficult to maintain and extend, even though it has the advantage of putting all the program logic in one place.

The solution is adding a layer of messages that get both objects involved in the computation. As with Self Delegation, this causes you to create more messages, but the additional complexity is worth it.

* Send a message to the argument. Append the class name of the receiver to the selector. Pass the receiver as an argument.

The arithmetic example can be coded as follows. `Integer` and `Float` both `Double Dispatch` to the argument:

```java
Integer>>+ aNumber
    ^aNumber addInteger: self
Float>>+ aNumber
    ^aNumber addFloat: self
```

`Integer` and `Float` both have to implement both flavors of addition. The `Integer-Integer` and `Float-Float` cases are handled as primitives.

```java
Integer>>addInteger: anInteger
    <primitive: 1>
Float>>addFloat: aFloat
    <primitive: 2>
```

When you have one number of each class, you have to convert the `Integer` to a `Float` and start over:
Integer>>addFloat: aFloat
^self asFloat addFloat: aFloat
Float>>addInteger: anInteger
^self addFloat: anInteger asFloat

In the worst case, Double Dispatch can lead to N × M methods, where N is the number of classes of the original receiver and M is the number of classes of the original argument. Practically speaking, the receiver classes are usually related by inheritance, as are the argument classes, so many common implementations can be factored out.

A reviewer suggested another good use for Double Dispatch—implementing drag-and-drop operations. You want to execute different code depending on what kind of object is being dragged over what kind of receiver. The simplest and most flexible way to implement this is with Double Dispatch.

**Create a Mediating Protocol (p. 57) with which the objects communicate. Type Suggesting Parameter Names (p. 174) are important for keeping track of how much you know at any stage of the process.**

FORWARD

BACK

# Mediating Protocol

*You are implementing Dispatched Interpretation (p. 51) or Double Dispatch (p. 55).*

* How do you code the interaction between two objects that need to remain independent?

For the most part, when you write a program that involves the cooperation of two objects, you create methods as needed. The dialog grows organically. When you finish, the two objects work together, but you don't necessarily have a strong sense of all the messages flowing back and forth.
Most of the time, this sort of ad hoc interaction doesn't cost you much. The changes you need to make involve changing one object or the other and occasionally adding to the messages going between them.

You need to make the protocol between the objects more visible when you decide to replace one or the other of them. The important question for you then becomes, "Exactly what messages flow between these two objects?"

When you find the answer, a list of message selectors, you will probably have some work to do. First, you need to look at the words in the selectors and see if they form a coherent system. Protocols that grow piecemeal tend to accumulate little inconsistencies. Sometimes, you will not have consistent opposites in the messages, as in `#show` being the opposite of `#makeInvisible`. Sometimes, you will not have consistently made selectors plural, as in `#addEmployees`: being the opposite of `#removeAllEmployees`:

Because you are finding it necessary to replace one of the objects in the interaction, it is likely that others will have to create other replacements in the future. If the words in the protocol are consistent and clearly presented, they will be able to quickly create their replacements, using your code as examples.

* Refine the protocol between the objects so the words used are consistent.

In VisualWorks, `#value` and `#value:` is the Mediating Protocol between the user interface components and the application model.

In the Double Dispatch example, the Mediating Protocol is `#addFloat:` and `#addInteger:`. Of course, if we finished mixed mode arithmetic the protocol would be much larger.

I worked with Smalltalk/V for the Macintosh for a couple of years. One of the exercises I tried was replacing the Smalltalk-programmed TextPane with a wrapper around the native Macintosh text editor. Smalltalk/V used a Model/Pane/Dispatcher-based user interface framework, so there was a TextDispatcher associated with the pane. Its purpose was to interpret user input and pass along meaningful messages to the pane.

For a while, I tried just sticking the new pane in and debugging my way to health. It didn't take long before I realized there was no way that was going to work. There was just too much going on between the TextPane and the TextDispatcher. So I sat down with the code and recorded every message that went from the pane to the dis-
patcher and vice versa. In the end, I had only a handful of mes-
sages going from the pane to the dispatcher, but the dispatcher
was sending the pane 56 different messages.

With this Mediating Protocol of 56 messages in place, I could sit
down and design the new pane to support those messages. When
I got them all implemented, I knew I was done.

Put all the methods to support a Mediating Protocol in a single
method protocol, so they are easy to find and duplicate.

*Examine each message to make sure it has an Intention Revealing Selector (p. 49).*

BACK

BACK

Super

*You are sending a Message (p. 43).*

* How can you invoke superclass behavior?

An object executes in a rich context of state and behavior, created by com-
posing together the contexts of its class and all of its class' superclasses. Most
of the time, code in the class can be written as if the entire universe of meth-
ods it has available is flat. That is, take the union of all the methods up the
superclass chain and that's what you have to work with.

Working this way has many advantages. It minimizes any given method's
reliance on inheritance structure. If a method invokes another method on self,
as long as that method is implemented somewhere in the chain, the invoking
method is happy. This gives you great freedom to refactor code without having
to make massive changes to methods that assume the location of some method.

There are important exceptions to this model. In particular, inheritance
makes it possible to override a method in a superclass. What if the subclass
method wants some aspect of the superclass method? Good style boils down to
one rule: say things once and only once. If the subclass method were to contain
a copy of the code from the superclass method, the result would no longer be
easy to maintain. We would have to remember to update both or (potentially)
many copies at once. How can we resolve the tension between the need to over-
ride, the need to retain the illusion of a flat space of methods, and the need to
factor code completely?

* Invoke code in a superclass explicitly by sending a message to "super" instead of "self." The method corresponding to the message will be found in the superclass of the class implementing the
sending method.

One example of where you want to extend superclass behavior is initialization, where not only does the state defined by the superclass need to be initialized, but also the state defined by the subclass.

Always check code using "super" carefully. Change "super" to "self" if doing so does not change how the code executes. One of the most annoying bugs I've ever tried to track down involved a use of super that didn't do anything at the time I wrote it and invoked a different selector than the one for the currently executing method. I later overrode that method in the subclass and spent half a day trying to figure out why it wasn't being invoked. My brain had overlooked the fact that the receiver was "super" instead of "self," and I proceeded on that assumption for several frustrating hours.

**Extending Super (p. 60) adds behavior to the superclass. Modifying Super (p. 62) changes the superclass' behavior.**

FORWARD

BACK

## Extending Super

You are using Super (p. 59).

* How do you add to a superclass' implementation of a method?

Any use of super reduces the flexibility of the resulting code. You now have a method that assumes not just that somewhere there is an implementation of a particular method, but that the implementation has to exist in the superclass chain above the class that contains the method. This assumption is seldom a big problem, but you should be aware of the tradeoff you are making.

If you are avoiding duplication of code by using super, the tradeoff is quite reasonable. For instance, if a superclass has a method that initializes some instance variables, and your class wants to initialize the variables it has introduced, super is the right solution. Rather than have code like:
Class: Super
superclass: Object
instance variables: a

Super class>>new
^self basicNew initialize

Super>>initialize
a := self defaultA

and rather than extending initialization in a subclass like this:

Class: Sub
superclass: Super
instance variables: b

Sub class>>new
^self basicNew
initialize;
initializeB

Sub>>initializeB
b := self defaultB

using super you can implement both initializations explicitly:

Sub>>initialize
super initialize.
b := self defaultB
and not have Sub override "new" at all. The result is a more direct expression of the intent of the code. Make sure Supers are initialized when they are created and extend the meaning of initialization in Sub.

* Override the method and send a message to "super" in the overriding method.

Another example of Extending Super is display. If you have a subclass of a Figure that needs to display just like the superclass, but with a border, you could implement it like this:

```java
BorderedFigure>>display
super display.
self displayBorder
```

## Modifying Super

BACK

You are using Super (p. 59).

* How do you change part of the behavior of a superclass' method without modifying it?

This problem introduces a tighter coupling between subclass and superclass than Extending Super. Not only are we assuming that a superclass implements the method we are modifying, we are assuming that the superclass is doing something we need to change.

Often, situations like this can best be addressed by refactoring methods with Composed Method so you can use pure overriding. For example, the following initialization code could be modified by using super.
Class: IntegerAdder
superclass: Object
instance variables: sum count

IntegerAdder>>initialize
sum := 0.
count := 0

Class: FloatAdder
superclass: IntegerAdder
instance variables:

FloatAdder>>initialize
super initialize.
sum := 0.0

A better solution is to recognize that IntegerAdder>>initialize is actually doing four things: representing and assigning the default values for each of two variables. Refactoring with Composed Method yields:

IntegerAdder>>initialize
sum := self defaultSum.
count := self defaultCount

IntegerAdder>>defaultSum
^0

IntegerAdder>>defaultCount
^0

FloatAdder>>defaultSum
^0.0

However, sometimes you have to work with superclasses that are not completely factored (i.e. the superclass does not implement #defaultSum). You are faced with the choice of either copying code or using super and accepting the costs of tighter subclass/superclass coupling. Most of the time, the addi-
tional coupling will not prove to be a problem. Communicate your desired
changes with the owner of the superclass. In the meantime:

* Override the method and invoke "super," then execute the code to modify the results.

Another example from the display realm is if you have a subclass
whose color is different from the superclass'.

SuperFigure>>initialize
    color := Color white.
    size := 0@0
SubFigure>>initialize
    super initialize.
    color := Color beige

FORWARD

Again, the better solution would be to use a Default Value Method (p. 86) to represent the default color, and then override just that method.

BACK

Delegation

A Composed Method (p. 21) needs work done by another object. A Message (p. 43) invokes computation in another object.

* How does an object share implementation without inheritance?

Inheritance is the primary built-in mechanism for sharing implementa-
tion in Smalltalk. However, inheritance in Smalltalk is limited to a single
superclass. What if you want to implement a new object like A but also like B?
Also, inheritance carries with it potentially staggering long-term costs. Code
in subclasses isn't just written in Smalltalk. It is written in the context of
every variable and method in every superclass. In deep, rich hierarchies, you
may have to read and understand many superclasses before you can under-
stand even the simplest method in a subclass.

Factored Superclass explains how to make effective use of inheritance at
minimal development cost. You will encounter situations where you will rec-
ognize common implementation, but where Factored Superclass is not appro-
priate. How can you respond?

* Pass part of its work on to another object.

For example, since many objects need to display, all objects in the
system delegate to a brush-like object (Pen in Visual Smalltalk,
GraphicsContext in VisualAge and VisualWorks) for display. That
way, all the detailed display code can be concentrated in a single
class and the rest of the system can have a simplified view of dis-
playing.

**Use Simple Delegation (p. 65) when the delegate need know nothing about the original object. Use Self Delegation (p. 67) when the identity of the original object or some of its state is needed by the delegate.**

FORWARD

Simple Delegation

BACK

**You need Delegation (p. 64) to a self-contained object. You may be implementing one of the following methods: Collection Accessor Method (p. 96), Equality Method (p. 124), or Hashing Method (p. 126).**

* How do you invoke a disinterested delegate?

When you use delegation, there are two main issues that help clarify
what flavor of delegation you need. First, is the identity of the delegating
object important? This might be true if a client object passes itself along,
expecting to be notified of some part of the work actually done by the delegate.
The delegate doesn't want to inform the client of its existence so it needs
access to the delegating object. Second, is the state of the delegating object
important to the delegate? Delegates are often simple, even state-less objects,
in order to be as widely useful as possible. If so, the delegate is likely to require
state from the delegating object to accomplish its job.

There are many cases of delegation where the answer to these two ques-
tions is “no.” The delegate has no reason to need the identity of the delegating
object. The delegate is self-contained enough to accomplish its job without
additional state.

* Delegate messages unchanged.
The typical example of this is an object that acts like a Collection (at least a little) but has lots of other protocol. Rather than waste inheritance by subclassing one of the collection classes, your object refers to a Collection. From a client's perspective, though, you respond to protocol like `do:` or `at:put:`.

The Collection doesn't care who invoked it. No state from the delegating object is required. The identity of the delegating object is irrelevant.

Here's an example—a Vector that holds only Numbers. We could implement it by subclassing `Collection`, but there are likely to be many messages that don't make sense for a Vector. Rather than subclass `Collection` and block out scads of messages, we can subclass object and delegate only those messages we want.

### Vector
* superclass: `Object`
* instance variables: `elements`

We create a Vector with a given number of elements:

```java
Vector class>>new: anInteger
    ^self new setElements: (Array new: anInteger)
Vector>>setElements: aCollection
    elements := aCollection
```

We'll ignore the arithmetic nature of Vectors and focus on how it delegates. Sometimes, clients want to treat a Vector as a Collection of Numbers. When someone iterates over a Vector, it delegates to its `elements` instance variable:

### Vector>>do: aBlock
* elements do: aBlock

This is an example of Simple Delegation. You can imagine implementing `at:`, `at:put:`, `size`, etc. the same way.
<figure><img src="image_5.png" /></figure>

# Self Delegation

You are using Delegation (p. 64).

* How do you implement delegation to an object that needs reference to the delegating object?

The issues are the same for Self Delegation as for Simple Delegation. Do you need the identity of the original delegating object? Do you need state from the delegating object?

If the answer to either of these questions is “yes,” Simple Delegation won’t work. Somehow, the delegate needs access to the delegating object.

One way to give the delegate access is to include a reference from the delegate back to the delegating object. This approach has a number of drawbacks. The backwards reference introduces additional programming complexity. Every time the delegate changes, the reference in the old delegate has to be destroyed and the reference in the new delegate set. More importantly, each delegate can only be used by one delegating object at a time. If creating multiple copies of the delegate is expensive or impossible, this simply won’t work.

The other approach, the one suggested here, is to pass the delegating object along as an additional parameter. This introduces a variant of the original method, which isn’t great, but the additional flexibility of this approach is worth the cost.

* Pass along the delegating object (i.e. "self") in an additional parameter called "for:"

The Digitalk Visual Smalltalk 3.0 image has an excellent example of Self Delegation. The implementation of hashed collections, like Dictionaries, is divided into two parts. The first is the Dictionary, the second is a HashTable. There are variants of HashTables that are efficient in different circumstances. The same collection might delegate to different HashTables at different times, depending on its

<figure><img src="image_6.png" /></figure>
characteristics (how big, how full, etc.)

The hash value of an object is implemented differently for different kinds of Collections. Dictionaries compute hash by sending "hash." IdentityDictionaries compute it by sending "basicHash." This is implemented using Self Delegation. When the Collection sends a message to the HashTable to add an element, it passes itself along:

```
Dictionary>>at: keyObject put: valueObject
  self hashTable
    at: keyObject
    put: valueObject
    for: self
```

The HashTable computes the hash value by sending back a message to the Collection:

```
HashTable>>at: keyObject put: valueObject for: aCollection
  | hash |
  hash := aCollection hashOf: keyObject.
...
```

Dictionaries and IdentityDictionaries implement this message differently:

```
Dictionary>>hashOf: anObject
  ^anObject hash
IdentityDictionary>>hashOf: anObject
  ^anObject basicHash
```

Self Delegation allows the hierarchy of hashed Collections to be
If the delegate needs different logic depending on who is delegating, use Double Dispatch (p. 55).

## Pluggable Behavior

* How do you parameterize the behavior of an object?

The conventional model of objects is that different instances of the same class have different state and the same behavior. Every Point can have different values for x and y, but they all use the same logic to compute `translatedBy:`. When you want different logic, you use a different class.

Using classes to specify behavior is simple. The programming tools are set up to help readers understand the behavior of your system statically, without necessarily having to run the code.

This model works for 90 percent of the objects you will create. Creating classes comes at a cost, though, and sometimes different classes don't effectively communicate how you think about a problem.

Classes are an opportunity. Each one will be useful to instantiate and/or specialize. However, each class you create places a burden on you, as the writer, to communicate its purpose and implementation to future readers. A system with hundreds or thousands of classes will intimidate a reader. Managing a namespace across many classes is expensive. You would like to invoke the costs of a new class only when there is a reasonable payoff. A large family of classes with only a single method each is unlikely to be valuable.

The other problem with specializing behavior only through classes is that classes are not flexible. Once you have created an object of a certain class, you cannot change that object's class without completely ruining the ability to understand the code statically. Only watching carefully while single stepping will give you insight into how such code runs. Smalltalk's single inheritance also does not allow specialization along several different axes at the same time.

If you are going to use Pluggable Behavior, here are the issues you need to consider:

* How much flexibility do you need?

* How many methods will need to vary dynamically?
* How hard is it to follow the code?

* Will clients need to specify the behavior to be plugged, or can it be hidden within the plugged object?

How can you specify different logic in different instances when creating lots of little classes or changing classes at run time won't work?

* Add a variable that will be used to trigger different behavior.

Typical examples of pluggable behavior are objects that have to interface with a variety of other objects, like user interface components that have to display the contents of many different objects. Using Pluggable Behavior is a much better solution than creating a hundred different subclasses, each differing from each other in only one or two methods.

For simple behavior changes, use a Pluggable Selector (p. 70). A Pluggable Block (p. 73) gives you more flexibility. Hide the implementation of pluggability behind an Intention Revealing Message (p. 48).

<figure><img src="image_7.png" /></figure>

BACK

## Pluggable Selector

You need simple Pluggable Behavior (p. 69).

* How do you code simple instance specific behavior?

The simplest way to implement Pluggable Behavior is to store a selector to be performed.

Let's say we have implemented a ListPane. We create a method that takes one of the elements of the collection to be displayed and returns a String:

ListPane>>printElement: anObject
^anObject printString

After awhile, we notice that there are many subclasses of ListPane that only override this one method:
DollarListPane>>printElement: anObject

^anObject asDollarFormatString

DescriptionListPane>>printElement: anObject

^anObject description

It hardly seems worth the cost of all these subclasses if all they are going
to do is override one method. A simpler solution is to make ListPane itself a
little more flexible, so different instances send different messages to their ele-
ments. We add a variable called "printMessage" and modify #printElement:

ListPane>>printElement: anObject

^anObject perform: printMessage

To preserve the previous behavior, we would have to initialize the
printMessage:

ListPane>>initialize

printMessage := #printString

Pluggable Selector meets the Pluggable Behavior criteria as follows:

Readability—Pluggable Selector is harder to follow than simple class-
based behavior. By looking at an object with an inspector, you can tell how it
will behave. You don't necessarily have to single step through the code.

Flexibility—The methods for the Pluggable Selectors must be imple-
mented in the receiving object. The set of possible methods to be invoked
should change at the same rate as the rest of the object.

Extent—Pluggable selectors should be used no more than twice per
object. Any more than that and you risk obscuring the intent of the program.
Use State Object if you need more dimensions of variability.
* Add a variable that contains a selector to be performed. Append "Message" to the Role Suggesting Instance Variable Name. Create a Composed Method that simply performs the selector.

Pluggable Selector is also useful for a simple kind of constraint. For example, if you wanted to locate one visual component relative to some part of another, we could use Pluggable Selector to create a RelativePoint:

Class: RelativePoint
superclass: Object
instance variables: figure locationMessage

Here is the Constructor Method:

RelativePoint class>>centered: aFigure
^self new
  setFigure: aFigure
  message: #center
RelativePoint>>setFigure: aFigure message: aSymbol
figure := aFigure.
locationMessage := aSymbol

To use a RelativePoint, you send it messages like #x and #y, just like a regular Point.

RelativePoint>>asPoint
^figure perform: locationMessage
RelativePoint>>x
^self asPoint x
Once you have this, you can go crazy duplicating all the necessary Point protocol, re-engineering for performance, etc. As an example of Pluggable Selector, however, the interesting observation is that you don't have to make a subclass for CenteredRelativePoint, TopLeftRelativePoint, etc.; you can capture the variability in a single selector.

# Pluggable Block

<figure><img src="image_8.png" /></figure>

> You need complex Pluggable Behavior (p. 69) that is not implemented by the plugged object.

* How do you code complex Pluggable Behavior that is not quite worth its own class?

Pluggable Selector works when the behavior to be invoked lives within the plugged object. Sometimes, though, the behavior can't live within the plugged object either because it is complex and not related to the plugged object's other responsibilities, because it is already implemented in another object not easily accessible to the plugged object, or because the range of behavior to be plugged was not known when the object was created.

The common solution in this case, particularly when the behavior is already implemented, is to plug in a Block to be evaluated rather than a selector to be performed. The block can be created anywhere, can access objects otherwise inaccessible to the plugged object through the use of a Block Closure, and can involve arbitrary amounts of logic.

Blocks used in such a general way come at enormous cost. You can never statically analyze the code to understand the flow of control. Even inspecting the plugged object is unlikely to unearth its secrets. Only by single stepping through the invocation of the block will the reader understand what is going on.

Blocks are also more difficult to store on external media than Symbols. Some Object Streams and object databases cannot store and retrieve Blocks.

* Add an instance variable to store a Block. Append "Block" to the Role Suggesting Instance Variable Name. Create a Composed Method to evaluate the Block to invoke the Pluggable Behavior.

The VisualWorks object PluggableAdaptor is a good example of a Pluggable Block. All the objects in the ValueModel family, of which
PluggableAdaptor is one, provide the protocol #value and #value:.
PluggableAdaptor implements these messages with a PluggableBlock.
Here is a simplified implementation:

Class: PluggableAdaptor
superclass: ValueModel
instance variables: getBlock setBlock

The Constructor Method sets the blocks:

PluggableAdaptor class>>getBlock: getBlock setBlock:
setBlock
^self new
setGetBlock: getBlock
setBlock: setBlock

Notice that the Constructor Parameter Method has to use a variant
of Type Suggesting Parameter Name because the obvious para-
meter names are already used for instance variable names.

PluggableAdaptor>>setGetBlock: gBlock setBlock: sBlock
getBlock := gBlock.
setBlock := sBlock

We can implement #value and #value: by invoking the Pluggable
Blocks.
PluggableAdaptor>>value
^getBlock value
PluggableAdaptor>>value: anObject
putBlock value: anObject

Now we can connect any object that expects #value and #value:
to any other object:

Car>>speedAdaptor
^PluggableAdaptor
  getBlock: [self speed]
  putBlock: [:newSpeed | self speed: newSpeed]

## Collecting Parameter

*You have written an Intention Revealing Selector (p. 49).*

* How do you return a collection that is the collaborative result of several methods?

One of the downsides of Composed Method is that it occasionally creates problems because of linkages between the small methods. A state that would have been stored in a temporary variable now has to be shared between methods.

The simplest solution to this problem is to leave all the code in a single method and use temporary variables to communicate between the parts of the method. All the benefits you expect from Composed Method vanish if you take this approach. The code is less revealing, more difficult to reuse and refine, and harder to modify.
Another solution is to add an instance variable to the object that is shared only between the methods. This variable is very different than the other variables in the object. It is only valid while the methods are executing, not for the lifetime of the object. Instance variables should exist to communicate and store only state that must go together.

We can solve the problem by adding an additional parameter that is passed to all the methods. I hesitate to add layers of methods like this, except when they do useful work. In this case, because the other solutions aren't valid, this is the right solution.

* Add a parameter that collects their results to all of the submethods.

Here's an example. The following code extracts all the married men and unmarried women from a collection of people:

```
marriedMenAndUnmarriedWomen
  | result |
result := OrderedCollection new.
self people do: [:each | each isMarried & each isMan
  ifTrue: [result add: each]].
self people do: [:each | each isUnmarried & each
  isWoman ifTrue: [result add: each]].
^result
```

Using Composed Method, we put each iteration into its own method:

```
marriedMen
  | result |
result := OrderedCollection new.
self people do: [:each | each isMarried & each isMan
  ifTrue: [result add: each]].
^result

unmarriedWomen
  | result |
result := OrderedCollection new.
self people do: [:each | each isUnmarried & each
  isWoman ifTrue: [result add: each]].
^result
```
Now the question is how to compose the two methods. For an
example this simple, I would probably use Concatenation to write:

```
marriedMenAndUnmarriedWomen
    ^self marriedMen, self unmarriedWomen
```

but that doesn't demonstrate this pattern very well. If several layers
of methods, or several objects, are involved, it is more clear to mod-
ify the submethods. Instead of returning a Collection, each adds its
objects to a Collection. The code then becomes:

```
marriedMenAndUnmarriedWomen
    | result |
    result := OrderedCollection new.
    self addMarriedMenTo: result.
    self addUnmarriedWomenTo: result.
    ^result
addMarriedMenTo: aCollection
    self people do: [:each | each isMarried & each isMan
        ifTrue: [aCollection add: each]]
addUnmarriedWomenTo: aCollection
    self people do: [:each | each isUnmarried & each
        isWoman ifTrue: [aCollection add: each]]
```

This code contains fewer lines and is more direct than the original.
(If this were production code, I would probably continue factoring
via Composed Method to concentrate the similarities between
addMarriedMenTo: and addUnmarriedWomenTo:.)

In general, use an OrderedCollection (p. 116) as the Collecting Parameter. You
may use a Concatenating Stream (p. 165) as the Collecting Parameter if the
objects to be collected are bytes or Characters. Use a Set (p. 119) if you want to
avoid duplicates.
*This page intentionally left blank*
4

State

Sure, how you specify behavior is most important in coding Smalltalk objects, but you still won't get anywhere without state. Before you start a computation, something has to record what the problem is. While you are computing, you often need to store intermediate results. When you finish a computation, you have to remember the answer.

Most state-related decisions have more to do with modeling and less with coding, so the patterns here don't tell anything like the whole story. However, the tactical decisions you make about representation will have an important impact on how well your code communicates with others.

This section talks about two kinds of state: instance variables and temporary variables. Of the two, temporary variables are covered much more thoroughly because they are a complete artifact of coding, living only as long as a method is computing. Instance variables also have an important role to play in coding, however, so their role in computing, and even some of their roles in modeling, is covered here.
## Instance Variables

I wrote the section on Temporary Variables before I wrote this section. I was pleased with how the section on temps came out. I expected this section to turn out to be the same sort of cut-and-dry, "Here's how it goes" list of patterns. It didn't.

The problem is that temporary variables really are all about coding. They are a tactical solution to a tactical problem. Thus, they fit very well in the scope of this book.

Most uses of instance variables are not tactical. Along with the distribution of computational responsibility, the choice of how to represent a model is at the core of modeling. The decision to create an instance variable usually comes from a much different mind-set and in a different context than the decision to create a temp.

I leave this section here because there are still important coding reasons to create instance variables, and there are some practical, tactical techniques to be learned when using instance variables.

## Common State

* How do you represent state, different values for which will exist in all instances of a class?

In the dawn of computing time, state was all there was. What is a box of punched cards but a bunch of state made manifest? Unit record equipment existed to re-order and transform the state, but all the transformations were hard-coded (like with wires and pulleys and gears) into the machines. State was king.

The first thing electronic computing did was make state virtual. No longer did it only exist in physical form, that physical form was turned into electrons so it could be more easily and quickly manipulated. The manipulations were still physically manifested in the form of patch cords, but they were getting easier to change.

The stored program computer changed all this. Now, the manipulations and the state were on par. They were both virtual parts of the same machine, stored as charges that could easily be changed.

Because of the extreme resource limitations of those early machines, the unification of program and state became complete. You could encode a program in fewer bytes if you were willing to treat it like data sometimes—
changing the program as circumstances changed. Of course, you could never
hope to just read program source and understand what was happening, you
had to watch the program in action under lots of different conditions before
you understood it.

Once we had enough memory that we no longer needed to commit atroc-
ities in the name of space efficiency, state still bit us on the backside. Huge
programs were written where many many functions used many many differ-
ent bits of state. No part of the state could be changed without changing many
parts of the program.

The enormous cost of such programs led to a backlash. Programs as state
were bad. State must be bad, too. This led to the development of functional
programming, where there is no state, only programs.

In spite of their conceptual and mathematical elegance, functional pro-
gramming languages never caught on for commercial software. The problem is
that programmers think and model in terms of state. State is a pretty darn
good way to think about the world.

Objects represent a middle ground. State is good, but only when properly managed. It is manageable if it is chopped into little pieces, some alike and some different. Similarly, related programs are chopped into little pieces, some alike, some different. That way, changing part of the representation of the state of a program need lead to only a few, localized changes in the program.

* Declare an instance variable in the class.

A Cartesian Point has instance variables to hold its horizontal and
vertical offsets. A Point in polar coordinates has instance variables
to hold its radius and angular offset. A House has an instance vari-
able to hold a collection of all of its rooms.

Instance variables have a very important communicative role to
play. They say once and for all and out in the open, "Here's what
I'm modeling with this object." A set of objects reveals a lot that
was in the mind of the original programmer just by what the
instance variables are and what they are named.

Be sure to declare instance variables in order of importance in the
class definition.

Name the variable using Role Suggesting Instance Variable Name (p. 110). Initialize the instance variable either with Lazy Initialization (p. 85), Explicit Initialization (p. 83), or a Constructor Parameter Method (p. 25). You need to choose whether to use the variable with Direct Variable Access (p. 89) or Indirect Variable Access (p. 91).
## Variable State

* How do you represent state whose presence varies from instance to instance?

Warning! This is not a pattern you should use often, if ever. It is here because you will see code written with it and you will have to understand what is going on.

This pattern is here for all the LISP programmers who come to Smalltalk. Some LISP cultures value flexibility over all else. Their objects tend to have no fixed parts. A Point might have an x, it might have a y, it might have a color, who knows?

The symptom of code like this is that classes declare a single instance variable that holds a Dictionary mapping of Strings or Symbols (the names of variables) to Objects. Some of the values of the Dictionary might be Numbers, others Collections, others Strings. Moreover, if you look at several instances of this class, all of their Dictionaries have the same keys.

The problem with code like this is that you can't read it and understand what is going on. The programming tools don't support this style of programming well. There is no equivalent of "browse instance variable references" for code that stores all its state in Dictionaries.

It is certainly legitimate to build models where state is sometimes present and sometimes not, even in instances of the same class. You wouldn't want to declare a hundred variables, almost all of which are nil in almost all instances, just because a few instances will need them.

* Put variables that only some instances will have in a Dictionary stored in an instance variable called "properties." Implement "propertyAt: aSymbol" and "propertyAt: aSymbol put: anObject" to access properties.

Visual Smalltalk uses properties connected to its graphical widgets to communicate between various parts of the program. For example, an EntryField has a property called `PreviousContents`, which is used to determine whether the field's contents have changed.

VisualWorks 2.5 has a perfect example of when NOT to use this pattern. Their Package object uses Variable State. The Constructor Method takes a name for the Package, so every Package has to have a name (Common State, right?). However, instead of being stored in an instance variable, it is stored as part of the Variable State.
Make sure that with any variables, all or nearly all instances shared are implemented as instance variables, not as entries on the property list. Variable State is often used as a temporary convenience and never revisited, even though its generality is not used.

> You may want to hide the difference between variables stored as instance variables and variables stored on the property list with a Getting Method (p. 93) and Setting Method (p 95).

FORWARD

## Explicit Initialization

BACK

> You've found Common State (p. 80) that always starts at the same value. A Constructor Parameter Method (p. 25) has just set the state of some variables.

* How do you initialize instance variables to their default value?

Usually, in these patterns, I have tried to avoid ambiguity. If there are two equally valid ways to accomplish some task, I pick one.

Initialization is an issue for which I cannot in good conscience pick one solution. There are two ways to solve the problem of instance variable initialization, each valid in different circumstances—circumstances you are certain to encounter.

This pattern emphasizes readability over flexibility. You should use an initialize method when you want people to read your code as easily as possible and you aren't terribly concerned about future subclasses. By putting all the initialization in one place, Explicit Initialization makes it easy to figure out what all the variables are.

Flexibility is impaired by Explicit Initialization because all of the variables are mentioned in a single method. If you add or remove an instance variable, you will have to remember to edit the Explicit Initialization.

Explicit Initialization can also be more costly than Lazy Initialization Methods because they spend the effort to initialize all the values at instance creation time. If computing some of the initial values is expensive and the values aren't used right away (or perhaps not at all), you may be able to improve performance by not initializing them right away.

* Implement a method "initialize" that sets all the values explicitly. Override the class message "new" to invoke it on new instances.
For example, consider a `Timer` that defaults to executing every 1000 milliseconds. It also keeps track of how many times it has gone off:

Class: Timer
superclass: Object
instance variables: period count

Use `basicNew` to create the instance to avoid accidentally setting "initialize" off twice, should a future superclass invoke it.

Timer class>>new
^self basicNew initialize

Now we can initialize the values:

Timer>>initialize
  count := 0.
  period := 1000

Even better, we can explain that magic number 1000 with a message:

Timer>>defaultMillisecondPeriod
^1000
Timer>>initialize
  count := 0.
  period := self defaultMillisecondPeriod
Put `initialize` methods in a method protocol called "initialize-release."

*Use Default Value Method (p. 86) to explain any value that isn't obvious. Initialize Methods in a hierarchy commonly need Extending Super (p. 60) to finish their job.*

FORWARD

# Lazy Initialization

BACK

*You are initializing Common State (p. 80).*

* How do you initialize an instance variable to its default value?

Here is the flip side of variable initialization. All the strengths of Explicit Initialization become weaknesses and all the weaknesses strengths.

Lazy Initialization breaks initialization into two methods per variable. The first is a Getting Method that hides the fact that the variable is lazily initialized from anyone wanting to use its value. This implies that there can be no Direct Variable Access. The second method, the Default Value Method, provides the default value of the variable.

This is where the flexibility comes in. If you make a subclass, you can change the default value by overriding the Default Value Method.

Readability suffers because there isn't any one place you can look to see all the variables and their initial values. Instead, you have to look at several methods to see all the values.

Performance is another reason to use a Lazy Initialization. Expensive initialization that may not be needed for a while (or at all) can be deferred by using Lazy Initialization.

* Write a Getting Method for the variable. Initialize it if necessary with a Default Value Method.

The Timer example from above needs no explicit initialization. Instead, count is initialized in its Getting Method:

```
Timer>>count
    count isNil ifTrue: [count := self defaultCount].
    ^count
```
The default value comes from its own method:

```
Timer>>defaultCount
^0
```

Similarly for period:

```
Timer>>period
period isNil ifTrue: [period := self defaultPeriod].
^period
Timer>>defaultPeriod
^1000
```

Some people swear by Lazy Initialization. They go so far as to say that all initialization should be done this way. I actually lean towards Explicit Initialization. Too many times, I've bent over backwards to supply lots of flexibility that is never used. I'd rather do it the simple way first, then fix it if it's a problem. However, if I know I am writing code that is likely to be subclassed by others, I'll go ahead and use Lazy Initialization from the first.

FORWARD

**A Default Value Method (p. 86) supplies a default value. A Compute Method supplies the value of a Caching Instance Variable.**

BACK

## Default Value Method

**You have a complicated default value in Explicit Initialization (p. 83). You need a default value for Lazy Initialization (p. 85).**

* How do you represent the default value of a variable?

The simplest way to provide default values is right in line with the code. It's generally easy to read and quick and simple to write.
Patterns whose purpose is creating flexibility (Lazy Initialization) or who may need additional communication (Explicit Initialization), need an Intention Revealing Message. It gives you an opportunity to communicate through the selector. It gives future subclasses the option of simply overriding a single value.

* Create a method that returns the value. Prepend "default" to the name of the variable as the name of the method.

A Book might offer up an empty String as its synopsis if no synopsis has been entered:

```
Book>>defaultSynopsis
^"
```

If you are computing the value of a Caching Instance Variable, call the method "computeArea" rather than "defaultArea." This will provide a clue to readers that the variable is intended as a cache.

Put Default Value Methods in a method protocol called "private."

**Use a Constant Method (p. 87) for constant default values.**

FORWARD

## Constant Method

BACK

**You are writing a Composed Method (p. 21). You may need a Default Value Method (p. 86).**

* How do you code a constant?

Smalltalk provides several options for representing shared constants or variables. Pools provide a set of variables that can be used in any number of different classes. Class variables are variables that are shared throughout a hierarchy.

I know that some folks use lots of pools in their applications. I never use them. Here's what I don't like about pools—they make it too easy to stop making useful responsibilities and instead just spread data around.
The IBM Smalltalk window system is a good example. There is a pool called CwConstants that contains hundreds of constants. Rather than being able to send a list pane a message like `#singleSelect` to make it select one item at a time, you send it `selectionPolicy: XmSINGLESELECT.`

Of course, you could say that this is just one little thing you have to remember, and besides, C programmers have to deal with stuff like this all the time. However, multiply “one little thing to remember” by several hundred and you don’t have a system that feels much like Smalltalk any more, at least not when you’re working with the window system.

I would rather limit the visibility of constants to a single class. Then, that class can provide meaningful behavior to other objects. If you can refactor your code so that only a single class cares about a constant, you can then represent that constant as a method.

In the list pane example, this means leaving the original implementation of `#selectionPolicy: alone` but not expecting outside objects to invoke it. Instead, for each of the possible argument values we create a method:

```
ListPane>>singleSelect
    self selectionPolicy: 15
```

If other methods also needed to know that `15` was the magic constant for single selection, we create a method for it—a method that just returns `15`.

```
ListPane>>singleSelectPolicy
    ^15
ListPane>>singleSelect
    self selectionPolicy: self singleSelectPolicy
```

One of the downsides of representing constants as methods is it is easier to automatically generate the initialization for a pool than it is to automatically create a method. If you have to synchronize a set of constants with other programs, you may find it easier to use pools. However, you should still strive to provide rich protocol so that few classes need to know about the pool.
Another question about Constant Methods is what happens when you have hundreds or thousands of constants? A pool can easily grow to contain as many entries as necessary. A class with a thousand Constant Methods would look cluttered.

* Create a method that returns the constant.

You can implement the colors of visual components as Constant Methods:

SelectorFigure>>textColor

^Color darkGray

ExpressionFigure>>textColor

^Color chartreuse

A comment I've heard over and over about this pattern is, "What if you have to deal with hundreds of constants in one class?" To me, a class that has to deal with hundreds of constants is almost certainly doing too much work and needs to be broken up. However, if you absolutely have to, you can use other facilities like Pools to manage huge numbers of shared constants.

Put Constant Methods in a method protocol called "private."

# Direct Variable Access

You need to access Common State (p. 80) as readably as possible.

How do you get and set an instance variable's value?

Accessing state is a topic much like initialization. There are two good answers. One is more readable. One is more flexible. Also like initialization, you will find dogmatic adherents of both approaches.

The simple, readable way to get and set the values of instance variables is to use the variables directly in all the methods that need their values. The alternative requires that you send a message every time you need to use or change an instance variable's value.

BACK
When I first started programming in Smalltalk, at Tektronix in the mid-80s, the debate about accessing state was hot. There were factions on both sides making self-important statements (don't you just love research labs?)

The Indirect Variable Access crowd has won the hearts and mind of the Small talking public, mostly, I think, because most of the high volume training companies teach indirect access. The issue is nowhere near as simple as "direct access bad, indirect access good."

I tried to reopen the debate in my Smalltalk Report column a few years back. A little brush fire started that eventually fizzled out. I was wondering if I was making too big a deal of the merits of direct access. Maybe I should have left well enough alone.

Then, I spent several months working for a client that insisted on indi-rect access. A professional programmer can take on any of a number of styles at will, so I was a good soldier and wrote my getters and setters.

After I was done with that client, I wrote some code for myself. I was amazed at how much smoother it read than what I had been previously work-ing on. The only difference in style was direct versus indirect access.

What I noticed was that every time I read:

...self x...

I paused for a moment to remind myself that the message “x” was just fetching an instance variable. When I read:

...X...

I just kept reading.

I told Ward of my experience. He had another good explanation. When you write classes that only have a handful of methods, adding a getting and a setting method can easily double the number of methods in your class—twice as many methods to buy you flexibility that you may never use.
On the other hand, it's awful frustrating to get a class from someone and see the opportunity to quickly subclass it, only to discover that they used Direct Variable Access, so there is no way to make the changes you want without changing most of the code in the superclass.

* Access and set the variable directly.

Most of the example code in this book uses Direct Variable Access because I want to be as easy to read as possible. When you have direct access, putting in Indirect Variable Access is no big deal. Thus, you can read:

```
Point>>setX: xNumber y: yNumber
x := xNumber.
y := yNumber
```

quickly, and there is no danger that you won't know what to do if you choose indirect access later.

# Indirect Variable Access

BACK

*You need to access Common State (p. 80) as flexibly as possible.*

How do you get and set an instance variable's value?

Now I have to display my true schizophrenia. Having convinced you in Direct Variable Access that just using variables is good enough, I'm going to ask you to ignore that crazy bastard and listen to me talk some sense here.

When you use Direct Variable Access, many methods make the assumption that a variable's value is valid. For some code this is a reasonable assumption. However, if you want to introduce Lazy Initialization, to stop storing and start computing the value, or if you want to change assumptions in a new subclass, you will be disappointed that the assumption of validity is wide spread.

The solution is to always use Getting Methods and Setting Methods to access variables. Thus, instead of:
Point>>+ aPoint
^x + aPoint x @ (y + aPoint y)

you would see:

Point>>+ aPoint
^self x + aPoint x @ (self y @ aPoint y)

If you browse the instance variable references of a class that uses Indirect Variable Access, you will only see two references to each variable, the Getting Method and the Setting Method.

What you give up with Indirect Variable Access is simplicity and readability. You have to define all those Getting Methods and Setting Methods. Even if you have your system do it for you, you have that many more methods to manage and document. As explained above, code using Direct Variable Access reads smoothly because you are not forever reminding yourself “Oh yeah, that’s just a Getting Method.”

* Access and set its value only through a *Getting Method* and *Setting Method*.

A Point written with Indirect Variable Access provides methods for its instance variables:

Point>>x
^x
Point>>x: aNumber
x := aNumber
That way, you could define a `PolarPoint` subclass that merely implemented these methods differently, and all the superclass code would still work.

```python
PolarPoint>>x
^self radius cos * self theta
```

If you need to code for inheritance, use Indirect Variable Access. Future generations will thank you.

One warning—do not go half way. If you are going to use direct access, use it for all access. If you decide later you need to move a variable to indirect access, perhaps to take advantage of Lazy Initialization, change the accessing of the variable throughout. On the other hand, it doesn't bother me much to see some variables in an object accessed directly and others indirectly.

**You will need to define a Getting Method (p. 93) and a Setting Method (p. 95) for each variable. For variables holding collections, consider implementing Collection Accessor Methods (p. 96) and an Enumeration Method (p. 144).**

FORWARD

BACK

# Getting Method

**You are using Lazy Initialization or Indirect Variable Access (p. 91).**

* How do you provide access to an instance variable?

Once you have decided to use Indirect Variable Access, you are committed to providing a message-based protocol for getting and setting variable values. The only real questions are how you use it and what you call it.

Here's the real secret of writing good Getting Methods—*make them private at first*. I cannot stress this enough. You will be fine if the same object invokes and implements the Getting Method. Another way of saying this is you always send messages invoking Getting Methods to "self."
Some people try to ensure this by prefixing “my” to the name of the method. Thus, instead of:

x

^X

you have:

myX

^X

This makes sure that code like:

self bounds origin myX

looks stupid. I don't feel this is necessary. I'd rather give programmers (myself included) the benefit of the doubt. If some other object absolutely has to send my private Getting Method, it should be able to do so in as readable a manner as possible.

* Provide a method that returns the value of the variable. Give it the same name as the variable.

A Book that needed to display its author and title in a user interface would publish Getting Methods:
Book>>author
^author
Book>>title
^title

There are cases where you will publish the existence of Getting Methods for use in the outside world. You should make a conscious decision to do this after considering all the alternatives. It is preferable to give an object more responsibility, rather than have it act like a data structure.

Put private Getting Methods in a method protocol called "private-accessing." Put public Getting Methods in a method protocol called "accessing."

# Setting Method

You are using Indirect Variable Access (p. 91).

* How do you change the value of an instance variable?

Everything I said once about Getting Methods, I'd like to say twice about Setting Methods. Setting Methods should be even more private. It is one thing for another object to tear out your state, it is quite another for it to bash in a new state. The possibilities for the code in the two objects to get out of sync and break, in confusing ways, are legion.

Revisiting naming, I don't feel it is necessary to prepend "my" to the names of Setting Methods. It might provide a little more protection from unauthorized use, but I don't think the extra difficulty reading is worth it.

* Provide a method with the same name as the variable. Have it take a single parameter, the value to be set.
A Book editing interface would need Setting Methods for author and title:

```ksharp
Book>>author: aString
author := aString
Book>>title: aString
title := aString
```

Even if I use Indirect Variable Access, if I have a variable that is only set at instance creation time, I would not provide a Setting Method. I'd use the Constructor Parameter Method to set the all the values at once. Once you have a Setting Method, though, you should use it for all changes to the variable.

Put private Setting Methods in a method protocol called "private-accessing." Put public Setting Methods in a method protocol called "accessing."

FORWARD

Set boolean properties with a Boolean Property Setting Method (p. 100).

## Collection Accessor Method

BACK

You are using Indirect Variable Access (p. 91).

* How do you provide access to an instance variable that holds a collection?

The simplest solution is just to publish a Getting Method for the variable. That way, any client that wants can add to, delete from, iterate over, or otherwise use the collection.

The problem with this approach is that it opens up too much of the implementation of an object to the outside world. If the object decides to change the implementation, say by using a different kind of collection, the client code may well break.

The other problem with just offering up your private collections for public viewing is that it is hard to keep related state current when someone else
is changing the collection without notifying you. Here's a department that uses
a Caching Instance Variable to speed access to its total salary:

```python
Department
    superclass: Object
    instance variables: employees totalSalary
    totalSalary
        totalSalary isNil ifTrue: [totalSalary := self
        computeTotalSalary].
        ^totalSalary
    computeTotalSalary
        ^employees
            inject: 0
            into: [:sum :each | sum + each salary]
    clearTotalSalary
        totalSalary := nil
```

What happens if client code deletes an employee without notifying the
department?

...aDepartment employees remove: anEmployee...

The totalSalary cache never gets cleared. It now contains a number
inconsistent with the value returned by computeTotalSalary.

The solution to this is not to let other objects have your collections. If you
use Indirect Variable Access, make sure Getting Methods for collections are
private. Instead, give clients restricted access to operations on the collection
through messages that you implement. This gives you a chance to do whatever
other processing you need to.

The downside of this approach is that you have to actually implement all
of these methods. Giving access to a collection takes one method. You might
need four or five methods to provide all the necessary protected access to the
collection. In the long run, it's worth it though, because your code will read better and be easier to change.

* Provide methods that are implemented with Delegation to the collection. To name the methods, add the name of the collection to the collection messages.

If Department wanted to let others add and delete employees, it would implement Collection Accessor Methods:

addEmployee: anEmployee

self clearTotalSalary.

employees add: anEmployee

removeEmployee: anEmployee

self clearTotalSalary.

employees remove: anEmployee

Don't just blindly name a Collection Accessor Method after the collection message it delegates. See if you can find a word from the domain that makes more sense. For example, I prefer:

employs: anEmployee

^employees includes: anEmployee

to:

includesEmployee: anEmployee

^employees includes: anEmployee
Put Collection Accessor Methods in a method protocol called "accessing."

FORWARD

**Implement an Enumeration Method (p. 99) for safe and efficient general collection access.**

Enumeration Method

BACK

*You are using Indirect Variable Access (p. 91). You may have implemented a Collection Accessor Method (p. 96).*

* How do you provide safe, general access to collection elements?

Sometimes, clients want lots of ways of accessing a private collection. You could implement twenty or thirty Collection Accessor Methods but you haven't the time and you aren't even sure even that would be enough. At the same time, all the arguments for not just making a Getting Method for the collection public still hold.

* Implement a method that executes a Block for each element of the collection. Name the method by concatenating the name of the collection and "Do:."

The Enumeration Method for a Department's Employees looks like this:

```ruby
Department>>employeesDo: aBlock
employees do: aBlock
```

Now client code that wants to get a collection of all of the Employees in a bunch of departments can use a Concatenating Stream:
```kotlin
allEmployees
    | writer |
        writer := WriteStream on: Array new.
        self departments do: [:eachDepartment |
            eachDepartment employeesDo: [:eachEmployee | writer
            nextPut: eachEmployee]]
        ^writer contents
```

What if you want Departments to be able to contain other Departments, and not just Employees (this is an example of the modeling pattern Composite)? You can implement employeesDo: for both:

```kotlin
Department>>employeesDo: aBlock
    employees do: [:each | each employeesDo: aBlock]
Employee>>employeesDo: aBlock
    aBlock value: self
```

Put Enumeration Methods in a method protocol called "enumerating."

## Boolean Property Setting Method

*You are using a Setting Method (p. 95).*

* How do you set a boolean property?

The simplest solution is to use a Setting Method. Let's say we have a Switch that stores a Boolean in an instance variable "isOn." The Setting Method is:

BACK
```kotlin
Switch>>on: aBoolean
isOn := aBoolean
```

There are two problems with this approach. The first is that it exposes the representation of the status of the switch to clients. This has led me to situations where I make a representation change in one object that has to be reflected in many others. The second problem is that it is hard to answer simple questions like “who turns on the switch?”

Creating distinct methods for the two states causes you to create one more method than you would have otherwise. However, the cost of these methods is money well spent because of the improvement in communication of the resulting code.

Using the names of the two states as the names of the methods is tempting (Switch>>on and Switch>>off, in this example). As with Query Method, though, there is a potential confusion about whether you're interrogating the object or telling it what to do. Thus, even though adding another word to the selector results in a selector that is less natural to say, the added clarity is worth it.

* Create two methods beginning with "be." One has property name, the other the negation. Add " toggle" if the client doesn't want to know about the current state.

Here are some examples:

```
beVisible/beInvisible/toggleVisible
beDirty/beClean
```

Put Boolean Property Setting Methods in a method protocol called "accessing."
<figure><img src="image_9.png" /></figure>

# Role Suggesting Instance Variable Name

You need to name Common State (p. 80).

* What do you name an instance variable?

The two important pieces of information to communicate about any variable are:

* What is its purpose?

* How is it used?

The purpose or role of a variable is important to the reader because it helps direct their attention appropriately. Typically, when you read code you have a purpose in mind. If you understand the role of a variable and it is unrelated to your purpose, you can quickly skim over irrelevant code that uses that variable. Likewise, if you see a variable that is related to your purpose, you can quickly narrow your reading to relevant code by looking for that variable.

How a variable is used and the messages it is sent are its “type.” Smalltalk doesn’t have declared types, but that doesn’t mean they aren’t important. Understanding the messages sent to a variable tells you what objects can be safely placed as values in that variable. Substitution of objects is the heart of disciplined maintenance and reuse.

Different variables appear in different contexts, so what you need to communicate with their names is different. The context for instance variables is most similar to the context for temporary variables. The only way you have for communicating the role of an instance variable is through its name. If the variables in Point were called “t1” and “t2” instead of “x” and “y,” you’d have a lot of reading to do before you could tell which was the horizontal component and which the vertical. Naming the variables by their roles gives you that information directly.

On the other hand, the type of an instance variable is easily discovered from the code in which it resides. It is easy to find where the variable is used and from there discover what messages it is sent. You also get hints from Creation Parameter Setting Methods or Setting Methods that set the value of the variable. If I asked you what the type of “x” was in:

Point>>x: aNumber
x := aNumber
you'd be able to tell me instantly. In the interest of keeping names simple, short, and readable, you can safely leave out any mention of the type of a variable in its name.

* Name instance variables for the role they play in the computation. Make the name plural if the variable will hold a Collection.

The role of the instance variable "x" is to hold the horizontal offset of the Point. The role of the "y" instance variable is to hold the vertical offset.

## Temporary Variables

Temporary variables let you store and reuse the value of expressions. They can be used to improve the performance or readability of methods. The following patterns motivate and guide the use of temporary variables. The examples are taken from Smalltalk, but the discussion applies to any language with procedure-scoped variables.

## Temporary Variable

BACK

*A Composed Method (p. 21) needs temporary storage.*

* How do you save the value of an expression for later use within a method?

A stateless language like FP contains no notion whatever of a variable. If you need the value of an expression, you evaluate the expression. If you need it in many places in a program, you evaluate it many places.

While the abstract properties of a stateless language might be attractive to a language designer, practical programs use variables to simplify the expression of computation. Each variable has several distinguishing features. The scope of a variable is the textual area within which it can be used. The extent of a variable defines how long its value lasts. The type of a variable is the signature of messages sent to it.

Long extent, wide scope, and large type all make variables difficult to manage. If all three factors are present in many variables, you have a program that can only be understood in its entirety. Limiting the scope, extent, and type of variables wherever possible produces programs that are easier to understand, modify, and reuse.
Another language design decision is whether to require the explicit declaration of variables. Early languages, like FORTRAN, detected the presence of variables automatically. ALGOL and its descendants required explicit declaration. Explicit declaration puts a burden on the programmer writing the program but pays off when someone else needs to understand the program. The presence and use of variables is often the first place a reader begins.

* Create a variable whose scope and extent is a single method. Declare it just below the method selector. Assign it as soon as the expression is valid.

Temporary variables are good at helping you understand a computation that is halfway towards its goal. Thus, you can more easily read:

```
Rectangle>>bottomRight
| right bottom |
right := self left + self width.
bottom := self top + self height.
^right @ bottom
```

than you can:

```
Rectangle>>bottomRight
^self left + self width @ (self top + self height)
```

Collecting *Temporary Variable* saves intermediate results for later use. *Caching Temporary Variable* (p. 106) improves performance by saving values. *Explaining Temporary Variable* (p. 108) improves readability by breaking up complex expressions. *Reusing Temporary Variable* (p. 109) lets you use the value of a side-effecting expression more than once in a method.
<figure><img src="image_10.png" /></figure>

# Collecting Temporary Variable

*Sometimes a Temporary Variable (p. 103) is used to collect intermediate results.*

* How do you gradually collect values to be used later in a method?

The right set of enumeration protocol would make this question moot. Inject:into:, in particular, often eliminates the need for a temporary variable. Code like:

```
| sum |
sum := 0.
self children do: [:each | sum := sum + each size].
^sum
```

can be rewritten as:

```
^self children
  inject: 0
  into: [:sum :each | sum + each size]
```

The variety of enumeration strategies in complex programs makes it impossible to generalize the `inject:into:` idiom. For example, what if you want to merge two collections together so that you have an element from collection a, an element from collection b, and so on. This would require a special enumeration method:

```
^self leftFingers
  with: self rightFingers
  inject: Array new
  into: [:sum :eachLeft :eachRight |
    ...(sum copyWith: eachLeft) copyWith: eachRight]
```
It is much simpler to create a Stream for the duration of the method:

```kotlin
| results |
results := Array new writeStream.
self leftFingers with: self rightFingers do:
    [:eachLeft :eachRight | results nextPut: eachLeft;
nextPut: eachRight].
^results contents
```

* When you need to collect or merge objects over a complex enumeration, use a temporary variable to hold the collection or merged value.

The variable "answer" in `Collection>>deepCopy` is a simple example of a Collecting Temporary Variable:

```kotlin
deepCopy
| answer |
answer := self species new.
self do: [:each | answer add: each copy].
^answer
```

FORWARD

**Role Suggesting Temporary Variable Name (p. 102) explains how to name the variable.**

## Caching Temporary Variable

**A performance measurement has shown you that an expression in a method is a bottleneck.**

* How do you improve the performance of a method?

Many performance related decisions sacrifice programming style to the needs of demanding users with limited machine resources. Successful performance tuning hinges on being explicitly aware of this tradeoff and only intro-
ducing changes that pay back in increased performance more than they cost in increased maintenance.

As with variables, the scope and extent of a performance tuning decision dramatically affect its cost. Performance related changes that are confined to a single object are good, changes that only affect a single method are even better.

All performance tuning boils down to two techniques—either you execute code less often or you execute code that costs less. Of these, the first is often the most valuable. It relies on the fact that for reasons of readability, expressions are often executed several times even though they return the same value. Caching saves the value of the expression so that the next time the value is used instantly.

The biggest problem with caches is their assumption that the expression returns the same value. What if this isn't true? What if it is true for a while, but then the value of the expression changes? You can limit the complexity introduced by the need to keep a cache valid by limiting the scope and extent of the variable used for the cache.

* Set a temporary variable to the value of the expression as soon as it is valid. Use the variable instead of the expression in the remainder of the method.

For example, you might have some graphics code that uses the bounds of the receiver. If calculating the bounds is expensive, you can transform:

self children do: [:each | ...self bounds...]

into:

| bounds |

bounds := self bounds.

self children do: [:each | ...bounds...]

If the cost of calculating the bounds dominates the cost of the method, this takes a method that is linear in cost in the number of children and turns it into one that is constant.
**Role Suggesting Temporary Variable Name (p. 102) explains how to name the variable. Caching Instance Variable caches expression values if they are used from many methods.**

## Explaining Temporary Variable

**Temporary Variable (p. 103) can be used to improve the readability of complex methods.**

* How do you simplify a complex expression within a method?

In the passion of the moment, you can write expressions within methods that are quite complex. Most expressions are simple at first. As soon as you are looking at live data, though, you realize your naive assumptions will never work. You add this complexity, then that one, then another, until you have many layers of messages piled on each other. While you are debugging, it is all understandable because you have so much context. Coming back to such a method in six months is quite a different experience.

Fixing the method right might require changes to several objects. While you are just exploring, such a commitment might be inappropriate.

* Take a subexpression out of the complex expression. Assign its value to a temporary variable before the complex expression. Use the variable instead in the complex expression.

An example is the use of the variable `"lastIndex"` in `LinearHashMap>>findKeyIndex:for: from Visual Smalltalk. The message "size" is fast, so the performance of the method would probably not change much if the variable weren't used. The size of the receiver is being used to mean a final value for an index, so the variable helps explain the method:

```
LinearHashMap>>findKeyIndex: element for: client
    | index indexedObject lastIndex |
    lastIndex := self size.
...
```
*Role Suggesting Temporary Variable Name (p. 102) explains how to name the variable. Composed Method (p. 21) puts the subexpression where it belongs and gives it a name.*

## Reusing Temporary Variable

*Temporary Variable (p. 103) can be used to reuse the value of expressions that cannot be executed more than once.*

* How do you use an expression several places in a method when its value may change?

Methods without temporary variables are easier to understand than methods with temporary variables. However, you sometimes encounter expressions whose values change, either because of side-effects of evaluating the expression or because of outside effects, but you need to use the value more than once. Using a temporary variable is worth the cost in such a case, because the code simply wouldn't work otherwise.

For example, if you are reading from a stream, the evaluation of "stream next" causes the stream to change. If you are matching the value read against a list of keywords, you must save the value. Thus:

```
stream next = a ifTrue: [...].
stream next = b ifTrue: [...].
stream next = c ifTrue: [...]
```

is not likely what you mean. Instead, you need to save the value in a temporary variable so you only execute "stream next" once.

```
| token |
token := stream next.
token = a ifTrue: [...]
...
```
Resources that are affected by the outside world also require this treat-
ment. For example, "Time millisecondClockValue" cannot be executed more
than once if you want to be guaranteed the same answer.

* Execute the expression once and set a temporary variable. Use the variable instead of the expression in the remainder of the method.

FORWARD

**Role Suggesting Temporary Variable Name (p. 110)** explains how to name the variable.

BACK

Role Suggesting Temporary Variable Name

Collecting Temporary Variable (p. 105) stores the intermediate results of a computation. Caching Temporary Variable (p. 106) improves performance by eliminating redundant computation. Explaining Temporary Variable (p. 108) makes methods containing complex expressions easier to read. Reusing Temporary Variable (p. 109) correctly executes methods containing side-effecting expressions.

* What do you call a temporary variable?

There are two important dimensions to communicate about a variable.
The first is its type. Readers wishing to modify code need to know what
responsibilities are assumed for an object occupying a variable. The second
important dimension is role, that is, how the object is used in the computation.
Understanding the role is important to understanding the method in which
the variable is used. Different kinds of variables require different naming
treatments to communicate type and role.

Temporary variables communicate their role by context. If you are
staring at:

| sum |
sum := 0.
...sum...
you cannot possibly be confused about its type. Even if a temporary variable is
initialized by a expression, you will be able to understand its type as long as
the expression is well written:

| bounds |
bounds := self bounds.
... bounds ...

Role, on the other hand, requires explicit communication. You have prob-
ably had the experience of reading code whose temporary variables had names
like "a," "b," and the ever popular "temp." As a reader, you have to go through
the code holding these useless names in your head until the light comes on. "A
ha! 'b' is really the left offset of the parent widget."

* Name a temporary variable for the role it plays in the computation.

Use variable naming as an opportunity to communicate valuable
tactical information to future readers.

"results" is a good name for a Collecting Temporary Variable.
"right" and "bottom" are good names for Explaining Temporary
Variables.
*This page intentionally left blank*
5

Collections

The collection hierarchy is one of the great strengths of Smalltalk. Code that has to be tediously written over and over in other languages is a single word in Smalltalk. The result is more flexible, because the collections respond to much of the same protocol, so a linear list can be converted to a hash table by substituting “Set” for “OrderedCollection.”

The bad news is, the collection classes give you yet more stuff to learn so you can master Smalltalk. The good news is, no single piece of the protocol is complicated or hard to learn and the result is code that is simpler, faster, easier to maintain, and more flexible.

The very richness of the collection classes is their biggest
drawback. Beginning programmers typically learn to use a small
fraction of the available classes and messages, relying on leftover
skills from procedural programming for the rest of the functionali-
ty they need. As a result, their code is much larger than it needs to
be, difficult to read for an experienced Smalltalker, and more prone
to error.

For example, it is common to find hand coded loops for itera-
tion in beginner Smalltalk code. Not only is:
```pascal
l index l
index := 1.
[index <= aCollection size] while True:
    [...aCollection at: index...
    index := index + 1]
```

more difficult to write and read than:

```pascal
aCollection do: [:each l ...each...]
```

it is also less flexible. The first code will only work with indexed collections. The second will work with Sets and Dictionaries, too.

During code reviews, I commonly find opportunities to transform four, five, or six line expressions into a single line using the full power of the collection protocol.

Our discussion of collections is divided into three sections:

*   **Classes**—When you want to use a collection, the first thing you have to decide is “which one.” This section describes what problem or problems each of the major collection classes solve.

*   **Protocol**—Programming habits carried over from other languages can reduce the effectiveness of code when you use collections. This section describes the major messages you can send to collections and what problem each solves.

*   **Idioms**—Because collections are so powerful, there are a small set of standard tricks that experienced Smalltalkers know to play with them. If you are reading code that uses one of these idioms, you may be puzzled at first. This section introduces the problems you can solve using collections in unusual ways.

## Classes

This section presents the circumstances under which you would choose to use each of the major collection classes.
# Collection

* How do you represent a one-to-many relationship?

Every programming language provides facilities to represent one-to-many relationships. The first data structure in FORTRAN was the array.

Computer science has made a franchise of representing one-to-many relationships. How many thousands of varieties of trees, lists, and tables are there hidden away in the Journals of the ACM?

Such an important topic has picked up a vast quantity of idiom in every programming language. Even though I hardly use C any more, I can instantly recognize:

for (i = 0; i < n; i++) ...

as iterating over an array.

One of the most brilliant early developments in Smalltalk was presenting a unified protocol to all the varieties of ways of representing one-to-many relationships. No longer does all client code directly encode how to iterate over elements. Iteration is the responsibility of the object representing the relationship itself. This results in tremendous power throughout development. You can change from a linear list to a hash table by changing “OrderedCollection” to “Set,” with the confidence that no other code will be affected.

The down side of the Collection classes is their very power. Because you can write code involving Collections in very few words, you have to be initiated in the special meaning of those words before you have a chance of understanding such code. Once you understand the vocabulary, though, you will never be able to write code in a language that doesn’t support Collections without a wistful sigh about “how easy this would be in Smalltalk.”

There is an alternative to using the Collection classes. Any class can be made indexable, that is have both named variables and variables you access through `at:` and `at:put:`. Using this feature, any class can be made to act like both a regular object and a collection, at the same time. This would be useful if you were extremely tight on space, but copying the Collection code just isn't worth it.

* Use a Collection.
A Library could keep a Collection of Books.

**Use an OrderedCollection for Collections (p. 116) that change size dynamically.**
**Use an Array (p. 133) for fixed-sized Collections. Use a Set (p. 119) to ensure element uniqueness.**
**Use a Dictionary (p. 128) to map from one kind of object to another. Use a Temporarily Sorted Collection (p. 155) for ordering elements.**
**Use a SortedCollection (p. 131) to keep elements in a computed order.**

FORWARD

OrderedCollection

BACK

You need a dynamically sized Collection (p. 115).

* How do you code Collections whose size can't be determined when they are created?

Many of the hassles programs give users come from the need for flexibility. Primitive memory management has lead to a lack of flexibility in the sizes of data. Every time I read, "You can have up to 99 files" or "Each function can have no more than 256 lines," I imagine a software engineer preallocating memory to handle just that many items. While arbitrary limits like "99" or "256" are typically chosen because the engineers can't imagine the need for any more, just as typically, they become a hindrance to a user somewhere down the road (sometimes years down the road).

There is no excuse for arbitrary data size limitations in Smalltalk. Two factors work in your favor as you try to eliminate such limits. First, the Collection classes give you tremendous leverage to change your mind about representing one-to-many relationships. Second, the garbage collector frees you from the drudgery of maintaining references as data structures change size.

This flexibility comes at a cost. The implementation of OrderedCollection, the most common dynamically sized Collection, allocates more memory than it strictly needs at first, so that some growth can be accommodated at little cost. The implementation also uses indirection to access elements. In some Collection-intensive code, I have found this to be a bottleneck. While you're just trying to get the program working, though, you shouldn't worry about such issues. There is time enough to address them later.

* Use an OrderedCollection as your default dynamically sized Collection.

Here is an example of using OrderedCollection:
Class: Document
superclass: Object
instance variables: paragraphs

A Document stores an OrderedCollection of Paragraphs, defined here with Lazy Initialization:

Document>>paragraphs
paragraphs isNil ifTrue: [paragraphs :=
OrderedCollection new].
^paragraphs

We need to be able to add new Paragraphs dynamically, so we need OrderedCollection's ability to change its size dynamically:

Document>>addParagraph: aParagraph
self paragraphs add: aParagraph

Typesetting a Document is implemented by typesetting each Paragraph in turn. The order of the Paragraphs is important, so storing them in an OrderedCollection is exactly right.

Document>>typesetOn: aPrinter
self paragraphs do: [:each | each typesetOn: aPrinter]
<figure><img src="image_11.png" /></figure>

## RunArray

You are using an OrderedCollection (p. 116).

* How do you compactly code an OrderedCollection or Array where you have the same element many times in a row?

The simplest solution is just to use an OrderedCollection. During early development, this is probably the right answer. When you begin working with realistic sized data sets, you may discover that you are using more memory than you can afford.

The classic example of this is text editing. Conceptually, each character in an editor has its own font, size, and decoration. The obvious representation of this is as an OrderedCollection of Style objects that parallels the characters. This might even work for short text. When you are dealing with a whole book, though, the extra four bytes for the slot in the OrderedCollection plus the 12 bytes for the Style header plus the 12 bytes for the variables in the Style plus all the bytes for the Font, Size, and Decoration objects really add up.

If you look at typical text, you'll see that most of the information is redundant. There will be 50 characters with one style, 200 with another, 90 with another, and so on. A RunArray stores this as "50 of style 1, 200 of style 2, 90 of style 3." Each count-object pair is called a "run."

If we stored this information in an OrderedCollection, we would need 340 elements. A RunArray needs only three runs (each with two references).

Storage efficiency comes at a cost. First, if you really have a different object in each element, a RunArray will take twice as much storage as an Array or OrderedCollection. Second, the time necessary to access an element at the end of a RunArray is proportional to the number of runs. The VisualWorks implementation avoids some of this cost by caching the position of the last element fetched.

* Use a RunArray to compress long runs of the same element.

A common example of using a RunArray is storing the emphasis for text. In a piece of text like this:

this is a test

the characters themselves can be stored in a 14 element String. The emphasis can be stored in a parallel 14 element array:
## `(plain plain plain plain plain bold bold bold bold plain plain plain plain plain plain)`

This takes an extra four bytes per character, or 56 bytes. However, because there are so many adjacent elements that are the same, a `RunArray` can save space. You can think of it as storing:

5-#plain, 4-#bold, 5-#plain

This takes only 6 x 4 bytes, equaling 24 bytes.

I know I need a `RunArray` when I click "self" in an inspector of an `Array` or `OrderedCollection` and I see the same element printing over and over.

The beauty of using a `RunArray` is that client code can't know whether they have an `Array`, an `OrderedCollection`, or a `RunArray`, since they all support the same messages. You can code with whichever one works best, then change your mind later without any appreciable cost.

VisualWorks 2 implements `RunArray`. `VisualAge` and `VisualSmalltalk` do not at this writing.

# Set

BACK

> You need a **Collection** (p. 115) with unique elements. You may need a **Collecting Parameter** (p. 75) without duplicates. You may have been using an **OrderedCollection** (p. 116).

* How do you code a Collection whose elements are unique?

Suppose you have a Collection of Accounts and you want to send statements to all of the Owners. You don't have an explicit Collection of the Owners
anywhere. You only want to send a single statement to each Owner. Each
Owner could have a number of different Accounts.

How can we get each Owner only once? The naive code doesn't work right:

owners
  | results |
  results := OrderedCollection new.
  self accounts do: [:each | results add: each owner].
  ^results

We may get multiple copies of an Owner. You could solve this problem
yourself by checking whether an owner was in the results before adding it:

owners
  | results |
  results := OrderedCollection new.
  self accounts do:
    [:each if owner |
     owner := each owner.
     (results includes: owner) ifFalse: [results add:
      owner]].
  ^results

Sets solve this problem for you by ignoring `add: anObject` if anObject is
already part of the Set. Using a Set instead of an OrderedCollection fixes the
problem.

owners
  | results |
  results := Set new.
  self accounts do: [:each | results add: each owner].
  ^results
Another way of looking at the difference is by trying both Collections out in a workspace:

```
| o |
o := OrderedCollection new.
```

Put the String 'abc' in the Collection and it occurs once:

```
o add: 'abc'.
o occurrencesOf: 'abc' => 1
```

Put it in again, and it occurs twice:

```
o add: 'abc'.
o occurrencesOf: 'abc' => 2
```

Take it out once, and it only occurs once:

```
o remove: 'abc'.
o occurrencesOf: 'abc' => 1
```

Sets show different behavior.

```
| s |
s := Set new.
```
Like an OrderedCollection, put 'abc' in once and it occurs once:

```ruby
s add: 'abc'.
s occurrencesOf: 'abc' => 1
```

But, put it in again, and it still only occurs once:

```ruby
s add: 'abc'.
s occurrencesOf: 'abc' => 1
```

Take it out, and it's gone:

```ruby
s remove: 'abc'.
s occurrencesOf: 'abc' => 0
```

(By the way, any time I'm trying to understand some new code, I pull out a workspace and start fiddling like this. There is no better way to understand a new object than to grab an instance and start sending it messages. If you think you know what's going on, try to predict how it will react. If you haven't a clue, just start sending messages and see what comes back.)

The elimination of duplicates comes at a cost. The order of adding and deleting that OrderedCollection preserves is not available for Sets. Also, OrderedCollection responds to the indexed messages at: and at: put:.. Sets do not.

* Use a Set.

Use Sets when you don't want duplicates. If we want to get a Collection of all the members of all the clubs, we could just write:
clubMembers
  I results I
    results := OrderedCollection new.
    self clubs do: [:each I results addAll: each members].
    ^results

If one student could be in more than one club, that student would show up more than once in the result. To avoid this, we write:

clubMembers
  I results I
    results := Set new.
    self clubs do: [:each I results addAll: each members].
    ^results

Sets probably cause me the most incompatibility problems of any of the Collection classes. I am forever passing a Set to a list pane that expects an indexable Collection. It is easy enough to solve the problem by creating an Array or SortedCollection.

memberList: aPane
aPane contents: self clubMembers

becomes: