Patterns

39
Patterns 1

description

Patterns. Intention revealing selector Naming based on side effects Double-dispatching method Accessing methods Query methods Boolean property setting Converter methods Constructors. Composed Method. How big should a method be? Write methods that perform one identifiable task. - PowerPoint PPT Presentation

Transcript of Patterns

Page 1: Patterns

Patterns

1

Page 2: Patterns

Intention revealing selector

Naming based on side effects

Double-dispatching method

Accessing methods

Query methods

Boolean property setting

Converter methods

Constructors

2

Page 3: Patterns

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

Page 4: Patterns

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

Page 5: Patterns

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

Page 6: Patterns

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

Page 7: Patterns

Reversing method

Point

printOn: aStream

aStream

print: x;

nextPutAll: ‘ @’;

print: y

7

Page 8: Patterns

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

Page 9: Patterns

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

Page 10: Patterns

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

Page 11: Patterns

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

Page 12: Patterns

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

Page 13: Patterns

readNewSubclassOn: aCodeReader in: aNameSpace

(NewSubclassReader on: aCodeReader in: aNameSpace) readNewSubclass

13

Page 14: Patterns

readNewSubclass

self initializeClassInformation.

self makeNewMetaclass.

self makeNewClass.

self isNewClassIncompatibleWithSuperclass ifTrue:

[CodeReader invalidClassFormatSignal

raiseWith: fullName

errorString: ' : ', fullName].

self checkShapeChange.

self readSubclassInfoFromCodeReader.

^class

14

Page 15: Patterns

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

Page 16: Patterns

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

Page 17: Patterns

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.

Page 18: Patterns

Simple Superclass Name

Give superclasses simple names: two or (preferably) one word

- Number

- Collection

- VisualComponent

Page 19: Patterns

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

Page 20: Patterns

Qualified Subclass NameUse names with obvious meaning. Otherwise,

prepend an adjective to most important superclass.

- OrderedCollection

- UndefinedObject

- CloneFigureCommand, CompositeCommand, ConnectionCommand

Page 21: Patterns

Variables: Roles vs. TypesTypes are specified by classes

aRectangle

aCollection

aView

Roles - how an object is used

location

employees

topView

Page 22: Patterns

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.

Page 23: Patterns

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

Page 24: Patterns

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.

Page 25: Patterns

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.

Page 26: Patterns

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!

Page 27: Patterns

Class Comments

Every class should have a comment that describes the purpose of the class and the types of its instance variables

Page 28: Patterns

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.

Page 29: Patterns

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.

Page 30: Patterns

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.

Page 31: Patterns

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.

Page 32: Patterns

Lazy Initialization

Timer>>count

count isNil

ifTrue: [count := self defaultCount]

^count

Page 33: Patterns

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.

Page 34: Patterns

Constant Method

How do you code a constant?

Create a method that returns the constant.

Page 35: Patterns

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

Page 36: Patterns

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:

Page 37: Patterns

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:

Page 38: Patterns

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

Page 39: Patterns

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