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.