Andy Bulka Technical Director Austhink Software www.austhink.com March 2008 Refactoring to patterns…
Simple Composite pattern <ul><li>Class with a “children” collection </li></ul><ul><li>Children are of type Node (i.e. you ...
Classic Composite pattern (GOF) <ul><li>Distinguish between Composites and Leaves </li></ul><ul><li>Benefit of “classic” i...
The Problem Code <ul><li>We have two classes that loop through their children –  duplicate code </li></ul><ul><li>The chil...
The Solution <ul><li>Create a common base class which has the generic “composite” looping behaviour </li></ul><ul><li>That...
Original Problem code class  Node (object): def __init__(self, name): self.name = name def  toPlainTextString (self): retu...
Step 1 <ul><li># Create a Composite Class - compile </li></ul><ul><li>class Composite(Node): </li></ul><ul><li>pass </li><...
Step 2 <ul><li>Make each child container (a class in the hierarchy that </li></ul><ul><li>contains duplicate child-handlin...
Step 3 <ul><li>For each method with duplicated looping code </li></ul><ul><li>1. move & rename the child reference field U...
Everything moved to Composite <ul><li>class  Composite (Node): </li></ul><ul><li>def __init__(self): </li></ul><ul><li>sel...
Step 4 <ul><li>Check interfaces so that  client code  using the old composites still works. </li></ul>f = FormTag() f. chi...
New UML <ul><li>We have inserted a new class called  Composite  above the LinkTag and FormTag, which does the common loopi...
Before and After
Upcoming SlideShare
Loading in …5
×

Extract Composite Talk Andy

1,033 views

Published on

Published in: Business, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,033
On SlideShare
0
From Embeds
0
Number of Embeds
494
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Extract Composite Talk Andy

  1. 1. Andy Bulka Technical Director Austhink Software www.austhink.com March 2008 Refactoring to patterns…
  2. 2. Simple Composite pattern <ul><li>Class with a “children” collection </li></ul><ul><li>Children are of type Node (i.e. you point to yourself) </li></ul>
  3. 3. Classic Composite pattern (GOF) <ul><li>Distinguish between Composites and Leaves </li></ul><ul><li>Benefit of “classic” is that you can distinguish leafs and override display() or doubleClick() or whatever for leafs. </li></ul>
  4. 4. The Problem Code <ul><li>We have two classes that loop through their children – duplicate code </li></ul><ul><li>The children attribute is named differently in both classes – inconsistent </li></ul><ul><li>Both classes are “composites” </li></ul>
  5. 5. The Solution <ul><li>Create a common base class which has the generic “composite” looping behaviour </li></ul><ul><li>That’s where the name of the refactoring comes from “Extract Composite” </li></ul>
  6. 6. 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 = &quot;&quot; for node in self.allNodesVector: result += node.toPlainTextString() return result class LinkTag (Node): def __init__(self): self.linkData = [] def toPlainTextString (self): result = &quot;&quot; for node in self.linkData: result += node.toPlainTextString() return result f = FormTag() f.allNodesVector.append(Node(&quot;a&quot;)) f.allNodesVector.append(Node(&quot;b&quot;)) f.allNodesVector.append(Node(&quot;c&quot;)) l = LinkTag() l.linkData += [Node(&quot;x&quot;), Node(&quot;y&quot;), Node(&quot;z&quot;)] print f.toPlainTextString() print l.toPlainTextString() abc xyz output
  7. 7. Step 1 <ul><li># Create a Composite Class - compile </li></ul><ul><li>class Composite(Node): </li></ul><ul><li>pass </li></ul>
  8. 8. Step 2 <ul><li>Make each child container (a class in the hierarchy that </li></ul><ul><li>contains duplicate child-handling code) a subclass of </li></ul><ul><li>your composite – compile </li></ul><ul><li>class Composite(Node): </li></ul><ul><li>pass </li></ul><ul><li>class FormTag(Composite): </li></ul><ul><li>… . </li></ul><ul><li>class LinkTag(Composite): </li></ul><ul><li>… . </li></ul>
  9. 9. Step 3 <ul><li>For each method with duplicated looping code </li></ul><ul><li>1. move & rename the child reference field UP </li></ul><ul><li>to the composite using &quot;Pull Up Field&quot; </li></ul><ul><li>2. Move the method UP to the composite using &quot;Pull Up Method&quot; </li></ul><ul><li>3. Pull up any relevant constructor code too. </li></ul>
  10. 10. Everything moved to Composite <ul><li>class Composite (Node): </li></ul><ul><li>def __init__(self): </li></ul><ul><li>self.children = [] </li></ul><ul><li>def toPlainTextString(self): </li></ul><ul><li>result = &quot;&quot; </li></ul><ul><li>for node in self.children: </li></ul><ul><li>result += node.toPlainTextString() </li></ul><ul><li>return result </li></ul><ul><li>class FormTag(Composite): </li></ul><ul><li>pass </li></ul><ul><li>class LinkTag(Composite): </li></ul><ul><li>pass </li></ul>
  11. 11. Step 4 <ul><li>Check interfaces so that client code using the old composites still works. </li></ul>f = FormTag() f. children .append(Node(&quot;a&quot;)) f. children .append(Node(&quot;b&quot;)) f. children .append(Node(&quot;c&quot;)) l = LinkTag() l. children += [Node(&quot;x&quot;), Node(&quot;y&quot;), Node(&quot;z&quot;)] print f.toPlainTextString() print l.toPlainTextString() f = FormTag() f. allNodesVector .append(Node(&quot;a&quot;)) f. allNodesVector .append(Node(&quot;b&quot;)) f. allNodesVector .append(Node(&quot;c&quot;)) l = LinkTag() l. linkData += [Node(&quot;x&quot;), Node(&quot;y&quot;), Node(&quot;z&quot;)] print f.toPlainTextString() print l.toPlainTextString()
  12. 12. New UML <ul><li>We have inserted a new class called Composite above the LinkTag and FormTag, which does the common looping work. </li></ul>
  13. 13. Before and After

×