Top Banner
“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

“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.

Dec 19, 2015

Download

Documents

Welcome message from author
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
Page 1: “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.

• “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)

Page 2: “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.

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”)

Page 3: “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.

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

Page 4: “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.

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

Page 5: “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.

“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

Page 6: “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.

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

Page 7: “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.

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(); }

protected: virtual void acquireLock() { // acquire lock } virtual void releaseLock() { // release lock }

virtual int directRead() = 0; virtual void directWrite(int n) = 0;

}; // end of class SyncReadWrite

Page 8: “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.

Multiple inheritance example in C++: code duplication in child classes

class SyncA : public A, SyncReadWrite { public: virtual int read() { return SyncReadWrite::read(); } virtual void write(int n) { SyncReadWrite::write(n); }protected: virtual int directRead() { return A::read(); } virtual void directWrite(int n) { A::write(n); }}; // end of class SyncA

class SyncB : public B, SyncReadWrite { public: virtual int read() { return SyncReadWrite::read(); } virtual void write(int n) { SyncReadWrite::write(n); }protected: virtual int directRead() { return B::read(); } virtual void directWrite(int n) { B::write(n); }}; // end of class SyncB

Code duplication

Page 9: “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.

Let’s mix it!

• A mixin is an (abstract subclass) specification– may be applied to various classes to extend them with

the same set of features

• Key idea: create components designed for reuse rather than for instantiation

• Implementation– C++ – using templates– Java – using (multiple inheritance of) interfaces– Smalltalk – language extension using a mixin

invocation operator

Page 10: “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.

Mixin example

Rectangle

asString

asString

^ super asString, ‘ ‘, self color asString

Rectangle + MColor

asStringserializeOn:

MColor

asString

serializeOn:

Rectangle + MColor + MBorder

asStringserializeOn:

MyRectangle

asString

^ super asString, ‘ ‘, self borderWidth asString

MBorder

asString

serializeOn:

Page 11: “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.

Mixins are not a panacea

Problems? You bet!– It is impossible to control how individual

features are composed– Composition of mixins is messy

• Mixins applied later in the chain (silently) override identically named features of earlier mixins

• Reestablishing the original behavior requires changes in other mixins

– Modifying a mixin used in several places in a class hierarchy may be particularly unpleasant

Page 12: “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.

Mixins in C++: no multiple inheritance

