• “Traits: Composable Units of Behavior” N. Schaerli, S. Ducasse, O. Nierstrasz, and A. Black, U Bern / OHSU, ECOOP 2003 • “Traits: A Mechanism for Fine-grained Reuse” S. Ducasse, O. Nierstrasz, N. Schaerli, R. Wuyts, and A. Black, ACM TOPLAS (forthcoming) Presented by Evgeniy Gabrilovich Traits Traits are primitive units of code reuse that consist only of methods (i.e., no state)
38
Embed
“Traits: Composable Units of Behavior” N. Schaerli, S. Ducasse, O. Nierstrasz, and A. Black, U Bern / OHSU, ECOOP 2003 “Traits: A Mechanism for Fine-grained.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
• “Traits: Composable Units of Behavior”N. Schaerli, S. Ducasse, O. Nierstrasz, andA. Black, U Bern / OHSU, ECOOP 2003
• “Traits: A Mechanism for Fine-grained Reuse”S. Ducasse, O. Nierstrasz, N. Schaerli, R. Wuyts, and A. Black, ACM TOPLAS (forthcoming)
Presented by Evgeniy Gabrilovich
Traits
Traits are primitive units of code reuse that consist only of
methods(i.e., no state)
The quest for better reuse mechanisms
• Common forms of inheritance– Single / multiple / mixin inheritance
• Limitations of the different forms of inheritance• Traits, traits, traits …
– Introduction to traits– Usage examples– Discussion of trait properties– Implementation
• Smalltalk-80, Scala, C#/Rotor, Perl 6 (“roles”)
Key observation about reuse
• A class is not necessarily an appropriate element of reuse
• Two contradictory roles of classes– Generator of instances
A class must be completeEach class should have a unique place in the
class hierarchy
– Unit of reuseA class should be smallUnits of reuse should be applicable at numerous
arbitrary places
Single inheritance• Not expressive enough for factoring out
common features shared by classes in a complex hierarchy– Code duplication
• Smalltalk example
ReadStream WriteStream
ReadWriteStream
?
ReadStream WriteStream
ReadWriteStream
Code duplication
PositionableStream
read + write
functions
“Multiple inheritance is good, but there is no good way to do it” (Steve Cook, OOPSLA’87)
Problem #1: Conflicting features that are
inherited along different paths
– Conflicting methods• Can be resolved by overriding
– Conflicting state variables
A
B
D
C
Problem #2: Limited compositional power
A
readwrite:
B
readwrite:
A
readwrite:
SyncA
readwrite:acquireLockreleaseLock
read self acquireLock res := super read self releaseLock ^ res
write: val self acquireLock super write: val self releaseLock
SyncReadWrite
readwrite:acquireLockreleaseLock
SyncA SyncB
Multiple inheritance example in C++: base class with abstract methods
class SyncReadWrite { public: virtual int read() { acquireLock(); result = directRead(); releaseLock(); return result; } virtual void write(int n) { acquireLock(); directWrite(n); releaseLock(); }
Sample trait implementation in (an extension of) Smalltalk
Trait named: #TDrawing uses: {}
draw ^ self drawOn: World canvas
refresh ^ self refreshOn: World canvas
refreshOn: …
bounds self requirement
drawOn: aCanvas self requirement
Trait composition
• Classes are composed from traits– Provide required methods– Resolved conflicts due to trait composition
• Traits can be nested– The semantics for the containing class is not
nested– Traits are inlined
• Nested traits are equivalent to flattened traits
Addressing known problems
• Traits specify no state– Methods provided by traits never access state
variable directly• Only using required methods
– Can only cause method conflicts• Can be resolved by overriding or by exclusion
• Traits are detached from the inheritance hierarchy
• Traits are not composed in any particular order
Class = Superclass +State + Traits + Glue methods
TCircle
=hash<<=…areaboundscircumferencescaleBy:…
centercenter:radiusradius:
TDrawing
drawrefreshrefreshOn:
boundsdrawOn:
Circle
initializedrawOn:centercenter:radiusradius:
Sample class using traitsObject subclass: #Circle instanceVariableNames: ‘center radius’ traits: {TCircle . TDrawing}
initialize center := 0@0. radius := 50 center ^ center radius ^ radius
drawOn: aCanvas …
center: aPoint
center := aPoint
radius: aNumber
radius := aNumber
Completing a class definition
• In order for a class to be complete, all the requirements of the traits must be satisfied
• These methods can be implemented– in the class itself,– in a direct or indirect superclass,– by another trait that is used by the class.
The flattening property
The semantics of a method defined in a trait is identical to the semantics of the same method defined in a class that uses the trait. – The keyword super has no special semantics
for traits– super simply refers to the superclass of the
class that uses the trait.
Nested traits
TCircle
<=hash
TGeometry
areaboundsscaleBy:…
centercenter:radiusradius:
TMagnitude
<=>between:and:
<
TEquality
~= =hash
Flattened nested traits
TCircle
<=hash
areaboundsscaleBy:…
centercenter:radiusradius:
<=>between:and:
~=
More nested traits
TEquality
~= =hash
TColorredgreensaturationred:…=hash
rgbrgb:
Lack of composition order
• The order of trait composition is irrelevant
Conflicting trait methods must be explicitly disambiguated
• Precedence rules for conflict resolution– Class methods take precedence over trait
methods (= overriding trait methods)– Traits methods take precedence over