Slideshare.net (beta)

Love SlideShare? Want to join the team? We are hiring software engineers, operations engineers, quality assurance engineers, and community managers. In San Francisco & New Delhi. More info here, or email your resume to jobs [at] slideshare [dot] net.
 
Post: 
Myspace Hi5 Friendster Xanga LiveJournal Facebook Blogger Tagged Typepad Freewebs BlackPlanet gigya icons

All comments

Add a comment on Slide 1

If you have a SlideShare account, login to comment; else you can comment as a guest


Showing 1-50 of 0 (more)

Refactoring Fest

From krivitsky, 1 month ago

Materials by Naresh Jain from XP days, Kyiv, April 08. http://www. more

181 views  |  0 comments  |  0 favorites  |  4 downloads
 

Groups/Events

Not added to any group/event

 
 

Privacy InfoNew!

This slideshow is Public

 
Embed in your blog
Embed (wordpress.com)

Slideshow Statistics
Total Views: 181
on Slideshare: 181
from embeds: 0* * Views from embeds since 21 Aug, 07

Slideshow transcript

Slide 1: Refactoring Fest Naresh Jain naresh@agilefaqs.com Licensed Under Creative Commons by Naresh Jain 1

Slide 2: Tutorial Schedule What, Why, When and How... Refactor? How to Refactor to Patterns How to deal with Legacy Code? Refactoring Hands-on session Licensed Under Creative Commons by Naresh Jain 2

Slide 3: Three Golden Rules Once and only once [DRY] Express intent Tell, don’t ask Licensed Under Creative Commons by Naresh Jain 3

Slide 4: Definitions Licensed Under Creative Commons by Naresh Jain 4

Slide 5: Definitions Loose Usage Licensed Under Creative Commons by Naresh Jain 4

Slide 6: Definitions Loose Usage Reorganize a program (or something) Licensed Under Creative Commons by Naresh Jain 4

Slide 7: Definitions Loose Usage Reorganize a program (or something) As a noun Licensed Under Creative Commons by Naresh Jain 4

Slide 8: Definitions Loose Usage Reorganize a program (or something) As a noun a change made to the internal structure of some software to make it easier to understand and cheaper to modify, without changing the observable behavior of that software Licensed Under Creative Commons by Naresh Jain 4

Slide 9: Definitions Loose Usage Reorganize a program (or something) As a noun a change made to the internal structure of some software to make it easier to understand and cheaper to modify, without changing the observable behavior of that software As a verb Licensed Under Creative Commons by Naresh Jain 4

Slide 10: Definitions Loose Usage Reorganize a program (or something) As a noun a change made to the internal structure of some software to make it easier to understand and cheaper to modify, without changing the observable behavior of that software As a verb the activity of restructuring software by applying a series of refactorings without changing the observable behavior of that software. Licensed Under Creative Commons by Naresh Jain 4

Slide 11: What is Refactoring? Licensed Under Creative Commons by Naresh Jain 5

Slide 12: What is Refactoring? small steps, each of which changes the program’s A series of internal structure without changing its external behavior - Martin Fowler Licensed Under Creative Commons by Naresh Jain 5

Slide 13: What is Refactoring? small steps, each of which changes the program’s A series of internal structure without changing its external behavior - Martin Fowler Verify no change in external behavior by Testing Using the right tool - IDE Formal code analysis by tool Being very, very careful Licensed Under Creative Commons by Naresh Jain 5

Slide 14: What if you hear... Licensed Under Creative Commons by Naresh Jain 6

Slide 15: What if you hear... We’ll just refactor the code to add logging support Licensed Under Creative Commons by Naresh Jain 6

Slide 16: What if you hear... We’ll just refactor the code to add logging support Licensed Under Creative Commons by Naresh Jain 6

Slide 17: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? Licensed Under Creative Commons by Naresh Jain 6

Slide 18: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? Licensed Under Creative Commons by Naresh Jain 6

Slide 19: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? We have too much duplicate code, we need to refactor the code to eliminate duplication Licensed Under Creative Commons by Naresh Jain 6

