based on metz chapter 8: combining objects with...

40
Composition Based on Metz Chapter 8: Combining Objects with Composition 1

Upload: others

Post on 21-Aug-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Composition

Based on Metz Chapter 8: Combining Objects with Composition

1

Page 2: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

What is Composition?

• Objects respond to requests

• How?✦ they have their own methods✦ they “pass the buck” to another object:

forwarding to a component✦ they acquire behavior from another object:

delegation

2

Page 3: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

The Gang of Four say:

3

• The first principle of object-oriented design:‣ Program to an interface, not to an

implementation

• The second principle of object-oriented design:‣ Favor object composition over inheritance

Page 4: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

The Gang of Four say:

3

• The first principle of object-oriented design:‣ Program to an interface, not to an

implementation

• The second principle of object-oriented design:‣ Favor object composition over inheritance

• The first principle of object-oriented design:‣ Program to an interface, not to an

implementation

• The second principle of object-oriented design:‣ Favor object composition over inheritance

Page 5: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Inheritance vs. Composition• Inheritance lets us quickly create a

specialization of an existing object ‣ all we need do is program the differences

• But inheritance is not a panacea:‣ the extension must be prepared in advance, as

a new class or factory

‣ the kind of extension can’t be changed at runtime

‣ with single inheritance, you have just one shot 4

Page 6: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Costs of Inheritance• What happens when you get it wrong?

• Reasonable, usable and Exemplary are coins with two sides!‣ ¬ reasonable: making changes near the top of

an incorrectly-modeled hierarchy

‣ ¬ usable: recumbentMountainBike (or immutableSet) can’t be built

‣ ¬ exemplary: can’t extend an incorrectly-modeled hierarchy

5

Page 7: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Composition• Pros‣ component can be changed at runtime

° e.g., state pattern

‣ clear separation of responsibilities° need know only the interface of the component

• Cons‣ more work

° define separate classes for part, parts ...

‣ delegation not supported by most languages° must use self delegation pattern (Beck, p.67)

6

Page 8: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Metz:• Inheritance:‣ for the cost of arranging objects in a hierarchy, you get

message delegation for free

• Composition:‣ reverses these costs & benefits:

° not restricted to a hierarchy; objects relationships are explicit

° delegation of messages must also be explicit

• when faced with a problem that composition can solve, you should be biased towards using composition

7

Page 9: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Composing a Bicycle from Parts

Page 10: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

9

Bicycle with Inheritance from

Chapter 6

Page 11: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

9

Bicycle with Inheritance from

Chapter 6

ptg11539634

Some object-oriented programming languages have syntax that allows you toexplicitly declare classes as abstract. Java, for example, has the abstract keyword.The Java compiler itself prevents creation of instances of classes to which this keywordhas been applied. Ruby, in line with its trusting nature, contains no such keyword andenforces no such restriction. Only good sense prevents other programmers fromcreating instances of Bicycle; in real life, this works remarkably well.

Abstract classes exist to be subclassed. This is their sole purpose. They provide acommon repository for behavior that is shared across a set of subclasses—subclassesthat in turn supply specializations.

It almost never makes sense to create an abstract superclass with only one sub-class. Even though the original Bicycle class contains general and specific behaviorand it’s possible to imagine modeling it as two classes from the very beginning, donot. Regardless of how strongly you anticipate having other kinds of bikes, that daymay never come. Until you have a specific requirement that forces you to deal withother bikes, the current Bicycle class is good enough.

Even though you now have a requirement for two kinds of bikes, this still may notbe the right moment to commit to inheritance. Creating a hierarchy has costs; the bestway to minimize these costs is to maximize your chance of getting the abstraction rightbefore allowing subclasses to depend on it. While the two bikes you know about supplya fair amount of information about the common abstraction, three bikes would supplya great deal more. If you could put this decision off until FastFeet asked for a third kindof bike, your odds of finding the right abstraction would improve dramatically.

