Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Practical Refactoring (NomadPHP)

Practical Refactoring (NomadPHP)

Every codebase builds up some legacy over time, there is hardly a way around that. But how you handle the legacy is what seperates a good developer from a great developer. Refactoring code should be a part of your every day work, but how to effectively refactor your code? How to ensure the quality of the new code as well as the fact that refactoring code won’t break something elsewhere in your code? During this talk we’ll go into the why, when and how of refactoring.

Stefan Koopmanschap

August 23, 2013
Tweet

More Decks by Stefan Koopmanschap

Other Decks in Technology

Transcript

  1. Refactoring • What is it? • Why would we do

    it? • When do we do it? Thursday, August 22, 13
  2. Refactoring • What is it? • Why would we do

    it? • When do we do it? • How do we do it? Thursday, August 22, 13
  3. Code refactoring is the process of changing a computer program's

    internal structure without modifying its external behavior or existing functionality. Thursday, August 22, 13
  4. Code quality • Lessen complexity • Increase readability • Increase

    maintainability • Upgrade performance Thursday, August 22, 13
  5. Code quality • Lessen complexity • Increase readability • Increase

    maintainability • Upgrade performance • Increase stability Thursday, August 22, 13
  6. What’s in it for them? • Less bugs • Faster

    development Thursday, August 22, 13
  7. What’s in it for them? • Less bugs • Faster

    development • It is part of the process Thursday, August 22, 13
  8. Example if ($order) { if ( ! $order->retryPossible()) { throw

    new BadRequestHttpException('Order already exists for ShoppingCart'); } } Thursday, August 22, 13
  9. Example if ($order) { if ( ! $order->retryPossible()) { throw

    new BadRequestHttpException('Order already exists for ShoppingCart'); } } public function isOpen() { return $this->getOrder() === null; } Thursday, August 22, 13
  10. Example public function isOpen() { return ( $this->getOrder() === null

    || $this->getOrder()->retryPossible() === true ); } Thursday, August 22, 13
  11. Continuously • Your code gets better, one step at a

    time • You don’t spend ages on refactoring, it’s part of the project Thursday, August 22, 13
  12. Isolation • Small, independant classes and methods • Class or

    method too big? refactor again! Thursday, August 22, 13
  13. mysql_connect('127.0.0.1', 'root'); mysql_select_db('refactoring'); $newsSQL = "SELECT * FROM NEWS ORDER

    BY published_at DESC"; $result = mysql_query($newsSQL); while($row = mysql_fetch_assoc($result)) { echo $row['published_at'] . ': ' . $row['title'].'<br />'; echo nl2br($row['message']) . '<br /><br />'; } Thursday, August 22, 13
  14. require_once('config.php'); $db = new PDO('mysql:dbname='.$db_name.';host='.$db_server, $db_user, $db_pass); $newsSQL = "SELECT

    * FROM NEWS ORDER BY published_at DESC"; $stmt = $db->prepare($newsSQL); $stmt->execute(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo $row['published_at'] . ': ' . $row['title'].'<br />'; echo nl2br($row['message']) . '<br /><br />'; } Thursday, August 22, 13
  15. $db_server = '127.0.0.1'; $db_user = 'root'; $db_pass = ''; $db_name

    = 'refactoring'; require_once('config.php'); $db = new PDO('mysql:dbname='.$db_name.';host='.$db_server, $db_user, $db_pass); $newsSQL = "SELECT * FROM NEWS ORDER BY published_at DESC"; $stmt = $db->prepare($newsSQL); $stmt->execute(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo $row['published_at'] . ': ' . $row['title'].'<br />'; echo nl2br($row['message']) . '<br /><br />'; } Thursday, August 22, 13
  16. class NewsRepository { private $db; public function __construct($db) { $this->db

    = $db; } public function getAllNews() { $newsSQL = "SELECT * FROM NEWS ORDER BY published_at DESC"; $stmt = $this->db->prepare($newsSQL); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } } Thursday, August 22, 13
  17. require_once('config.php'); require_once('NewsRepository.php'); $db = new PDO('mysql:dbname='.$db_name.';host='.$db_server, $db_user, $db_pass); $newsRepo =

    new NewsRepository($db); $news = $newsRepo->getAllNews(); foreach($news as $row) { echo $row['published_at'] . ': ' . $row['title'].'<br />'; echo nl2br($row['message']) . '<br /><br />'; } Thursday, August 22, 13
  18. Tests • Tests are contracts and verifications • Contract: Code

    should do what is tested Thursday, August 22, 13
  19. Tests • Tests are contracts and verifications • Contract: Code

    should do what is tested • Verification: Does it do what is tested? Thursday, August 22, 13
  20. Tests • Tests are contracts and verifications • Contract: Code

    should do what is tested • Verification: Does it do what is tested? • Don’t change the tests Thursday, August 22, 13
  21. Tests • Tests are contracts and verifications • Contract: Code

    should do what is tested • Verification: Does it do what is tested? • Don’t change the tests • Just expand the test Thursday, August 22, 13
  22. <?php class NewsRepositoryTest extends PHPUnit_Framework_TestCase { $private $MockDb; public function

    setUp() { // here we set up the mock class $this->MockDb = new MockDb(); } public function testGetAllNews() { $newsRepo = new NewsRepository($this->MockDb); // mock repo returns 2 newsitems $news = $newsRepo->getAllNews(); $this->assertEquals(2, count($news)); } } Thursday, August 22, 13
  23. public function getAllNews($limit = null) { $newsSQL = "SELECT *

    FROM NEWS ORDER BY published_at DESC"; if ( ! is_null($limit)) { $newsSQL .= " LIMIT 0, " . $limit; } $stmt = $this->db->prepare($newsSQL); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } Thursday, August 22, 13
  24. public function testGetAllNews() { $newsRepo = new NewsRepository($this->MockDb); // mock

    repo returns 2 newsitems $news = $newsRepo->getAllNews(); $this->assertEquals(2, count($news)); // new functionality: limit the newsitems $news = $newsRepo->getAllNews(1); $this->assertEquals(1, count($news)); } Thursday, August 22, 13
  25. Tests • Untested code? • Write tests before refactoring if

    possible • Write tests during refactoring Thursday, August 22, 13
  26. Tests • Untested code? • Write tests before refactoring if

    possible • Write tests during refactoring • Tested code? Thursday, August 22, 13
  27. Tests • Untested code? • Write tests before refactoring if

    possible • Write tests during refactoring • Tested code? • Expand those tests Thursday, August 22, 13
  28. Your IDE can help • Most IDE’s have refactoring support

    • Scan for usage of methods and classes • http://qafoo.com/blog/ 041_refactoring_browser.html Thursday, August 22, 13
  29. So, refactoring • What is it? • Why would we

    do it? Thursday, August 22, 13
  30. So, refactoring • What is it? • Why would we

    do it? • When do we do it? Thursday, August 22, 13
  31. So, refactoring • What is it? • Why would we

    do it? • When do we do it? • How do we do it? Thursday, August 22, 13