template <class Super>class MSyncReadWrite : public Super {public: virtual int read() { acquireLock(); result = Super::read(); releaseLock(); return result; } virtual void write(int n) { acquireLock(); Super::write(n); releaseLock(); }

protected: virtual void acquireLock() { // acquire lock } virtual void releaseLock() { // release lock }}; // end of MSyncReadWrite

class SyncA : public MSyncReadWrite<A> {};class SyncB : public MSyncReadWrite<B> {};

Page 13: “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.

Introduction to traits

• Lightweight software components– Basic building blocks for classes– Primitive units of code reuse

• A trait provides methods that implement behavior

• A trait requires methods that parameterize the provided behavior (optional)– Required methods are used by – not

implemented in – a trait

Page 14: “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.

Sample traits

TCircle

=hash<<=…areaboundscircumferencescaleBy:…

centercenter:radiusradius:

TDrawing

drawrefreshrefreshOn:

boundsdrawOn:

Geometry-related behavior Drawing-related behavior

Page 15: “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.

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

Page 16: “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.

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

Page 17: “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.

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

Page 18: “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.

Class = Superclass +State + Traits + Glue methods

TCircle

=hash<<=…areaboundscircumferencescaleBy:…

centercenter:radiusradius:

TDrawing

drawrefreshrefreshOn:

boundsdrawOn:

Circle

initializedrawOn:centercenter:radiusradius:

Page 19: “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.

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

Page 20: “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.

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.

Page 21: “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.

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.

Page 22: “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.

Nested traits

TCircle

<=hash

TGeometry

areaboundsscaleBy:…

centercenter:radiusradius:

TMagnitude

<=>between:and:

<

TEquality

~= =hash

Page 23: “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.

Flattened nested traits

TCircle

<=hash

areaboundsscaleBy:…

centercenter:radiusradius:

<=>between:and:

~=

Page 24: “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.

More nested traits

TEquality

~= =hash

TColorredgreensaturationred:…=hash

rgbrgb:

Page 25: “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.

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

superclass methods (flattening property!)

Page 26: “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.

Method conflicts

TCircle

=hash~=…areaboundscircumferencescaleBy:…

centercenter:radiusradius:

TDrawing

drawrefreshrefreshOn:

boundsdrawOn:

Circleinitialize=hashrgbrgb:drawOn:centercenter:radiusradius:

TColor

=hash~=red…

rgbrgb:

TEquality

~= =hash

Page 27: “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.

traits: { TCircle @ { #circleHash -> #hash. #circleEqual: -> #= } }

Conflict resolution

• Conflicts must be explicitly resolved – Conflicting methods are excluded, and turned

into required ones

• Possible ways to resolve a conflict:– Define an overriding method in the class or in

the composite trait– Rename conflicting methods (aliasing)– Avoid a conflict by explicitly excluding some

methodstraits: { TCircle . TDrawing . TColor - { #=. #hash. #~=. } }

Page 28: “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.

C++ RevisitedDocument

MSyncReadWrite<MLogOpenClose<Document> >

MLogOpenClose<Document>

MyDocument

Document

TLogOpenClose<Document>

MyDocument

TSyncReadWrite<Document>

virtual

Page 29: “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.

Traits in C++template <class Super>class TLogOpenClose : virtual public Super {public: virtual void open() { … } virtual void close() { … } virtual void reset() { … }

protected: virtual void log(const char* s) { … }}; // end of TLogOpenClose

template <class Super>class TSyncReadWrite : virtual public Super {public: virtual void read() { … } virtual void write(int n) { … } virtual void reset() { … }

protected: virtual void acquireLock() { … } virtual void releaseLock() { … }}; // end of TSyncReadWrite

class MyDocument : public TLogOpenClose<Document>, public TSyncReadWrite<Document> { … // glue code};

Page 30: “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.

Traits in C++: what we can and cannot do

• Nested traitstemplate <class Super>

class TLogAndSync

: virtual public TLogOpenClose<Super>,

virtual public TSyncReadWrite<Super> { };

• Composition of traits– Sum … OK– Aliasing … can be simulated using scope operator ::– Exclusion … nope

• Every conflict must be resolved by overriding the conflicting methods

Page 31: “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.

Review of trait properties• Untangling reusability and classes

– Classes are instance generators and hence have to be complete

– Units of reuse should be small

• Trait composition operates at a finer granularity than inheritance– Single inheritance is retained– Flattening property

• Conflicting features– Methods only, no state– If the same method from the same trait is obtained via

multiple paths, there is no conflict

Page 32: “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.

Evaluation against identified problems: code duplication

Stream

positionposition:

WriteStream

nextPut:position:

ReadStream

next

ReadWriteStream

next

Code duplication

Page 33: “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.

Stream hierarchy refactored using traits

Stream

positionposition:

WriteStreamReadStream ReadWriteStream

TReadStream TReadStreamTWriteStream

TWriteStream

Page 34: “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.

Evaluation against identified problems: duplicated wrappers

Like mixins, traits can explicitly refer to a method implemented by the superclass

B

readwrite:

A

readwrite:

SyncReadWrite

readwrite:acquireLockreleaseLock

SyncA SyncB

TSyncReadWrite

readwrite:acquireLockreleaseLock

readwrite:

A

readwrite:

SyncA

Page 35: “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.

Mixin example (revisited)

Rectangle

asString

asString

^ super asString, ‘ ‘, self color asString

Rectangle + MColor

asStringserializeOn:

MColor

asString

serializeOn:

Rectangle + MColor + MBorder

asStringserializeOn:

MyRectangle

asString

^ super asString, ‘ ‘, self borderWidth asString

MBorder

asString

serializeOn:

Page 36: “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.

Evaluation against identified problems: composition

• Total ordering– Trait composition does not impose total

ordering

• Dispersal of glue code– Glue code is always located in the combining

entity• The superordinate entity is in complete charge of

plugging together the components that implement its features

– Glue code is separated from the implementation of features

Page 37: “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.

Traits offer more control

Rectangle

asString

MyRectangle

TColor

asStringserializeOn:

TBorder

asStringserializeOn:

Glue code

Page 38: “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.

Evaluation against identified problems: fragile hierarchies

• Every method conflict must be resolved explicitly– This requires extra work …

• but you always get what you expect

• Changes mandated by conflict resolution are limited to the direct users of the trait– A direct client can simply exclude a new trait method

• Not so with mixins– introducing a new method may require changes to

many other components or addition of new components