Patterns of Work Patterns of Nature Patterns of Movement ...
Patterns
-
Upload
logan-franklin -
Category
Documents
-
view
30 -
download
0
description
Transcript of Patterns
Patterns
1
Intention revealing selector
Naming based on side effects
Double-dispatching method
Accessing methods
Query methods
Boolean property setting
Converter methods
Constructors
2
Composed Method
How big should a method be?
Write methods that perform one identifiable task.
Few lines per method.
Consistent level of abstraction.
Minimizes number of methods you have to change in subclass.
Minimizes code copying in subclass.
3
Composed Method UsageTop down
- self input; process; output
Bottom up
- common expressions
- long loop bodies
- comments
From client - two or more messages to another object is suspicious
4
Methods from Comments
Comments indicate "identifiable task"
If you need to comment a block of code, it probably should be a separate method.
Turn method comment into method name.
5
Reversing MethodGood 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: aStream6
Reversing method
Point
printOn: aStream
aStream
print: x;
nextPutAll: ‘ @’;
print: y
7
Reversing method
Make a method on the parameter.
Derive its name from the original message.
Take the original receiver as a parameter.
Implement the method by sending the original message to the original receiver.
8
Method object
What do you do about a method that is too big but that can’t be decomposed because of all the temporary variables that are used?
Turn method into a class. Temporary variables and arguments become instance variables. Then you can decompose the method.
9
Example of Method Object
In class Class
readNewSubclassOn: aCodeReader in: aNameSpace
| fullName numInstVars numMetaInstVars
metaclassFormat allMetaclassInstVars metaclassInstVars classFormat allClassInstVars classInstVars newMeta class bookkeepingInfoStart bookkeepingInfoSize |
fullName := aCodeReader readByteSymbol.10
aCodeReader fileFormat >= 10
ifTrue:
[metaclassFormat := aCodeReader readLong.
numMetaInstVars := aCodeReader readLong.
allMetaclassInstVars := aCodeReader readByteStringCollection.
metaclassInstVars := allMetaclassInstVars
copyFrom: allMetaclassInstVars size - numMetaInstVars + 1
to: allMetaclassInstVars size.
classFormat := aCodeReader readLong.
numInstVars := aCodeReader readLong.
allClassInstVars := aCodeReader readByteStringCollection.
classInstVars := allClassInstVars copyFrom: allClassInstVars size - numInstVars + 1 to: allClassInstVars size]
ifFalse:
[metaclassFormat := aCodeReader readLong.
metaclassInstVars := aCodeReader readByteStringCollection.
numMetaInstVars := metaclassInstVars size.
classFormat := aCodeReader readLong.
classInstVars := aCodeReader readByteStringCollection.
numInstVars := classInstVars size].
11
Make class NewSubclassReader, a subclass of Object.
Make instance variables for arguments, receiver, and temporaries: aCodeReader aNameSpace superclass fullName numInstVars numMetaInstVars metaclassFormat allMetaclassInstVars metaclassInstVars classFormat allClassInstVars classInstVars newMeta class
12
readNewSubclassOn: aCodeReader in: aNameSpace
(NewSubclassReader on: aCodeReader in: aNameSpace) readNewSubclass
13
readNewSubclass
self initializeClassInformation.
self makeNewMetaclass.
self makeNewClass.
self isNewClassIncompatibleWithSuperclass ifTrue:
[CodeReader invalidClassFormatSignal
raiseWith: fullName
errorString: ' : ', fullName].
self checkShapeChange.
self readSubclassInfoFromCodeReader.
^class
14
Extract method
Turn an expression into a method of its own References to arguments or temporaries
turn into arguments of new method. References to instance variables don’t
change ^ in the expression can be a problem
15
Execute Around Method
Pairs of actions that must be taken together Open file / close file Start tag / end tag
aCursor showWhile: [ … ]
aFile openDuring: [ aThing printOn: aFile]
16
Simple Superclass NameWhat should we call the root of a hierarchy?
Complex name conveys full meaning.
Simple name is easy to say, type, extend.
But need to show that subclasses are related.
Simple Superclass Name
Give superclasses simple names: two or (preferably) one word
- Number
- Collection
- VisualComponent
Qualified Subclass Name
What should you call a subclass that plays a role similar to its superclass?
Unique name conveys most information
Derived name communicates relationship to superclass
Qualified Subclass NameUse names with obvious meaning. Otherwise,
prepend an adjective to most important superclass.
- OrderedCollection
- UndefinedObject
- CloneFigureCommand, CompositeCommand, ConnectionCommand
Variables: Roles vs. TypesTypes are specified by classes
aRectangle
aCollection
aView
Roles - how an object is used
location
employees
topView
Role Suggesting Instance Variable
What should you name an instance variable?
Type is important for understanding implementation. But class comment can describe type.
Role communicates intent, and this is harder to understand than type.
Role Suggesting Instance Variable
Name instance variables for the role they play. Make the name plural if the variable is a collection.
Point: x, y
Interval: start, stop, step
Polyline: vertices
Type Suggesting Parameter Name
Name of variable can either communicate type or role.
Keywords communicate their parameter's role, so name of variable should give new information.
Type Suggesting Parameter Name
Name parameters according to their most general expected class, preceded by "a" or "an". If there is more than one parameter with the same expected class, precede the class with a descriptive word.
Temporaries
Name temporaries after role they play.
Use temporaries to:
collect intermediate results
reuse result of an expression
name result of an expression
Methods are simpler when they don't use temporaries!
Class Comments
Every class should have a comment that describes the purpose of the class and the types of its instance variables
Method comments
Name of method should describe what it does.
Name of arguments should describe what they are.
Name of method should describe return type.
Method comment should describe anything else that isn’t obvious.
Common State
Different instances of a class have different values for some state. How do you represent it?
Declare an instance variable in the class.
Name the variable using Role Suggesting Instance Variable Name. Initialize it with either Lazy Initialization, Explicit Initialization, or a Constructor Parameter Method.
Explicit Initialization
How do you initialize instance variables to their default value?
Make the code readable instead of changeable.
Implement a method “initialize” that sets all the values. Override the class method “new” to invoke it on new instances.
Lazy Initialization
How do you initialize instance variables to their default value?
Emphasize ease of change.
Force all accesses to variable to go through accessing method. Make Getting method check whether the variable has been initialized and initialize it if necessary.
Lazy Initialization
Timer>>count
count isNil
ifTrue: [count := self defaultCount]
^count
Default Value Method
How do you represent the default value of a variable?
Create a method that returns the value. Prepend “default” to the name of the variable as the name of the method.
Constant Method
How do you code a constant?
Create a method that returns the constant.
How do you get and set an instance variable’s value?
Direct Variable Access: Access and set the variable directly.
Indirect Variable Access: Use a Getting Method and a Setting Method
Collection Accessor Method
How do you provide access to an instance variable that holds a collection?
Provide methods that delegate to the collection. To name the methods, add the name of the collection to the collection name.
addEmployee:
includesEmployee:
Enumeration Method
How do you provide access to collection elements?
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:”
employeesDo:
How to make a good program
Make it run the test casesMake it easy to understand, simple, follow
coding standards, and eliminate duplication.
It is OK to get the tests to run first, and then worry about making your program readable.
It is OK to make sure your program is always readable.
38
How to make a good program
It is not OK to hand in programs that are hard to understand, that don’t follow standard patterns, and that have a lot of duplication.
39