Slide 20: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? We have too much duplicate code, we need to refactor the code to eliminate duplication Licensed Under Creative Commons by Naresh Jain 6

Slide 21: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? We have too much duplicate code, we need to refactor the code to eliminate duplication This class is too big, we need to refactor it Licensed Under Creative Commons by Naresh Jain 6

Slide 22: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? We have too much duplicate code, we need to refactor the code to eliminate duplication This class is too big, we need to refactor it Licensed Under Creative Commons by Naresh Jain 6

Slide 23: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? We have too much duplicate code, we need to refactor the code to eliminate duplication This class is too big, we need to refactor it Caching? Licensed Under Creative Commons by Naresh Jain 6

Slide 24: What if you hear... We’ll just refactor the code to add logging support Can you refactor the code so that it authenticates against LDAP instead of Database? We have too much duplicate code, we need to refactor the code to eliminate duplication This class is too big, we need to refactor it Caching? Licensed Under Creative Commons by Naresh Jain 6

Slide 25: Origin Ward Cunningham and Kent Beck Smalltalk style Ralph Johnson at University of Illinois at Urbana- Champaign Bill Opdyke’s Thesis ftp://st.cs.uiuc.edu/pub/papers/refactoring/opdyke- thesis.ps.Z John Brant and Don Roberts: The Refactoring Browser Licensed Under Creative Commons by Naresh Jain 7

Slide 26: Why do we Refactor? Licensed Under Creative Commons by Naresh Jain 8

Slide 27: Why do we Refactor? Helps us deliver more business value faster Licensed Under Creative Commons by Naresh Jain 8

Slide 28: Why do we Refactor? Helps us deliver more business value faster Improves the design of our software Combat’s “bit rot” Easier to maintain and understand Easier to facilitate change More flexibility Increased re-usability Licensed Under Creative Commons by Naresh Jain 8

Slide 29: Why do we Refactor?... Licensed Under Creative Commons by Naresh Jain 9

Slide 30: Why do we Refactor?... Minimizes technical debt Licensed Under Creative Commons by Naresh Jain 9

Slide 31: Why do we Refactor?... Minimizes technical debt Keep development at speed Licensed Under Creative Commons by Naresh Jain 9

Slide 32: Why do we Refactor?... Minimizes technical debt Keep development at speed To make the software easier to understand Write for people, not the compiler Understand unfamiliar code Licensed Under Creative Commons by Naresh Jain 9

Slide 33: Why do we Refactor?... Minimizes technical debt Keep development at speed To make the software easier to understand Write for people, not the compiler Understand unfamiliar code To help find bugs refactor while debugging to clarify the code Licensed Under Creative Commons by Naresh Jain 9

Slide 34: Why do we Refactor?... Minimizes technical debt Keep development at speed To make the software easier to understand Write for people, not the compiler Understand unfamiliar code To help find bugs refactor while debugging to clarify the code To “Fix broken windows” - Pragmatic Programmers Licensed Under Creative Commons by Naresh Jain 9

Slide 35: Readability Which code segment is easier to read? Sample 1 if (date.before(Summer_Start) || date.after(Summer_End)){ charge = quantity * winterRate + winterServiceCharge; else charge = quantity * summerRate; } Sample 2 if (isSummer(date)) { charge = summerCharge(quantity); Else charge = winterCharge(quantity); } Licensed Under Creative Commons by Naresh Jain 10

Slide 36: When should you refactor? Licensed Under Creative Commons by Naresh Jain 11

Slide 37: When should you refactor? To add new functionality refactor existing code until you understand it refactor the design to make it simple to add Licensed Under Creative Commons by Naresh Jain 11

Slide 38: When should you refactor? To add new functionality refactor existing code until you understand it refactor the design to make it simple to add To find bugs refactor to understand the code Licensed Under Creative Commons by Naresh Jain 11