A decision to put off the creation of the Bicycle hierarchy commits you to writingMountainBike and RoadBike classes that duplicate a great deal of code. A decision toproceed with the hierarchy accepts the risk that you may not yet have enough informa-tion to identify the correct abstraction. Your choice about whether to wait or to proceed

118 Chapter 6. Acquiring Behavior Through Inheritance

Bicycle

MountainBike RoadBike

Figure 6.6 Bicycle as the superclass of MountainBike and RoadBike.

Page 12: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

9

Bicycle with Inheritance from

Chapter 6

Page 13: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

9

Bicycle with Inheritance from

Chapter 6

What’s the major responsibility of a

bicycle object?

Page 14: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• What’s the major responsibility of a bicycle object?

• To respond to the spares request with a collection of spare parts

• Bicycles have parts; this feels like a bicycle should be composed of parts

• So, let’s create a parts object • bicycles will delegate responsibility for

spares to their parts

10

Page 15: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• bicycles will delegate responsibility for spares to their parts

ptg11539634

Composing a Bicycle of PartsThis section begins where the Bicycle example in Chapter 6, Acquiring BehaviorThrough Inheritance, ended. If that code is no longer in the forefront of your mind, it’sworth flipping back to the end of Chapter 6 and refreshing your memory. This sectiontakes that example and moves it through several refactorings, gradually replacinginheritance with composition.

Updating the Bicycle ClassThe Bicycle class is currently an abstract superclass in an inheritance hierarchy andyou’d like to convert it to use composition. The first step is to ignore the existing codeand think about how a bicycle should be composed.

The Bicycle class is responsible for responding to the spares message. Thisspares message should return a list of spare parts. Bicycles have parts, the bicycle–partsrelationship quite naturally feels like composition. If you created an object to hold all ofa bicycle’s parts, you could delegate the spares message to that new object.

It’s reasonable to name this new class Parts. The Parts object can be responsiblefor holding a list of the bike’s parts and for knowing which of those parts needs spares.Notice that this object represents a collection of parts, not a single part.

The sequence diagram in Figure 8.1 illustrates this idea. Here, a Bicycle sendsthe spares message to its Parts object.

Every Bicycle needs a Parts object; part of what it means to be a Bicycle is tohave-a Parts. The class diagram in Figure 8.2 illustrates this relationship.

164 Chapter 8. Combining Objects with Composition

Figure 8.1 A Bicycle asks Parts for spares.

a Bicycle the Parts

a Bicycle the Parts

spares

Bicycle Parts1

Figure 8.2 A Bicycle has-a Parts.

spares

Page 16: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• bicycles will delegate responsibility for spares to their parts

ptg11539634

Composing a Bicycle of PartsThis section begins where the Bicycle example in Chapter 6, Acquiring BehaviorThrough Inheritance, ended. If that code is no longer in the forefront of your mind, it’sworth flipping back to the end of Chapter 6 and refreshing your memory. This sectiontakes that example and moves it through several refactorings, gradually replacinginheritance with composition.

Updating the Bicycle ClassThe Bicycle class is currently an abstract superclass in an inheritance hierarchy andyou’d like to convert it to use composition. The first step is to ignore the existing codeand think about how a bicycle should be composed.

The Bicycle class is responsible for responding to the spares message. Thisspares message should return a list of spare parts. Bicycles have parts, the bicycle–partsrelationship quite naturally feels like composition. If you created an object to hold all ofa bicycle’s parts, you could delegate the spares message to that new object.

It’s reasonable to name this new class Parts. The Parts object can be responsiblefor holding a list of the bike’s parts and for knowing which of those parts needs spares.Notice that this object represents a collection of parts, not a single part.

The sequence diagram in Figure 8.1 illustrates this idea. Here, a Bicycle sendsthe spares message to its Parts object.

Every Bicycle needs a Parts object; part of what it means to be a Bicycle is tohave-a Parts. The class diagram in Figure 8.2 illustrates this relationship.

164 Chapter 8. Combining Objects with Composition

Figure 8.1 A Bicycle asks Parts for spares.

a Bicycle the Parts

a Bicycle the Parts

spares

