This document discusses several basic design principles and smells:
- A class should have a single responsibility and minimize access to its data.
- Inheritance should represent an "is-a" relationship, not be used for implementation convenience.
- Methods should not expose implementation details and overuse of conversions should be avoided.
- Missing information should be handled gracefully rather than raising errors.
- Nil values should be avoided by returning empty collections instead.
- Objects rather than strings or tuples should be used to represent data.
- The tell-don't-ask principle of using polymorphism rather than conditionals on types should be followed.
- Encapsulation should be maintained by not overusing accessors and
3. S.Ducasse 3
A Class should have
Class Person {
String getName();
void setName(String name);
int getAge();
void setAge(int age);
Car getCar();
void setCar(Car car);
}
What do we see ?
A class should have one main responsibility and some
behavior not just holding state
Minimal access to its data!
4. S.Ducasse 4
Confusing
Class City extends Place { ⊠}
Class Jerusalem extends City implements Capital { ⊠}
Class TelAviv extends City { ⊠}
What is wrong here?
Confusing inheritance and instantiation
Too much inheritance?
6. S.Ducasse 6
Do not overuse conversions
nodes asSet
removes all the duplicated nodes (if node knows how to
compare). But a systematic use of asSet to protect yourself
from duplicate is not good
nodes asSet asOrderedCollection
returns an ordered collection after removing duplicates
Look for the real source of duplication if you do not want
it!
7. S.Ducasse 7
Hiding missing information
Dictionary>>at: aKey
This raises an error if the key is not found
Dictionary>>at: aKey ifAbsent: aBlock
Allows one to specify action aBlock to be done when the
key does not exist.
Do not overuse it:
nodes at: nodeId ifAbsent:[ ]
This is bad because at least we should know that the
nodeId was missing
8. S.Ducasse 8
Avoid returning nil
Avoid to return special results as nil
messages := self fetchMessages.
messages isNil
 ifFalse: [ messages dispatchFrom: self ]
What if we would simply return an empty collection in
fetchMessages instead of nil?
Less conditional and ugly tests!!
9. S.Ducasse 9
Objects not strings!
âą Strings are dead objects
âą You can only concatenate strings
âą Use objects not their textual representation
10. S.Ducasse 10
Objects not tuples!
âą spec first
âą spec second
âą spec third
âą spec action
âą spec selector
âą spec menuItem
âą And add a printing
âą aSpec(âopenâ, #openBrowser,âopen (O)â)
11. S.Ducasse 11
Tell, Donât Ask
âą no condition and case based on the receiver type
âą Use polymorphism as much as possible to avoid type
checking