Slide 39: When should you refactor? To add new functionality refactor existing code until you understand it refactor the design to make it simple to add To find bugs refactor to understand the code For code reviews immediate effect of code review allows for higher level suggestions Licensed Under Creative Commons by Naresh Jain 11

Slide 40: When should you refactor? To add new functionality refactor existing code until you understand it Like championship refactor the design to make it simple to add To find bugs snooker players we are setting ourselves up for refactor to understand the code For code reviews our next shot immediate effect of code review allows for higher level suggestions Licensed Under Creative Commons by Naresh Jain 11

Slide 41: The Two Hats Adding Function Refactoring Add new capabilities to the system Does not add any new features Does not add tests (but may change Adds new tests some) Get the test working Restructure the code to remove redundancy Licensed Under Creative Commons by Naresh Jain 12

Slide 42: The Two Hats Adding Function Refactoring Add new capabilities to the system Does not add any new features Does not add tests (but may change Adds new tests some) Get the test working Restructure the code to remove redundancy Swap frequently between the hats, but only wear one at a time Licensed Under Creative Commons by Naresh Jain 12

Slide 43: Refactoring and TDD TDD Rhythm - Test, Code, Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 44: Refactoring and TDD Add a Test TDD Rhythm - Test, Code, Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 45: Refactoring and TDD Add a Test Run the Test TDD Rhythm - Test, Code, Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 46: Refactoring and TDD Add a Test Pass Run the Test TDD Rhythm - Test, Code, Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 47: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 48: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Make a little change Licensed Under Creative Commons by Naresh Jain 13

Slide 49: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Make a little change Run the Test Licensed Under Creative Commons by Naresh Jain 13

Slide 50: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Make a little change Fail Run the Test Licensed Under Creative Commons by Naresh Jain 13

Slide 51: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Make a little change Fail Run the Test Pass Licensed Under Creative Commons by Naresh Jain 13

Slide 52: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Make a little change Fail Run the Test Pass Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 53: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Make a little change Fail Run the Test Pass Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 54: Refactoring and TDD Add a Test Pass Run the Test Fail TDD Rhythm - Test, Code, Refactor Make a little change Fail Run the Test Pass Refactor Licensed Under Creative Commons by Naresh Jain 13

Slide 55: Team Techniques Encourage refactoring culture nobody gets things right first time nobody can write clear code without reviews refactoring is forward progress Licensed Under Creative Commons by Naresh Jain 14

Slide 56: Team Techniques... Licensed Under Creative Commons by Naresh Jain 15

Slide 57: Team Techniques... Provide sound testing base tests are essential for refactoring build system and run tests daily Licensed Under Creative Commons by Naresh Jain 15

Slide 58: Team Techniques... Provide sound testing base tests are essential for refactoring build system and run tests daily Pair Programming two programmers working together can be quicker than working separately refactor with the class writer and a class user Licensed Under Creative Commons by Naresh Jain 15

Slide 59: How do we Refactor? We looks for Code-Smells Things that we suspect are not quite right or will cause us severe pain if we do not fix Licensed Under Creative Commons by Naresh Jain 16

Slide 60: Common Code Smells The Big Stinkers Duplicated code Long Method Feature Envy Long Parameter List Inappropriate Intimacy Switch Statements Comments Improper Naming Licensed Under Creative Commons by Naresh Jain 17

Slide 61: Duplicated Code Licensed Under Creative Commons by Naresh Jain 18

Slide 62: Duplicated Code There is obvious duplication Such as copy and paste Licensed Under Creative Commons by Naresh Jain 18

Slide 63: Duplicated Code There is obvious duplication Such as copy and paste There are unobvious duplications Such as parallel inheritance hierarchies. Similar algorithms Licensed Under Creative Commons by Naresh Jain 18

Slide 64: Duplicated Code There is obvious duplication Such as copy and paste There are unobvious duplications Such as parallel inheritance hierarchies. Similar algorithms Remedies Extract Method Pull Up Field Licensed Under Creative Commons by Naresh Jain 18

Slide 65: Feature Envy Licensed Under Creative Commons by Naresh Jain 19