Bicycle Parts1

Figure 8.2 A Bicycle has-a Parts.relationship

spares

Page 17: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• bicycles will delegate responsibility for spares to their parts

ptg11539634

Composing a Bicycle of PartsThis section begins where the Bicycle example in Chapter 6, Acquiring BehaviorThrough Inheritance, ended. If that code is no longer in the forefront of your mind, it’sworth flipping back to the end of Chapter 6 and refreshing your memory. This sectiontakes that example and moves it through several refactorings, gradually replacinginheritance with composition.

Updating the Bicycle ClassThe Bicycle class is currently an abstract superclass in an inheritance hierarchy andyou’d like to convert it to use composition. The first step is to ignore the existing codeand think about how a bicycle should be composed.

The Bicycle class is responsible for responding to the spares message. Thisspares message should return a list of spare parts. Bicycles have parts, the bicycle–partsrelationship quite naturally feels like composition. If you created an object to hold all ofa bicycle’s parts, you could delegate the spares message to that new object.

It’s reasonable to name this new class Parts. The Parts object can be responsiblefor holding a list of the bike’s parts and for knowing which of those parts needs spares.Notice that this object represents a collection of parts, not a single part.

The sequence diagram in Figure 8.1 illustrates this idea. Here, a Bicycle sendsthe spares message to its Parts object.

Every Bicycle needs a Parts object; part of what it means to be a Bicycle is tohave-a Parts. The class diagram in Figure 8.2 illustrates this relationship.

164 Chapter 8. Combining Objects with Composition

Figure 8.1 A Bicycle asks Parts for spares.

a Bicycle the Parts

a Bicycle the Parts

spares

Bicycle Parts1

Figure 8.2 A Bicycle has-a Parts.

spares

Page 18: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• bicycles will delegate responsibility for spares to their parts

ptg11539634

Composing a Bicycle of PartsThis section begins where the Bicycle example in Chapter 6, Acquiring BehaviorThrough Inheritance, ended. If that code is no longer in the forefront of your mind, it’sworth flipping back to the end of Chapter 6 and refreshing your memory. This sectiontakes that example and moves it through several refactorings, gradually replacinginheritance with composition.

Updating the Bicycle ClassThe Bicycle class is currently an abstract superclass in an inheritance hierarchy andyou’d like to convert it to use composition. The first step is to ignore the existing codeand think about how a bicycle should be composed.

The Bicycle class is responsible for responding to the spares message. Thisspares message should return a list of spare parts. Bicycles have parts, the bicycle–partsrelationship quite naturally feels like composition. If you created an object to hold all ofa bicycle’s parts, you could delegate the spares message to that new object.

It’s reasonable to name this new class Parts. The Parts object can be responsiblefor holding a list of the bike’s parts and for knowing which of those parts needs spares.Notice that this object represents a collection of parts, not a single part.

The sequence diagram in Figure 8.1 illustrates this idea. Here, a Bicycle sendsthe spares message to its Parts object.

Every Bicycle needs a Parts object; part of what it means to be a Bicycle is tohave-a Parts. The class diagram in Figure 8.2 illustrates this relationship.

164 Chapter 8. Combining Objects with Composition

Figure 8.1 A Bicycle asks Parts for spares.

a Bicycle the Parts

a Bicycle the Parts

spares

Bicycle Parts1

Figure 8.2 A Bicycle has-a Parts.composition relationship

spares

Page 19: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• bicycles will delegate responsibility for spares to their parts

ptg11539634

Composing a Bicycle of PartsThis section begins where the Bicycle example in Chapter 6, Acquiring BehaviorThrough Inheritance, ended. If that code is no longer in the forefront of your mind, it’sworth flipping back to the end of Chapter 6 and refreshing your memory. This sectiontakes that example and moves it through several refactorings, gradually replacinginheritance with composition.

Updating the Bicycle ClassThe Bicycle class is currently an abstract superclass in an inheritance hierarchy andyou’d like to convert it to use composition. The first step is to ignore the existing codeand think about how a bicycle should be composed.

