0
Stéphane Ducasse 1
Stéphane Ducasse
stephane.ducasse@inria.fr
http://stephane.ducasse.free.fr/
Elements of Design -
Simple...
S.Ducasse 2
A Simple Case...
Introduce parametrization
Avoid recompilation
S.Ducasse 3
Parametrization Advantages
DialectStream>>initializeST80ColorTable
"Initialize the colors that characterize th...
S.Ducasse 4
One Step
DialectStream>>initializeST80ColorTable
ST80ColorTable := IdentityDictionary new.
self defaultDescrip...
S.Ducasse 5
Composition-based Solution
DialectStream>>initializeST80ColorTableWith: anArray
ST80ColorTable := IdentityDict...
S.Ducasse 6
Good Coding Practices
Good coding practices
promote good design
Encapsulation
Level of decomposition
Factoring...
S.Ducasse 7
Be lazy and be private
Never do the job that you can delegate to another
one
Never let someone else plays with...
S.Ducasse 8
The Programmer Manifesto
Say something only once
Don’t ask, tell!
S.Ducasse 9
Designing Classes for Reuse
Complete interface
Responsibility of the instance creation
Loose coupling between ...
S.Ducasse 10
Behavior up State down
Abstract class
Concrete subclasses
S.Ducasse 11
Say once and only once
No duplicated magic number
Extract method
Remove duplicated code
S.Ducasse 12
Factorize Magic Numbers
Ideally you should be able to change your constants
without having any impact on the ...
S.Ducasse 13
Factoring Out Constants
We want to encapsulate the way “no next node” is
coded. Instead of writing:
Node>>nex...
S.Ducasse 14
Factoring Out Constants
Write:
NodeClient>>transmitTo: aNode
aNode hasNextNode
....
Node>>hasNextNode
^ (self...
S.Ducasse 15
Default value between class and instance
If we want to encapsulate the way “no next node” is
coded and shared...
S.Ducasse 16
Initializing without Duplicating
Node>>initialize
accessType := ‘local’
...
Node>>isLocal
^ accessType = ‘loc...
S.Ducasse 17
Good Signs of OOThinking
Short methods
No dense methods
No super-intelligent objects
No manager objects
Objec...
S.Ducasse 18
How do you divide a program into methods?
Messages take time
Flow of control is difficult with small methods
...
S.Ducasse 19
Composed Methods
Divide your program into methods that perform one
identifiable task. Keep all of the operati...
S.Ducasse 20
Do you See the Problem?
initializeToStandAlone
super initializeToStandAlone.
self borderWidth: 2.
self border...
S.Ducasse 21
Do you See the Problem?
initializeToStandAlone
super initializeToStandAlone.
self initializeBoardLayout.
self...
S.Ducasse 22
With code reuse…
initializeArea
area := self matrixClass
rows: self rowNumber
columns: self columnNumber.
are...
S.Ducasse 23
About Methods
• Avoid long methods
• A method: one task
• Avoid duplicated code
• Reuse Logic
S.Ducasse 24
Class Design
S.Ducasse 25
Behavior Up and State Down
Define classes by behavior, not state
Implement behavior with abstract state: if y...
S.Ducasse 26
Example
Collection>>removeAll: aCollection
aCollection do: [:each | self remove: each]
^ aCollection
Collecti...
S.Ducasse 27
Behavior-Defined Class
When creating a new class, define its public protocol and
specify its behavior without...
S.Ducasse 28
Implement Behavior with Abstract State
If state is needed to complete the implementation
Identify the state b...
S.Ducasse 29
Identify Message Layers
How can methods be factored to make the class both
efficient and simple to subclass?
...
Upcoming SlideShare
Loading in...5
×

Stoop ed-class forreuse

221

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
221
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Stoop ed-class forreuse"

  1. 1. Stéphane Ducasse 1 Stéphane Ducasse stephane.ducasse@inria.fr http://stephane.ducasse.free.fr/ Elements of Design - Simple Smells Simple Smells
  2. 2. S.Ducasse 2 A Simple Case... Introduce parametrization Avoid recompilation
  3. 3. S.Ducasse 3 Parametrization Advantages DialectStream>>initializeST80ColorTable "Initialize the colors that characterize the ST80 dialect" ST80ColorTable := IdentityDictionary new. #((temporaryVariable blue italic) (methodArgument blue normal) … (setOrReturn black bold)) do: [:aTriplet | ST80ColorTable at: aTriplet first put: aTriplet allButFirst] Problems: Color tables hardcoded in method Changes Require compilation Client responsible of initialize invocation No run-time changes
  4. 4. S.Ducasse 4 One Step DialectStream>>initializeST80ColorTable ST80ColorTable := IdentityDictionary new. self defaultDescription do: [:aTriplet | ST80ColorTable at: aTriplet first put: aTriplet allButFirst] DialectStream>>defaultDescription ^ #((temporaryVariable blue italic) (methodArgument blue normal) … (setOrReturn black bold)) Still requires subclassing and recompilation
  5. 5. S.Ducasse 5 Composition-based Solution DialectStream>>initializeST80ColorTableWith: anArray ST80ColorTable := IdentityDictionary new. anArray do: [:aTriplet | ST80ColorTable at: aTriplet first put: aTriplet allButFirst]. self initialize •In a Client DialectStream initializeST80ColorTableWith: #(#(#temporaryVariable #blue #normal) … #(#prefixKeyword #veryDarkGray #bold) #(#setOrReturn #red #bold) )
  6. 6. S.Ducasse 6 Good Coding Practices Good coding practices promote good design Encapsulation Level of decomposition Factoring constants
  7. 7. S.Ducasse 7 Be lazy and be private Never do the job that you can delegate to another one Never let someone else plays with your private data The Object Manifesto
  8. 8. S.Ducasse 8 The Programmer Manifesto Say something only once Don’t ask, tell!
  9. 9. S.Ducasse 9 Designing Classes for Reuse Complete interface Responsibility of the instance creation Loose coupling between classes Methods are units of reuse (self send) Use polymorphism as much as possible to avoid type checking Behavior up and state down Use correct names for class Use correct names for methods
  10. 10. S.Ducasse 10 Behavior up State down Abstract class Concrete subclasses
  11. 11. S.Ducasse 11 Say once and only once No duplicated magic number Extract method Remove duplicated code
  12. 12. S.Ducasse 12 Factorize Magic Numbers Ideally you should be able to change your constants without having any impact on the code! For that define a constant only once via accessor provide testing method (hasNextNode) default value using the constant accessor
  13. 13. S.Ducasse 13 Factoring Out Constants We want to encapsulate the way “no next node” is coded. Instead of writing: Node>>nextNode ^ nextNode NodeClient>>transmitTo: aNode aNode nextNode = ‘no next node’ ...
  14. 14. S.Ducasse 14 Factoring Out Constants Write: NodeClient>>transmitTo: aNode aNode hasNextNode .... Node>>hasNextNode ^ (self nextNode = self class noNextNode) not Node class>>noNextNode ^ ‘no next node’
  15. 15. S.Ducasse 15 Default value between class and instance If we want to encapsulate the way “no next node” is coded and shared this knowledge between class and instances. Instead of writing: aNode nextNode isNil not Write: Node>>hasNextNode ^ self nextNode = self noNextNode Node>>noNextNode ^self class noNextNode Node class>>noNextNode ^ #noNode
  16. 16. S.Ducasse 16 Initializing without Duplicating Node>>initialize accessType := ‘local’ ... Node>>isLocal ^ accessType = ‘local’ It’s better to write Node>>initialize accessType := self localAccessType Node>>isLocal ^ accessType = self localAccessType Node>>localAccessType
  17. 17. S.Ducasse 17 Good Signs of OOThinking Short methods No dense methods No super-intelligent objects No manager objects Objects with clear responsibilities State the purpose of the class in one sentence Not too many instance variables
  18. 18. S.Ducasse 18 How do you divide a program into methods? Messages take time Flow of control is difficult with small methods But: Reading is improved Performance tuning is simpler (Cache...) Easier to maintain / inheritance impact Composed Methods
  19. 19. S.Ducasse 19 Composed Methods Divide your program into methods that perform one identifiable task. Keep all of the operations in a method at the same level of abstraction. Controller>>controlActivity self controlInitialize. self controlLoop. self controlTerminate
  20. 20. S.Ducasse 20 Do you See the Problem? initializeToStandAlone super initializeToStandAlone. self borderWidth: 2. self borderColor: Color black. self color: Color blue muchLighter. self extent: self class defaultTileSize * (self columnNumber @ self rowNumber). self initializeBots. self running. area := Matrix rows: self rowNumber columns: self columnNumber. area indicesDo: [:row :column | area at: row at: column put: OrderedCollection new]. self fillWorldWithGround. self firstArea. self installCurrentArea
  21. 21. S.Ducasse 21 Do you See the Problem? initializeToStandAlone super initializeToStandAlone. self initializeBoardLayout. self initializeBots. self running. self initializeArea. self fillWorldWithGround. self firstArea. self installCurrentArea
  22. 22. S.Ducasse 22 With code reuse… initializeArea area := self matrixClass rows: self rowNumber columns: self columnNumber. area indicesDo: [:row :column | area at: row at: column put: OrderedCollection new] initializeArea can be invoke several times
  23. 23. S.Ducasse 23 About Methods • Avoid long methods • A method: one task • Avoid duplicated code • Reuse Logic
  24. 24. S.Ducasse 24 Class Design
  25. 25. S.Ducasse 25 Behavior Up and State Down Define classes by behavior, not state Implement behavior with abstract state: if you need state do it indirectly via messages. Do not reference the state variables directly Identify message layers: implement class’s behavior through a small set of kernel method
  26. 26. S.Ducasse 26 Example Collection>>removeAll: aCollection aCollection do: [:each | self remove: each] ^ aCollection Collection>>remove: oldObject self remove: oldObject ifAbsent: [self notFoundError] Collection>>remove: anObject ifAbsent: anExceptionBlock self subclassResponsibility
  27. 27. S.Ducasse 27 Behavior-Defined Class When creating a new class, define its public protocol and specify its behavior without regard to data structure (such as instance variables, class variables, and so on). For example: Rectangle Protocol: area intersects: contains: perimeter width height insetBy:
  28. 28. S.Ducasse 28 Implement Behavior with Abstract State If state is needed to complete the implementation Identify the state by defining a message that returns that state instead of defining a variable. For example, use Circle>>area ^self radius squared * self pi not Circle>>area ^radius squared * pi.
  29. 29. S.Ducasse 29 Identify Message Layers How can methods be factored to make the class both efficient and simple to subclass? Identify a small subset of the abstract state and behavior methods which all other methods can rely on as kernel methods. Circle>>radius Circle>>pi Circle>>center Circle>>diameter ^self radius * 2 Circle>>area ^self radius squared * self pi
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×