Smalltalk Best Practice Patterns: Part Two

Continuing from Part One

Patterns - Behavior

First pattern Kent mentioned is Composed Method, this basically explain the “Extract Method” refactoring action that’s implemented in all IDEs now.

Then, he described useful patterns that are more commonly known as “Copy Constructor”, “Getters/Setters”

One pattern that really stood out to me is Method Object. In this pattern, you have a complex method with many shared variables and parameters. Instead of refactoring directly in this class, create a new class named after the method. The parameters becomes constructor parameters and the shared variables become instance variables.

From

void startJob(String jobName, Date startTime) {
  Job job = findJob(jobName);
  job.setStartTime(startTime);
  validateJob(job);
}

To

class JobStarter {
  Job job;
  public JobStarter(String jobName, Date startTime) { }
  public void perform() {
    Job job = findJob();
    job.setStartTime(startTime);
    validateJob();
  }
  Job findJob() { }
  void validateJob();
}

I can see this is a good way to formalize a typical refactoring thought process.

Delegation using composition is another set of patterns. Still very relevant today.

Pluggable patterns defined ways to make a class, method to have variable behavior. This is another instance where Java’s lack of simple anonymous function (until Java 8) reduces the power of pluggable variation based on a passed in anonymous function or block.

Patterns - State

Many good ones here that are common knowledge now.

Collection Accessor Method - hide actual collection implementation from clients

From

class C {
  Map<String> names;
  Map<String> getNames() {}
}

To

class C {
  List<String> names;
  void addName(String name) {}
  void removeName(String name) {}
}

Enumeration Method - basically describes Iterable.forEach(item -> doSomething(item)) in Java 8

Boolean Property Setting Method - judicially create one or 2 specifically named method to effect a change in a boolean property

class A {
  boolean switchState;
  void turnOn();
  void turnOff();
}

Explaining Temporary Variable - refactoring action “Extract Variable”. The key point is to name the variable so that it’s easy to divine its intention.

void not_so_good() {
  if (state == something || state == somethingelse) {}
}
void better() {
  boolean valid_state = state == something;
  boolean end_state = state == somethingelse;
  if (valid_state || end_state) {}
}

Patterns - Classes

Simple Superclass Name combined with Qualified Subclass Name demonstrate typical naming strategy in libraries and framework. Makes a lot of sense.

Conclusion

I’m glad to have gone through it. Very cool that such a book from 1996 is still so relevant to us today. It’s an easy read and is a good way to get an exposure to the Smalltalk language. Through Smalltalk and this book, you can see evidence of both in current languages and frameworks.