The Bicycle class is responsible for responding to the spares message. Thisspares message should return a list of spare parts. Bicycles have parts, the bicycle–partsrelationship quite naturally feels like composition. If you created an object to hold all ofa bicycle’s parts, you could delegate the spares message to that new object.

It’s reasonable to name this new class Parts. The Parts object can be responsiblefor holding a list of the bike’s parts and for knowing which of those parts needs spares.Notice that this object represents a collection of parts, not a single part.

The sequence diagram in Figure 8.1 illustrates this idea. Here, a Bicycle sendsthe spares message to its Parts object.

Every Bicycle needs a Parts object; part of what it means to be a Bicycle is tohave-a Parts. The class diagram in Figure 8.2 illustrates this relationship.

164 Chapter 8. Combining Objects with Composition

Figure 8.1 A Bicycle asks Parts for spares.

a Bicycle the Parts

a Bicycle the Parts

spares

Bicycle Parts1

Figure 8.2 A Bicycle has-a Parts.

spares

Page 20: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• bicycles will delegate responsibility for spares to their parts

ptg11539634

Composing a Bicycle of PartsThis section begins where the Bicycle example in Chapter 6, Acquiring BehaviorThrough Inheritance, ended. If that code is no longer in the forefront of your mind, it’sworth flipping back to the end of Chapter 6 and refreshing your memory. This sectiontakes that example and moves it through several refactorings, gradually replacinginheritance with composition.

Updating the Bicycle ClassThe Bicycle class is currently an abstract superclass in an inheritance hierarchy andyou’d like to convert it to use composition. The first step is to ignore the existing codeand think about how a bicycle should be composed.

The Bicycle class is responsible for responding to the spares message. Thisspares message should return a list of spare parts. Bicycles have parts, the bicycle–partsrelationship quite naturally feels like composition. If you created an object to hold all ofa bicycle’s parts, you could delegate the spares message to that new object.

It’s reasonable to name this new class Parts. The Parts object can be responsiblefor holding a list of the bike’s parts and for knowing which of those parts needs spares.Notice that this object represents a collection of parts, not a single part.

The sequence diagram in Figure 8.1 illustrates this idea. Here, a Bicycle sendsthe spares message to its Parts object.

Every Bicycle needs a Parts object; part of what it means to be a Bicycle is tohave-a Parts. The class diagram in Figure 8.2 illustrates this relationship.

164 Chapter 8. Combining Objects with Composition

Figure 8.1 A Bicycle asks Parts for spares.

a Bicycle the Parts

a Bicycle the Parts

spares

Bicycle Parts1

Figure 8.2 A Bicycle has-a Parts.

one parts object per

bicycle

spares

Page 21: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

• bicycles will delegate responsibility for spares to their parts

ptg11539634

Composing a Bicycle of PartsThis section begins where the Bicycle example in Chapter 6, Acquiring BehaviorThrough Inheritance, ended. If that code is no longer in the forefront of your mind, it’sworth flipping back to the end of Chapter 6 and refreshing your memory. This sectiontakes that example and moves it through several refactorings, gradually replacinginheritance with composition.

Updating the Bicycle ClassThe Bicycle class is currently an abstract superclass in an inheritance hierarchy andyou’d like to convert it to use composition. The first step is to ignore the existing codeand think about how a bicycle should be composed.

The Bicycle class is responsible for responding to the spares message. Thisspares message should return a list of spare parts. Bicycles have parts, the bicycle–partsrelationship quite naturally feels like composition. If you created an object to hold all ofa bicycle’s parts, you could delegate the spares message to that new object.

It’s reasonable to name this new class Parts. The Parts object can be responsiblefor holding a list of the bike’s parts and for knowing which of those parts needs spares.Notice that this object represents a collection of parts, not a single part.

The sequence diagram in Figure 8.1 illustrates this idea. Here, a Bicycle sendsthe spares message to its Parts object.

Every Bicycle needs a Parts object; part of what it means to be a Bicycle is tohave-a Parts. The class diagram in Figure 8.2 illustrates this relationship.

