2. • Senior Developer / Team Lead at
Mayflower GmbH
• Reporting and Rating Apps
• QA and PHP 5 Migration
consultings
• PHP since 1999 (3.0.16)
• phpMyFAQ since 2001
Mayflower GmbH 2009 2
3. Who are you?
• What are you doing?
• What‘s your team size?
• Using MVC?
• Who‘s using Continous Integration?
• PHPUnit?
• 80% code coverage?
Mayflower GmbH 2009 3
4. Your projects...
• What‘s your average project lifetime?
• Is there PHP code more than 5 years old?
• How many lines of code?
• How many change requests per year?
• Has there been a specification?
• Were all features in the first
release as specified?
Mayflower GmbH 2009 4
5. What is Refactoring?
„Refactoring is a disciplined technique for
restructuring an existing body of code, altering
its internal structure without changing its
external behavior.“
-Martin Fowler, www.refactoring.com
Mayflower GmbH 2009 5
7. A PHP Project in 2000 ...
• no coding standards, no PHPDoc
• no MVC, no Design Patterns
• if you were lucky, someone used a
template system
• nobody cared about XSS or CSRF
a lot of changes in business logics
• never got refactored,
documentated or even tested ...
Mayflower GmbH 2009 7
9. In the year 2009
• change requests get more and
more expensive
• the bug rate is always
increasing
• the development team
motivation is decreasing
• requirement changes are
almost impossible
• new team members need a lot
of time to be productive
Mayflower GmbH 2009 9
10. Management point of view
Costs per Change Request
rising frequency
Dead end!
Benefit per Change Request
Mayflower GmbH 2009 10
13. Don‘t refactor ...
• weeks before a
important release
• only with a lot of junior
developers
• parallel with
development tasks
Mayflower GmbH 2009 13
14. Before starting refactoring
• define a coding standard
• avoids spaghetti code
• speeds up maintainability
• improves productivity
• fix your API specs
• complete your documentation
Mayflower GmbH 2009 14
15. During the refactoring...
• stay calm
• take a lot of good developers and
a bunch of juniors
• write tests, tests, tests
• don‘t let developer refactor their
own code
• don‘t let junior developers
refactor alone
Mayflower GmbH 2009 15
16. About Unittests
• Testing is essential during refactoring
• Problems
• most of old code isn‘t
„unittestable“
• API breaks during refacotoring
• Solution
• Selenium tests instead
• iterative refactoring
Mayflower GmbH 2009 16
17. (c) BMW AG
Okay, let‘s start!
Mayflower GmbH 2009 17
18. Back to Martin Fowler
„Refactoring is a disciplined technique for
restructuring an existing body of code, altering
its internal structure without changing its
external behavior.“
-Martin Fowler, www.refactoring.com
Mayflower GmbH 2009 18
20. Renaming
/**
* Remove a word from the stop word dictionary
*
* @param integer $id
*
* @return void
*/
public function remove($id)
{
$sql = sprintf(quot;DELETE FROM $this->tablename WHERE id = %d AND lang =
'%s'quot;, $id, $this->language);
$this->db->query($sql);
}
Mayflower GmbH 2009 20
21. Renaming
/**
* Remove a word from the stop word dictionary
*
* @param integer $stopword_id ID of the stop word
*
* @return void
*/
public function remove($stopword_id)
{
$delete = sprintf(quot;DELETE FROM $this->tablename WHERE id = %d AND lang =
'%s'quot;, $stopword_id, $this->language);
$this->db->query($delete);
}
Mayflower GmbH 2009 21
22. Restructuring
/**
* Remove a word from the stop word dictionary
*
* @param integer $stopword_id ID of the stop word
*
* @return void
*/
public function remove($stopword_id)
{
$delete = sprintf(quot;DELETE FROM $this->tablename WHERE id = %d AND lang =
'%s'quot;, $stopword_id, $this->language);
$this->db->query($delete);
}
Mayflower GmbH 2009 22
23. Restructuring
/**
* Remove a word from the stop word dictionary
*
* @param integer $stopword_id ID of the stop word
*
* @return void
*/
public function remove($stopword_id)
{
$delete = sprintf(quot;DELETE FROM %s WHERE id = %d AND lang = '%s'quot;,
$this->tablename,
$stopword_id,
$this->language);
$this->db->query($delete);
}
Mayflower GmbH 2009 23
24. Extraction
/**
* Remove a word from the stop word dictionary
*
* @param integer $stopword_id ID of the stop word
*
* @return void
*/
public function remove($stopword_id)
{
$delete = sprintf(quot;DELETE FROM %s WHERE id = %d AND lang = '%s'quot;,
$this->tablename,
$stopword_id,
$this->language);
$this->db->query($delete);
}
Mayflower GmbH 2009 24
25. Extraction
public function remove($stopword_id)
{
$delete = sprintf(quot;DELETE FROM %s WHERE id = %d AND lang = '%s'quot;,
$this->tablename,
$stopword_id,
$this->language);
$this->_execute($delete);
}
private function _execute($query)
{
return $this->db->query($query)
}
Mayflower GmbH 2009 25
26. Changing signature
/**
* Remove a word from the stop word dictionary
*
* @param integer $id ID of the stop word
*
* @return void
*/
public function remove($stopword_id)
{
$delete = sprintf(quot;DELETE FROM %s WHERE id = %d AND lang = '%s'quot;,
$this->tablename,
$stopword_id,
$this->language);
$this->db->query($delete);
}
Mayflower GmbH 2009 26
27. Changing signature
/**
* Remove a word from the stop word dictionary
*
* @param integer $stopword_id ID of the stop word
* @param boolean $logging Log removal? Default: false
*
* @return void
*/
public function remove($stopword_id, $logging = false)
{
$delete = sprintf(quot;DELETE FROM %s WHERE id = %d AND lang = '%s'quot;,
$this->tablename,
$stopword_id,
$this->language);
if ($logging) {
$this->_logAction('removal', $stopword_id);
}
$this->db->query($delete);
}
Mayflower GmbH 2009 27
30. Pull up / Pull down
x
x x
Mayflower GmbH 2009 30
31. Tips & Tricks
• Always add PHPDoc if it‘s missing
• Never trust automatic refactoring of IDEs
• Don‘t do refactoring for fun
• Write as much unittests as possible
Mayflower GmbH 2009 31
33. Thank you very much for your attention!
Thorsten Rinne
Mayflower GmbH
Mannhardtstraße 6
D-80538 München
+49 (0) 89 24 20 54 - 31
thorsten.rinne@mayflower.de
Mayflower GmbH 2009 33