Slide 66: Feature Envy A method that seems more interested in some other class than the one it is in. Licensed Under Creative Commons by Naresh Jain 19

Slide 67: Feature Envy A method that seems more interested in some other class than the one it is in. Remedies: Move Method Extract Method Licensed Under Creative Commons by Naresh Jain 19

Slide 68: Extract Method Licensed Under Creative Commons by Naresh Jain 20

Slide 69: Extract Method void printOwning(double amount){ printBanner(); // print details System.Console.WriteLine(string.Format(“name: “, name); System.Console.WriteLine(string.Format(“amount: “, amount); } Licensed Under Creative Commons by Naresh Jain 20

Slide 70: Extract Method void printOwning(double amount){ printBanner(); // print details System.Console.WriteLine(string.Format(“name: “, name); System.Console.WriteLine(string.Format(“amount: “, amount); } void printOwning(double amount){ printBanner(); printDetails(amount); } void printDetails(double amount){ System.Console.WriteLine(string.Format(“name: “, name); System.Console.WriteLine(string.Format(“amount: “, amount); } Licensed Under Creative Commons by Naresh Jain 20

Slide 71: Inappropriate Intimacy Licensed Under Creative Commons by Naresh Jain 21

Slide 72: Inappropriate Intimacy Two or more classes fiddling with each other’s private parts. Licensed Under Creative Commons by Naresh Jain 21

Slide 73: Inappropriate Intimacy Two or more classes fiddling with each other’s private parts. Remedies Move Method and Move Field Change Bi-directional Association to Unidirectional Extract Class Licensed Under Creative Commons by Naresh Jain 21

Slide 74: Extract Class Licensed Under Creative Commons by Naresh Jain 22

Slide 75: Extract Class Person name officeAreaCode officeNumber getTelephoneNumber Licensed Under Creative Commons by Naresh Jain 22

Slide 76: Extract Class Person Person TelephoneNumber name officeAreaCode name areaCode officeNumber telephoneNumber number getTelephoneNumber getTelephoneNumber getTelephoneNumber Licensed Under Creative Commons by Naresh Jain 22

Slide 77: Comments Licensed Under Creative Commons by Naresh Jain 23

Slide 78: Comments Comments – be suspicious! Licensed Under Creative Commons by Naresh Jain 23

Slide 79: Comments Comments – be suspicious! Comments are a deodorant. Licensed Under Creative Commons by Naresh Jain 23

Slide 80: Comments Comments – be suspicious! Comments are a deodorant. Comments represent a failure to express an idea in the code. Licensed Under Creative Commons by Naresh Jain 23

Slide 81: Comments Comments – be suspicious! Comments are a deodorant. Comments represent a failure to express an idea in the code. Remedies: Extract Method Rename Method Introduce Assertion Licensed Under Creative Commons by Naresh Jain 23

Slide 82: Introduce Assertion Licensed Under Creative Commons by Naresh Jain 24

Slide 83: Introduce Assertion double GetExpenseLimit() { // should have either expense limit or a primary project return(_expenseLimit != NULL_EXPENSE) ? _expenseLimit : _primaryProject.GetMemberExpenseLimit(); } Licensed Under Creative Commons by Naresh Jain 24

Slide 84: Introduce Assertion double GetExpenseLimit() { // should have either expense limit or a primary project return(_expenseLimit != NULL_EXPENSE) ? _expenseLimit : _primaryProject.GetMemberExpenseLimit(); } double GetExpenseLimit() { assert(_expenseLimit != NULL_EXPENSE || _primaryProject != null, “Expense Limit and Primary Project must not be null”); return(_expenseLimit != NULL_EXPENSE) ? _expenseLimit : _primaryProject.GetMemberExpenseLimit(); } Licensed Under Creative Commons by Naresh Jain 24

Slide 85: Long Method Licensed Under Creative Commons by Naresh Jain 25

Slide 86: Long Method Good OO code is easiest to understand and maintain with shorter methods with good names Long methods tend to be harder to read and understand Licensed Under Creative Commons by Naresh Jain 25

Slide 87: Long Method Good OO code is easiest to understand and maintain with shorter methods with good names Long methods tend to be harder to read and understand Remedies: Extract Method Replace Temp with Query Replace Method with Method Object. Decompose Conditional Licensed Under Creative Commons by Naresh Jain 25

Slide 88: Replace Temp with Query double basePrice = _quanity * _itemPrice; if(basePrice > 1000) { return basePrice * 0.95; } else { return basePrice * 0.98; } Licensed Under Creative Commons by Naresh Jain 26

Slide 89: Replace Temp with Query double basePrice = _quanity * if(getBasePrice() > 1000) { _itemPrice; return getBasePrice() * 0.95; if(basePrice > 1000) } { else { return basePrice * 0.95; return getBasePrice() * 0.98; } } else { double getBasePrice() { return basePrice * 0.98; return _quanitiy * _itemPrice; } } Licensed Under Creative Commons by Naresh Jain 26

Slide 90: Long parameter list Licensed Under Creative Commons by Naresh Jain 27

Slide 91: Long parameter list Functions should have as few parameters as possible. Licensed Under Creative Commons by Naresh Jain 27

Slide 92: Long parameter list Functions should have as few parameters as possible. Remedies: Replace Parameter with Method Preserve Whole Object Introduce Parameter Object Licensed Under Creative Commons by Naresh Jain 27

Slide 93: Introduce Parameter Object Licensed Under Creative Commons by Naresh Jain 28

Slide 94: Introduce Parameter Object Customer AmoutInvoicedIn(Date start, Date end) AmoutRecivedIn(Date start, Date end) AmoutOverdueIn(Date start, Date end) Licensed Under Creative Commons by Naresh Jain 28

Slide 95: Introduce Parameter Object Customer AmoutInvoicedIn(Date start, Date end) AmoutRecivedIn(Date start, Date end) AmoutOverdueIn(Date start, Date end) Customer AmoutInvoicedIn(DateRange range) AmoutRecivedIn(DateRange range) AmoutOverdueIn(DateRange range) Licensed Under Creative Commons by Naresh Jain 28

Slide 96: Switch Statements Licensed Under Creative Commons by Naresh Jain 29

Slide 97: Switch Statements Type cases are evil because they tend to be duplicated many times. Licensed Under Creative Commons by Naresh Jain 29

Slide 98: Switch Statements Type cases are evil because they tend to be duplicated many times. Remedies: Replace Type Code with Subclasses Replace Type Code with State / Strategy Replace Conditional with Polymorphism. Replace Parameter with Explicit Methods Introduce Null Object. Licensed Under Creative Commons by Naresh Jain 29

Slide 99: Replace Parameter with Explicit Methods void SetValue(String name, int value) { if(name.Equals(“height”)) { _height = value; return; } if(name.Equals(“width”)) { _width = value; return; } Trace.Assert(false, “Should never reach here”); } Licensed Under Creative Commons by Naresh Jain 30

Slide 100: Replace Parameter with Explicit Methods void SetValue(String name, int value) void SetHeight(int value) { { if(name.Equals(“height”)) _height = value; { } _height = value; return; } void SetWidth(int value) if(name.Equals(“width”)) { { _width = value; _width = value; } return; } Trace.Assert(false, “Should never reach here”); } Licensed Under Creative Commons by Naresh Jain 30

Slide 101: Inappropriate Naming Licensed Under Creative Commons by Naresh Jain 31

Slide 102: Inappropriate Naming Names given to variables (fields) and methods should be clear and meaningful. Licensed Under Creative Commons by Naresh Jain 31

Slide 103: Inappropriate Naming Names given to variables (fields) and methods should be clear and meaningful. A variable name should say exactly what it is. Which is better? private string s; OR private string salary; Licensed Under Creative Commons by Naresh Jain 31

Slide 104: Inappropriate Naming Names given to variables (fields) and methods should be clear and meaningful. A variable name should say exactly what it is. Which is better? private string s; OR private string salary; A method should say exactly what it does. Which is better? public double calc (double s) public double calculateFederalTaxes (double salary) Licensed Under Creative Commons by Naresh Jain 31

Slide 105: Refactoring & Patterns There is a natural relation between patterns and refactorings. Patterns are where you want to be; refactorings are ways to get there from somewhere else. - Martin Fowler Licensed Under Creative Commons by Naresh Jain 32

Slide 106: Refactoring to Patterns Licensed Under Creative Commons by Naresh Jain 33

Slide 107: Refactoring to Patterns Creation – creation of objects Licensed Under Creative Commons by Naresh Jain 33

Slide 108: Refactoring to Patterns Creation – creation of objects Simplification – code simplification Licensed Under Creative Commons by Naresh Jain 33

Slide 109: Refactoring to Patterns Creation – creation of objects Simplification – code simplification Generalization – code abstraction Licensed Under Creative Commons by Naresh Jain 33

Slide 110: Refactoring to Patterns Creation – creation of objects Simplification – code simplification Generalization – code abstraction Protection – improve protection of existing code Licensed Under Creative Commons by Naresh Jain 33

Slide 111: Refactoring to Patterns Creation – creation of objects Simplification – code simplification Generalization – code abstraction Protection – improve protection of existing code Accumulation – information accumulation code Licensed Under Creative Commons by Naresh Jain 33

Slide 112: Refactoring to Patterns Creation – creation of objects Simplification – code simplification Generalization – code abstraction Protection – improve protection of existing code Accumulation – information accumulation code Utilities – misc Licensed Under Creative Commons by Naresh Jain 33

Slide 113: How to refactor Legacy Code? Licensed Under Creative Commons by Naresh Jain 34

Slide 114: How to refactor Legacy Code? Identify change points Licensed Under Creative Commons by Naresh Jain 34

Slide 115: How to refactor Legacy Code? Identify change points Find an inflection point Licensed Under Creative Commons by Naresh Jain 34

Slide 116: How to refactor Legacy Code? Identify change points Find an inflection point Cover the inflection point Licensed Under Creative Commons by Naresh Jain 34

Slide 117: How to refactor Legacy Code? Identify change points Find an inflection point Cover the inflection point Break external dependencies Licensed Under Creative Commons by Naresh Jain 34

Slide 118: How to refactor Legacy Code? Identify change points Find an inflection point Cover the inflection point Break external dependencies Break internal dependencies Licensed Under Creative Commons by Naresh Jain 34

Slide 119: How to refactor Legacy Code? Identify change points Find an inflection point Cover the inflection point Break external dependencies Break internal dependencies Write tests Licensed Under Creative Commons by Naresh Jain 34

Slide 120: How to refactor Legacy Code? Identify change points Find an inflection point Cover the inflection point Break external dependencies Break internal dependencies Write tests Make changes Licensed Under Creative Commons by Naresh Jain 34

Slide 121: How to refactor Legacy Code? Identify change points Find an inflection point Cover the inflection point Break external dependencies Break internal dependencies Write tests Make changes Refactor the covered code. Licensed Under Creative Commons by Naresh Jain 34

Slide 122: Essential Reading Licensed Under Creative Commons by Naresh Jain 35

Slide 123: Refactoring Hands-on We’ll use an open source project to apply refactoring lessons Make sure your laptops are setup with the project Form pairs and each pair picks up a module/package of the open source project. Licensed Under Creative Commons by Naresh Jain 36

Slide 124: Refactoring Hands-on... You will be introduced to 2-3 code smells at a time Apply lessons form working with legacy code to write tests around your inflection point Apply lessons from refactoring and refactoring to patterns to eradicate the code smells Repeat last 3 steps, till we run out of time Licensed Under Creative Commons by Naresh Jain 37

Slide 125: Thank you Refactoring Fest Naresh Jain naresh@agilefaqs.com Licensed Under Creative Commons by Naresh Jain 38