164 Chapter 8. Combining Objects with Composition

Figure 8.1 A Bicycle asks Parts for spares.

a Bicycle the Parts

a Bicycle the Parts

spares

Bicycle Parts1

Figure 8.2 A Bicycle has-a Parts.

spares

Page 22: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

12

Bicycles with Parts

Page 23: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

13

Bicycles with Parts

Page 24: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Hierarchy (after Fig 8.3)

14

bicycle.withSize(sz) parts(p)

bicycle.parts(p)

roadBike.parts(p)mountainBike

.parts(p)

1

Page 25: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

The result

• Most code from bicycle moves into parts ‣ Metz: wasn’t a big change, and isn’t much of an

improvement

‣ made it blindingly obvious just how little Bicycle specific code there was to begin with

‣ Most of the code … deals with individual parts; the Parts hierarchy now cries out for another refactoring.

15

Page 26: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Composing the Parts Object

16

ptg11539634Creating a PartFigure 8.4 shows a new sequence diagram that illustrates the conversation betweenBicycle and its Parts object, and between a Parts object and its Part objects.Bicycle sends spares to Parts and then the Parts object sends needs_spare toeach Part.

Changing the design in this way requires creating a new Part object. The Partsobject is now composed of Part objects, as illustrated by the class diagram in Figure 8.5.The “1..*” on the line near Part indicates that a Parts will have one or more Partobjects.

Introducing this new Part class simplifies the existing Parts class, which nowbecomes a simple wrapper around an array of Part objects. Parts can filter its list ofPart objects and return the ones that need spares. The code below shows threeclasses: the existing Bicycle class, the updated Parts class, and the newly introducedPart class.

1 class Bicycle2 attr_reader :size, :parts34 def initialize(args={})5 @size = args[:size]6 @parts = args[:parts]

169Composing the Parts Object

a Bicycle

spares

needs_spare

the Parts a Part

a Bicycle the Parts a Part

Figure 8.4 Bicycle sends spares to Parts, Parts sends needs_spare to each Part.

Bicycle Parts1

Part1..*

Figure 8.5 Bicycle holds one Parts object, which in turn holds many Part objects.

Page 27: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Composing the Parts Object

16

ptg11539634Creating a PartFigure 8.4 shows a new sequence diagram that illustrates the conversation betweenBicycle and its Parts object, and between a Parts object and its Part objects.Bicycle sends spares to Parts and then the Parts object sends needs_spare toeach Part.

Changing the design in this way requires creating a new Part object. The Partsobject is now composed of Part objects, as illustrated by the class diagram in Figure 8.5.The “1..*” on the line near Part indicates that a Parts will have one or more Partobjects.

Introducing this new Part class simplifies the existing Parts class, which nowbecomes a simple wrapper around an array of Part objects. Parts can filter its list ofPart objects and return the ones that need spares. The code below shows threeclasses: the existing Bicycle class, the updated Parts class, and the newly introducedPart class.

1 class Bicycle2 attr_reader :size, :parts34 def initialize(args={})5 @size = args[:size]6 @parts = args[:parts]

169Composing the Parts Object

a Bicycle

spares

needs_spare

the Parts a Part

a Bicycle the Parts a Part

Figure 8.4 Bicycle sends spares to Parts, Parts sends needs_spare to each Part.

Bicycle Parts1

Part1..*

Figure 8.5 Bicycle holds one Parts object, which in turn holds many Part objects.

one or more part objects per parts

object

Page 28: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Composing the Parts Object

16

ptg11539634Creating a PartFigure 8.4 shows a new sequence diagram that illustrates the conversation betweenBicycle and its Parts object, and between a Parts object and its Part objects.Bicycle sends spares to Parts and then the Parts object sends needs_spare toeach Part.

Changing the design in this way requires creating a new Part object. The Partsobject is now composed of Part objects, as illustrated by the class diagram in Figure 8.5.The “1..*” on the line near Part indicates that a Parts will have one or more Partobjects.

