Download - Extract Composite Talk Andy
![Page 1: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/1.jpg)
Andy BulkaTechnical DirectorAusthink Softwarewww.austhink.com
March 2008
Refactoring to patterns…
![Page 2: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/2.jpg)
Simple Composite patternClass with a “children” collectionChildren are of type Node (i.e. you point to
yourself)
![Page 3: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/3.jpg)
Classic Composite pattern (GOF)Distinguish
between Composites and Leaves
Benefit of “classic” is that you can distinguish leafs and override display() or doubleClick() or whatever for leafs.
![Page 4: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/4.jpg)
The Problem CodeWe have two
classes that loop through their children – duplicate code
The children attribute is named differently in both classes – inconsistent
Both classes are “composites”
![Page 5: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/5.jpg)
The SolutionCreate a common base class which has the
generic “composite” looping behaviourThat’s where the name of the refactoring
comes from “Extract Composite”
![Page 6: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/6.jpg)
Original Problem code
class Node(object): def __init__(self, name): self.name = name def toPlainTextString(self): return self.name
class FormTag(Node): def __init__(self): self.allNodesVector = [] def toPlainTextString(self): result = "" for node in self.allNodesVector: result += node.toPlainTextString() return result
class LinkTag(Node): def __init__(self): self.linkData = [] def toPlainTextString(self): result = "" for node in self.linkData: result += node.toPlainTextString() return result
f = FormTag()f.allNodesVector.append(Node("a"))f.allNodesVector.append(Node("b"))f.allNodesVector.append(Node("c"))
l = LinkTag()l.linkData += [Node("x"), Node("y"), Node("z")]
print f.toPlainTextString()print l.toPlainTextString()
abcxyz
output
![Page 7: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/7.jpg)
Step 1# Create a Composite Class - compile
class Composite(Node): pass
![Page 8: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/8.jpg)
Step 2Make each child container (a class in the hierarchy
thatcontains duplicate child-handling code) a subclass ofyour composite – compile
class Composite(Node): pass
class FormTag(Composite): ….class LinkTag(Composite): ….
![Page 9: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/9.jpg)
Step 3For each method with duplicated looping code 1. move & rename the child reference field UP to the composite using "Pull Up Field" 2. Move the method UP to the composite using
"Pull Up Method" 3. Pull up any relevant constructor code too.
![Page 10: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/10.jpg)
Everything moved to Compositeclass Composite(Node): def __init__(self): self.children = [] def toPlainTextString(self): result = "" for node in self.children: result += node.toPlainTextString() return result
class FormTag(Composite): pass class LinkTag(Composite): pass
![Page 11: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/11.jpg)
Step 4Check interfaces so that client code using the
old composites still works.
f = FormTag()f.children.append(Node("a"))f.children.append(Node("b"))f.children.append(Node("c"))
l = LinkTag()l.children += [Node("x"), Node("y"), Node("z")]
print f.toPlainTextString()print l.toPlainTextString()
f = FormTag()f.allNodesVector.append(Node("a"))f.allNodesVector.append(Node("b"))f.allNodesVector.append(Node("c"))
l = LinkTag()l.linkData += [Node("x"), Node("y"), Node("z")]
print f.toPlainTextString()print l.toPlainTextString()
![Page 12: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/12.jpg)
New UMLWe have inserted a
new class called Composite above the LinkTag and FormTag, which does the common looping work.
![Page 13: Extract Composite Talk Andy](https://reader035.vdocument.in/reader035/viewer/2022081413/546b2246af7959651f8b5197/html5/thumbnails/13.jpg)
Before and After