oorpt object-oriented reengineering patterns and techniques 8. restructuring prof. o. nierstrasz
Post on 20-Dec-2015
220 views
TRANSCRIPT
![Page 1: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/1.jpg)
OORPTObject-Oriented Reengineering Patterns and Techniques
8. Restructuring
Prof. O. Nierstrasz
![Page 2: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/2.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.2
Roadmap
> Redistribute Responsibilities> Transform Conditionals to Polymorphism
![Page 3: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/3.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.3
Tests: Your Life Insurance
Detailed Model Capture
Initial Understanding
First Contact
Setting Direction
Migration Strategies
Detecting Duplicated Code
Redistribute Responsibilities
Transform Conditionals to Polymorphism
A Map of Reengineering Patterns
![Page 4: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/4.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.4
The Reengineering Life-Cycle
Requirements
Designs
Code
(0) requirementanalysis
(1) modelcapture
(2) problemdetection (3) problem
resolution
(4) program transformation
(2) problem detection(3) problem resolutionissues• OO paradigm• When/When not
![Page 5: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/5.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.5
Roadmap
> Redistribute Responsibilities— The Law of Demeter— Move Behaviour Close to Data— Eliminate Navigation Code— Split Up God Class
> Transform Conditionals to Polymorphism
![Page 6: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/6.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.6
Redistribute Responsibilities
Eliminate Navigation Code
Data containers
Monster client ofdata containers
Split Up God Class
Move Behaviour Close to Data
Chains of datacontainers
![Page 7: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/7.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.7
Roadmap
> Redistribute Responsibilities— The Law of Demeter— Move Behaviour Close to Data— Eliminate Navigation Code— Split Up God Class
> Transform Conditionals to Polymorphism
![Page 8: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/8.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.8
The Law of Demeter
> A method M of an object O should invoke only the methods of the following kinds of objects:1. O itself2. parameters of M3. any object M creates /instantiates4. direct component objects of O
http://en.wikipedia.org/wiki/Law_of_Demeterhttp://en.wikipedia.org/wiki/Law_of_Demeter
![Page 9: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/9.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.9
IndirectProviderdoSomething()
ImmediateProvider+providergetProvider()
IndirectClient
intermediate.provider.doSomething()Or intermediate.getProvider().doSomething()
intermediate.provider.doSomething()Or intermediate.getProvider().doSomething()
provider intermediate
The Core of the Problem
![Page 10: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/10.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.10
Roadmap
> Redistribute Responsibilities— The Law of Demeter— Move Behaviour Close to Data— Eliminate Navigation Code— Split Up God Class
> Transform Conditionals to Polymorphism
![Page 11: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/11.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.11
Move Behavior Close to Data
> Problem: How do you transform a data container into a service provider
> Solution: Move behavior defined by indirect clients to the class defining the data they manipulate
> …however— Visitor — Difficult to identify client code to be moved in
– Responsibility of the provider– Access attributes of the provider– Accessed by multiple clients
![Page 12: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/12.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.12
Transformation…
Provider+x+y+sety(val)+setx(val)
ClientOp2()
…provider.sety(provider.x + provider.y)…
…provider.sety(provider.x + provider.y)…
Provider-x-y-sety(val)+bump()
ClientOp2()
…provider.bump()…
…provider.bump()…
this.sety(provider.x + provider.y)this.sety(provider.x + provider.y)
![Page 13: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/13.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.13
Detection strategy
> Look for data containers— Classes with only accessors
> Duplicated client code
> Methods using sequence of accessors
![Page 14: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/14.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.14
Difficulties
> When the moved behavior accessed client data, having extra parameters can lead to complex interface
> Certain classes (Set or Stream) are data containers. Move functionality to provider if— It represents a provider responsibility— It accesses attributes of the provider— The same behavior defined in multiple clients
![Page 15: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/15.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.15
When Legacy Solution is not a Problem
> A Visitor typically defines behavior that acts on another class
> Configuration classes (global settings, language dependent information..)
> Mapping classes between objects and UI or databases representation
![Page 16: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/16.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.16
Roadmap
> Redistribute Responsibilities— The Law of Demeter— Move Behaviour Close to Data— Eliminate Navigation Code— Split Up God Class
> Transform Conditionals to Polymorphism
![Page 17: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/17.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.17
Eliminate Navigation Code
> Problem: How do you reduce the coupling due to classes that navigate object graph?
> Solution: iteratively move behavior close the data
— …however– Systematic uses produce large interfaces (shield collections)– AKA Law of Demeter
![Page 18: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/18.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.18
Eliminate Navigation Code
…engine.carburetor.fuelValveOpen = true…engine.carburetor.fuelValveOpen = true
Engine+carburetor
Car-engine+increaseSpeed()
Carburetor+fuelValveOpen
Engine-carburetor+speedUp()
Car-engine+increaseSpeed()
…engine.speedUp()…engine.speedUp()
carburetor.fuelValveOpen = truecarburetor.fuelValveOpen = true
Carburetor+fuelValveOpen
Car-engine+increaseSpeed()
Carburetor-fuelValveOpen+openFuelValve()
Engine-carburetor+speedUp()
carburetor.openFuelValve()carburetor.openFuelValve()fuelValveOpen = truefuelValveOpen = true
![Page 19: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/19.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.19
Detection (i)
> Class with lot of accessors few methods
> Each time a class changes, indirect clients get impacted
> Search for patterns— a.b.c.d.op() identified by
– egrep ‘.*\..*\..*\..’ *.java
— anObject.m1().m2().op() identified by– egrep ‘.*\(\).*\(\).*\(\).’ *.java
![Page 20: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/20.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.20
Detection (ii)
> Not a problem—(a.isNode()) & (a.isAbstract())
> Beware of disguised navigationToken token;
token = parseTree.token();if (token.identifier() != null){…
if(parseTree.token().identifier() != null){…
![Page 21: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/21.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.21
When the Legacy Solution is the Solution
> User Interfaces or databases may need to have access to indirect providers
> Brokers or object servers are special objects returning objects
![Page 22: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/22.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.22
Law of Demeter’s Dark Side
> Can produce large interfaces
Class A instVar: myCollection
A>>do: aBlock myCollection do: aBlock
A>>collect: aBlockmyCollection collect: aBlock
… … …
![Page 23: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/23.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.23
Roadmap
> Redistribute Responsibilities— The Law of Demeter— Move Behaviour Close to Data— Eliminate Navigation Code— Split Up God Class
> Transform Conditionals to Polymorphism
![Page 24: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/24.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.24
Split Up God Class
> Problem: How to break a class that controls the complete system logic?
> Solution: Incrementally distribute responsibilities into slave classes
— …however it is difficult to – Identify abstractions in blob– Limit impact of changes on other parts
![Page 25: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/25.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.25
Detection
> Huge, monolithic class with no clear and simple responsibility
> “The heart of the system”> One single class contains all the logic and control flow> Other classes only serve as passive data holders> Names like “Manager”, “System”, “Root”, “*Controller*” > Changes to the system always entail changes to the
same class
![Page 26: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/26.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.26
Transformation
> Difficult because God Class is a usually a huge blob> Identify cohesive set of attributes and methods
— Create classes for these sets
> Identify all classes used as data holder and analyze how the god class uses them— Itaeratively Move Behavior close to the Data
> Try to always have a running system before decomposing the God Class— Use accessors to hide the transformation — Use method delegation from the God Class to the providers— Use Façade to minimize change in clients
![Page 27: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/27.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.27
Strategies
> If God Class does not need to be changed don’t touch it!> Wrap it with different OO views
— but a God Class usually defines the control flow of the application
![Page 28: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/28.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.28
Roadmap
> Redistribute Responsibilities> Transform Conditionals to Polymorphism
— Transform Self Type Checks— Transform Client Checks — [Factor out State]— Factor out Strategy— Introduce Null Object— Transform Conditionals into Registration
![Page 29: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/29.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.29
A Map of Reengineering Patterns
Tests: Your Life Insurance
Detailed Model Capture
Initial Understanding
First Contact
Setting Direction
Migration Strategies
Detecting Duplicated Code
Redistribute Responsibilities
Transform Conditionals to Polymorphism
![Page 30: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/30.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.30
TransformSelf Type Checks
Test providertype
Test self typeTest external
attribute
TransformClient Type Checks
Transform Conditionalsinto Registration
Testnull values Introduce
Null Object
Factor Out Strategy
Factor Out State
Test object state
Transform Conditionals to Polymorphism
![Page 31: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/31.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.31
Forces
> Requirements change, so new classes and new methods will have to be introduced
> Adding new classes may clutter the namespace
> Conditionals group all the variant in one place but make changes difficult— Conditionals clutter logic— Editing several classes and fixing case statements to introduce
a new behavior is error prone
![Page 32: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/32.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.32
Overview
> Transform Self Type Checks— eliminates conditionals over type information in a provider by introducing new
subclasses
> Transform Client Checks — eliminates conditionals over client type information by introducing new method
to each provider classes
> Factor out State— kind of Self Type Check
> Factor out Strategy— kind of Self Type Check
> Introduce Null Object— eliminates null tests by introducing a Null Object
> Transform Conditionals into Registration— eliminates conditional by using a registration mechanism
![Page 33: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/33.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.33
Roadmap
> Redistribute Responsibilities> Transform Conditionals to Polymorphism
— Transform Self Type Checks— Transform Client Checks — [Factor out State]— Factor out Strategy— Introduce Null Object— Transform Conditionals into Registration
![Page 34: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/34.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.34
Am()
Client …case Text: this.doSomething()case Border: this.doOther()case D:
…case Text: this.doSomething()case Border: this.doOther()case D:
Transform Self Type Checks
> Symptoms— Simple extensions require many changes in conditional code— Subclassing impossible without duplicating and updating
conditional code— Adding new case to conditional code
![Page 35: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/35.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.35
Am()
Client …case Text: this.doSomething()case Border:case D:
…case Text: this.doSomething()case Border:case D:
ClientAm()hook()
this.doSomething()this.doSomething()
…this.hook()…this.hook()
Texthook()
Borderhook()
Dhook()
Transformation
![Page 36: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/36.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.36
Example: Transform Self Type Checks
class Message {private:
int type_; void* data;...void send (Channel* ch) {
switch (type_) {case TEXT : {
ch->nextPutAll(data);break;
}case ACTION : {
ch->doAction(data); ...
![Page 37: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/37.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.37
Messagesend()
Messagesend()
ActionMessagesend()
TextMessagesend()
switch (type_) {case TEXT : {ch->nextPutAll(data);break;}
case ACTION : {ch->doAction(data);
...
switch (type_) {case TEXT : {ch->nextPutAll(data);break;}
case ACTION : {ch->doAction(data);
...
Client1
Client1
Client2
Client2
Transform Self Type Check
![Page 38: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/38.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.38
Detection
> Long methods with complex decision logic— Look for attribute set in constructors but never changed— Attributes to model type or finite set constants— Multiple methods switch on the same attribute— grep switch ‘find . -name “*.cxx” -print’
![Page 39: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/39.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.39
Pros/Cons/Difficulties
> Pros— New behavior are easy to add and to understand: a new class— No need to change different method to add a behavior— All behaviors share a common interface
> Cons— Behavior are dispersed into multiple but related abstractions— More classes
> Difficulties— Not always one to one mapping between cases and subclasses— Clients may be changed to create instance of the right subclass
![Page 40: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/40.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.40
Roadmap
> Redistribute Responsibilities> Transform Conditionals to Polymorphism
— Transform Self Type Checks— Transform Client Checks — [Factor out State]— Factor out Strategy— Introduce Null Object— Transform Conditionals into Registration
![Page 41: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/41.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.41
Ainit()
Clienta : Am()
switch (a.class)case B: a.init(); ((B) a).x();case C: a.init(); ((C)) a).y();Case D: ((D) a).z()
switch (a.class)case B: a.init(); ((B) a).x();case C: a.init(); ((C)) a).y();Case D: ((D) a).z()
Bx()
Cinit()Y()
Dz()
Transform Client Type Checks
> Symptoms— Clients perform explicit type checks / type coercions— Adding a new provider (A subclass) change all clients— Clients are defining logic about providers
![Page 42: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/42.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.42
Transformation
Ainit()
Clienta : Am()
switch (a.class)case B: a.init(); ((B) a).x();case C: a.init(); ((C)) a).y();Case D: ((D) a).z()
Clienta : Am()
a.doit();a.doit(); Ainit()doit()
Bx()doit()
Cinit()Y()doit()
Dz()doit()
this.init ();this.x();this.init ();this.x();
this.init ();this.y();this.init ();this.y();
this.z();this.z();
Bx()
Cinit()Y()
Dz()
![Page 43: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/43.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.43
Example: Transform Client Type Checks
void makeCalls (Telephone* phoneArray[]) {for (Telephone *p = phoneArray; p; p++) {
switch (p-> phoneType()) {case TELEPHONE::POTS : {
POTSPhone* potsp =(POTSPhone*)p
potsp->tourne();potsp->call();...
case TELEPHONE::ISDN : {ISDNPhone* isdnp =
(ISDNPhone*)pisdnp->initLine();isdnp->connect();...
![Page 44: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/44.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.44
TelephoneBoxmakeCall ()
Telephone
POTSPhone...
ISDNPhone...
TelephoneBoxmakeCall ()
TelephonemakeCall()
POTSPhonemakeCall()
...
ISDNPhonemakeCall
...
Transform Client Type Check
![Page 45: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/45.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.45
Detection
> Transform Self Type Checks> Changing clients of method when new case added> Attribute representing a type
In Smalltalk: isKindOf:, isMemberOf:> In Java: instanceof> x.getClass() == y.getClass()> x.getClass().getName().equals(….)
![Page 46: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/46.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.46
Pros/Cons/Difficulties
> Pros— The provider offers now a polymorphic interface that can be
used by other clients— A class represent one case— Clients are not responsible of provider logic— Adding new case does not impact all clients
> Cons— Behavior is not group per method but per class
> Difficulties— Refactor the clients (Deprecate Obsolete Interfaces)— Instance creation should not be a problem
![Page 47: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/47.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.47
When the Legacy Solution is the Solution
> Abstract Factory may need to check a type variable to know which class to instantiate. — For example streaming objects from a text file requires to know
the type of the streamed object to recreate it
> If provider hierarchy is frozen— Wrapping the classes could be a good migration strategy
> Software that interfaces with non-OO libraries— Switch to simulate polymorphic calls
![Page 48: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/48.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.48
Roadmap
> Redistribute Responsibilities> Transform Conditionals to Polymorphism
— Transform Self Type Checks— Transform Client Checks — [Factor out State]— Factor out Strategy— Introduce Null Object— Transform Conditionals into Registration
![Page 49: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/49.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.49
Factor Out Strategy
> Problem: — How do you make a class whose behavior depends on testing
certain values more extensible?
> Solution:— Apply Strategy Pattern— Encapsulate the behavior and delegate using a polymorphic call
![Page 50: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/50.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.50
Transformation
AbstractStrategy
handleOperation()
Aoperation()
…strategy.handleOperation()…
…strategy.handleOperation()…
StrategyXhandleOperation()
Aoperation()
…case X: …case Z: ….…
…case X: …case Z: ….…
strategy
StrategyZhandleOperation()
![Page 51: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/51.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.51
Pros/Cons/Difficulties
> Pros— Behavior extension is well-identified— Behavior using the extension is clearer— Change behavior at run-time
> Cons— Namespace get cluttered— Yet another indirection
> Difficulties— Behavior can be difficult to convert and encapsulate (passing
parameter…)
![Page 52: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/52.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.52
Roadmap
> Redistribute Responsibilities> Transform Conditionals to Polymorphism
— Transform Self Type Checks— Transform Client Checks — [Factor out State]— Factor out Strategy— Introduce Null Object— Transform Conditionals into Registration
![Page 53: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/53.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.53
Introduce NullObject
> Problem: — How can you avoid repeated tests for null values?
> Solution: — Encapsulate the null behavior as a separate class that is
polymorphic to the provider
![Page 54: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/54.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.54
Transformation
AbstractObject
doit()
Clientm()
RealObjectdoit()
nothingnothing
NullObjectdoit()
RealObjectdoit()
Clientm()
…a.doit()…
…a.doit()…
…if (a!=Null) { a.doit()}…
…if (a!=Null) { a.doit()}…
![Page 55: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/55.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.55
Pros/Cons/Discussions
> Pros— Clients do not need to test for null values
> Difficulties— Different clients may have different null behavior— In statically typed languages, you have to introduce Null
interface> Hint
— The NullObject does not have to be a subclass of RealObject superclass as soon as it implements RealObject’s null interface (in Java and Smalltalk)
> Do not apply when— Very little code uses direct variable access — Code that checks is well-encapsulated in a single place
![Page 56: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/56.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.56
Roadmap
> Redistribute Responsibilities> Transform Conditionals to Polymorphism
— Transform Self Type Checks— Transform Client Checks — [Factor out State]— Factor out Strategy— Introduce Null Object— Transform Conditionals into Registration
![Page 57: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/57.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.57
Transform Conditional into Registration
> Problem— How do you reduce the coupling between tools providing
services and clients so that addition/removal of tools does not change client code?
> Solution: Introduce a registration mechanism— Tools register/unregister— Clients query them via the registration repository
![Page 58: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/58.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.58
Symptoms
> Long methods in clients checking which tools to invoke based on external properties e.g., file extension
> Removing or adding a tool forces you to change client code
> Difficulty to have run-time tool loading / unloading
![Page 59: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/59.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.59
Transformation (i)
ToolClientread()
XMLReaderopenFile (File)
WordReaderon (file)
suffix := selectedFile suffix = ‘xml’.suffix = ‘xml’
ifTrue: [ XMLReader openFile: selectedFile.^ self]
suffix = ‘doc’ifTrue: [WordReader on: selectedFile.
^ self].…
suffix := selectedFile suffix = ‘xml’.suffix = ‘xml’
ifTrue: [ XMLReader openFile: selectedFile.^ self]
suffix = ‘doc’ifTrue: [WordReader on: selectedFile.
^ self].…
![Page 60: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/60.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.60
Transformation (ii)
XMLReaderopenFile (File)load()unload()
ToolClientread()
(PluginManager uniqueInstance findToolFor: selectedFile suffix) action(PluginManager uniqueInstance findToolFor: selectedFile suffix) action
WordReaderon (file)load()unload()
Pluginactionfor: String use: class with: method
PluginManageradd/remove (Tool)findToolFor (String)
(PluginManager uniqueInstance add: (Plugin for: ‘xml’ use: XMLReader
with: openFile)
(PluginManager uniqueInstance add: (Plugin for: ‘xml’ use: XMLReader
with: openFile)
(PluginManager uniqueInstance remove: (Plugin for: ‘xml’ use: XMLReader
with: openFile)
(PluginManager uniqueInstance remove: (Plugin for: ‘xml’ use: XMLReader
with: openFile)
![Page 61: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/61.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.61
Pros/Cons/Difficulties
> Pros— New tools can be added without impacting clients— Interaction between tools and clients is normalized— Reduce coupling and support modular design
> Cons— Every tool should register and unregister
> Difficulties— Action should be defined on the tool and not the client anymore,
information should be passed from the client to the tool— Client knew statically the tools, now it is dynamic so more effort
for UI (i.e., consistent menu ordering)
![Page 62: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/62.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.62
Conclusion
> Navigation Code & Complex Conditionals— Most common lack of OO use
> Polymorphism is key abstraction mechanism— adds flexibility reduces maintenance cost
> Avoid Risk— Only refactor when inferior code must be changed
(cf. God Class)
> Performance?— Small methods with less navigation code are easier to optimise— Deeply nested if-statements cost more than virtual calls
Long case statements cost as much as virtual calls
![Page 63: OORPT Object-Oriented Reengineering Patterns and Techniques 8. Restructuring Prof. O. Nierstrasz](https://reader030.vdocuments.mx/reader030/viewer/2022032704/56649d4c5503460f94a29a09/html5/thumbnails/63.jpg)
© Stéphane Ducasse, Serge Demeyer, Oscar Nierstrasz
OORPT — Restructuring
8.63
License
> http://creativecommons.org/licenses/by-sa/2.5/
Attribution-ShareAlike 2.5You are free:• to copy, distribute, display, and perform the work• to make derivative works• to make commercial use of the work
Under the following conditions:
Attribution. You must attribute the work in the manner specified by the author or licensor.
Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.
• For any reuse or distribution, you must make clear to others the license terms of this work.• Any of these conditions can be waived if you get permission from the copyright holder.
Your fair use and other rights are in no way affected by the above.
Attribution-ShareAlike 2.5You are free:• to copy, distribute, display, and perform the work• to make derivative works• to make commercial use of the work
Under the following conditions:
Attribution. You must attribute the work in the manner specified by the author or licensor.
Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.
• For any reuse or distribution, you must make clear to others the license terms of this work.• Any of these conditions can be waived if you get permission from the copyright holder.
Your fair use and other rights are in no way affected by the above.