Introducing this new Part class simplifies the existing Parts class, which nowbecomes a simple wrapper around an array of Part objects. Parts can filter its list ofPart objects and return the ones that need spares. The code below shows threeclasses: the existing Bicycle class, the updated Parts class, and the newly introducedPart class.

1 class Bicycle2 attr_reader :size, :parts34 def initialize(args={})5 @size = args[:size]6 @parts = args[:parts]

169Composing the Parts Object

a Bicycle

spares

needs_spare

the Parts a Part

a Bicycle the Parts a Part

Figure 8.4 Bicycle sends spares to Parts, Parts sends needs_spare to each Part.

Bicycle Parts1

Part1..*

Figure 8.5 Bicycle holds one Parts object, which in turn holds many Part objects.

Page 29: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Should the Parts object be like a List?

17

Page 30: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

18

Delegation

• Delegation allows you to share implementation without inheritance

• Pass part of your work on to another object. Put that object in one of your instance variables‣ e.g., a Path contains a field form, the bit mask

responsible for actually drawing on the display. ‣ e.g., a Text contains a String

Page 31: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

19

What about self?• When you delegate, the receiver

of the delegating message (the delegate) is no longer the target‣ Does it matter? Does the delegate need

access to the target? Does the delegate send a message back to the client?

• If it doesn’t matter, forward messages unchanged — Beck calls this Simple Delegation

Page 32: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

19

What about self?• When you delegate, the receiver

of the delegating message (the delegate) is no longer the target‣ Does it matter? Does the delegate need

access to the target? Does the delegate send a message back to the client?

• If it doesn’t matter, forward messages unchanged — Beck calls this Simple Delegation

target

Page 33: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

19

What about self?• When you delegate, the receiver

of the delegating message (the delegate) is no longer the target‣ Does it matter? Does the delegate need

access to the target? Does the delegate send a message back to the client?

• If it doesn’t matter, forward messages unchanged — Beck calls this Simple Delegation

self

target

Page 34: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

19

What about self?• When you delegate, the receiver

of the delegating message (the delegate) is no longer the target‣ Does it matter? Does the delegate need

access to the target? Does the delegate send a message back to the client?

• If it doesn’t matter, forward messages unchanged — Beck calls this Simple Delegation

delegateself

target

Page 35: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

19

What about self?• When you delegate, the receiver

of the delegating message (the delegate) is no longer the target‣ Does it matter? Does the delegate need

access to the target? Does the delegate send a message back to the client?

• If it doesn’t matter, forward messages unchanged — Beck calls this Simple Delegation

delegate

target

Page 36: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

19

What about self?• When you delegate, the receiver

of the delegating message (the delegate) is no longer the target‣ Does it matter? Does the delegate need

access to the target? Does the delegate send a message back to the client?

• If it doesn’t matter, forward messages unchanged — Beck calls this Simple Delegation

self

delegate

target

Page 37: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

20

Simple Delegation Examplemethod do(aBlock) { collectionOfPoints.do(aBlock) }

method map(aBlock) {def newPath = path.withForm(self.form)newPath.points := (collectionOfPoints.map(aBlock)newPath }

Page 38: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

Simple Delegation works when:

• you don’t need the state of the original target object

• you don’t need the behaviour of the original target object

• you don’t need the identity of the original target object

If you need these things, use self delegation

21

Page 39: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

22

Self Delegation

• When the delegate needs a reference to the delegating object…

• Pass along the delegating object as an additional parameter.

Page 40: Based on Metz Chapter 8: Combining Objects with Compositionweb.cecs.pdx.edu/~black/OOP/Lectures/Composition.pdf · 2019. 5. 22. · explicitly declare classes as abstract. Java, for

23

Self Delegation Example

Dictionary: method at(key) put(value) { self.hashTable.at(key) put(value) for(self)}HashTable: method at(key) put(value) for(aCollection) { def hash = aCollection.hashOf(key)}Dictionary: method hashOf(anObject) { anObject.hash}PlugableDictionary: method hashOf(anObject) { injectedHash(anObject)}