Compose Method

961 views
889 views

Published on

Presentation given on Apr 2007 at Melbourne Patterns Group (Refactoring from the "Refactoring to Patterns" Book

http://htxt.it/szwY

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

  • Be the first to like this

No Downloads
Views
Total views
961
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Compose Method

  1. 1. Compose Method Problem You can't rapidly understand a method's logic. Solution Transform the logic into a small number of intention-revealing steps at the same level of detail.
  2. 2. Origin <ul><li>Compose Method Refactoring </li></ul><ul><li>from Refactoring to Patterns </li></ul><ul><li>by Joshua Kerievsky </li></ul><ul><li>Composed Method Pattern </li></ul><ul><li>from Smalltalk Best Practice Patterns </li></ul><ul><li>by Kent Beck </li></ul>
  3. 3. Benefits <ul><li>Efficiently communicates what a method does and how it does what it does. </li></ul><ul><li>Simplifies a method by breaking it up into well-named chunks of behavior at the same level of detail. </li></ul>
  4. 4. Liabilities <ul><li>Can lead to an overabundance of small methods. </li></ul><ul><li>Can make debugging difficult because logic is spread out across many small methods. </li></ul>
  5. 5. <ul><li>Before </li></ul><ul><li>private void paintCard(Graphics g) { </li></ul><ul><li>Image image = null; </li></ul><ul><li>if (card.getType().equals(&quot;Problem&quot;)) { </li></ul><ul><li>image = explanations.getGameUI().problem; </li></ul><ul><li>} else if (card.getType().equals(&quot;Solution&quot;)) { </li></ul><ul><li>image = explanations.getGameUI().solution; </li></ul><ul><li>} else if (card.getType().equals(&quot;Value&quot;)) { </li></ul><ul><li>image = explanations.getGameUI().value; </li></ul><ul><li>} </li></ul><ul><li>g.drawImage( </li></ul><ul><li>image,0,0, </li></ul><ul><li>explanations.getGameUI()); </li></ul><ul><li>if (shouldHighlight()) </li></ul><ul><li>paintCardHighlight(g); </li></ul><ul><li>paintCardText(g); </li></ul><ul><li>} </li></ul><ul><li>After </li></ul><ul><li>private void paintCard(Graphics g) { </li></ul><ul><li> paintCardImage(g); </li></ul><ul><li> if (shouldHighlight()) paintCardHighlight(g); paintCardText(g); </li></ul><ul><li>} </li></ul>
  6. 6. Extract Method <ul><li>You have a code fragment that can be grouped together. </li></ul><ul><li>Turn the fragment into a method whose name explains the purpose of the method. </li></ul>
  7. 7. Guidelines <ul><li>Think small </li></ul><ul><li>Remove duplication and dead code </li></ul><ul><li>Communicate intention </li></ul><ul><li>Simplify </li></ul><ul><li>Use the same level of detail </li></ul>
  8. 8. Example <ul><li>public class List... </li></ul><ul><ul><li>public void add(Object element) { </li></ul></ul><ul><ul><ul><li>if (!readOnly) { </li></ul></ul></ul><ul><ul><ul><ul><li>int newSize = size + 1; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>if (newSize > elements.length) { </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>Object[] newElements = new Object[elements.length + 10]; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>for (int i = 0; i < size; i++) </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>newElements[i] = elements[i]; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>elements = newElements; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>} </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><li>elements[size++] = element; </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><li>} </li></ul>
  9. 9. Step 1 <ul><li>public class List... </li></ul><ul><ul><li>public void add(Object element) { </li></ul></ul><ul><ul><ul><li>if (readOnly) </li></ul></ul></ul><ul><ul><ul><li>return; </li></ul></ul></ul><ul><ul><ul><li>int newSize = size + 1; </li></ul></ul></ul><ul><ul><ul><li>if (newSize > elements.length) { </li></ul></ul></ul><ul><ul><ul><ul><li>Object[] newElements = new Object[elements.length + 10]; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>for (int i = 0; i < size; i++) </li></ul></ul></ul></ul><ul><ul><ul><ul><li>newElements[i] = elements[i]; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>elements = newElements; </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>elements[size++] = element; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul>
  10. 10. Step 2 <ul><li>public class List... </li></ul><ul><li>private final static int GROWTH_INCREMENT = 10; </li></ul><ul><li>public void add(Object element)... </li></ul><ul><li>... </li></ul><ul><li>Object[] newElements = </li></ul><ul><li>new Object[elements.length + GROWTH_INCREMENT ]; </li></ul><ul><li>... </li></ul>
  11. 11. Step 3 <ul><li>public class List... </li></ul><ul><ul><li>public void add(Object element) { </li></ul></ul><ul><ul><ul><li>if (readOnly) </li></ul></ul></ul><ul><ul><ul><li>return; </li></ul></ul></ul><ul><ul><ul><li>if ( atCapacity()) { </li></ul></ul></ul><ul><ul><ul><ul><li>Object[] newElements = </li></ul></ul></ul></ul><ul><ul><ul><ul><li>new Object[elements.length + GROWTH_INCREMENT]; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>for (int i = 0; i < size; i++) </li></ul></ul></ul></ul><ul><ul><ul><ul><li>newElements[i] = elements[i]; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>elements = newElements; </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>elements[size++] = element; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>private boolean atCapacity() { </li></ul></ul><ul><ul><li>return (size + 1) > elements.length; </li></ul></ul><ul><ul><li>} </li></ul></ul>
  12. 12. Step 4 <ul><li>public class List... </li></ul><ul><ul><li>public void add(Object element) { </li></ul></ul><ul><ul><ul><li>if (readOnly) </li></ul></ul></ul><ul><ul><ul><li>return; </li></ul></ul></ul><ul><ul><ul><li>if (atCapacity()) </li></ul></ul></ul><ul><ul><ul><li>grow(); </li></ul></ul></ul><ul><ul><ul><li>elements[size++] = element; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>private void grow() { </li></ul></ul><ul><ul><li>Object[] newElements = </li></ul></ul><ul><ul><li>new Object[elements.length + GROWTH_INCREMENT]; </li></ul></ul><ul><ul><li>for (int i = 0; i < size; i++) </li></ul></ul><ul><ul><li>newElements[i] = elements[i]; </li></ul></ul><ul><ul><li>elements = newElements; </li></ul></ul><ul><ul><li>} </li></ul></ul>
  13. 13. Step 5 <ul><li>public class List... </li></ul><ul><ul><li>public void add(Object element) { </li></ul></ul><ul><ul><ul><li>if (readOnly) </li></ul></ul></ul><ul><ul><ul><li>return; </li></ul></ul></ul><ul><ul><ul><li>if (atCapacity()) </li></ul></ul></ul><ul><ul><ul><li>grow(); </li></ul></ul></ul><ul><ul><ul><li>addElement(element); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>private void addElement(Object element) { </li></ul></ul><ul><ul><li>elements[size++] = element; </li></ul></ul><ul><ul><li>} </li></ul></ul>
  14. 14. Example <ul><li>public class List... </li></ul><ul><ul><li>public void add(Object element) { </li></ul></ul><ul><ul><ul><li>if (!readOnly) { </li></ul></ul></ul><ul><ul><ul><ul><li>int newSize = size + 1; </li></ul></ul></ul></ul><ul><ul><ul><ul><li>if (newSize > elements.length) { </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>Object[] newElements = new Object[elements.length + 10]; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>for (int i = 0; i < size; i++) </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>newElements[i] = elements[i]; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>elements = newElements; </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>} </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><li>elements[size++] = element; </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><li>} </li></ul>

×