SlideShare uma empresa Scribd logo
1 de 22
Modernising Legacy
      Code
     Sam Harwood
What is Legacy Code?
Old


Fragile


Incomprehensible


Not under test
Why Modernise Legacy Code?
New development


Bug fixes


Change requests


To reduce maintenance costs
When to Refactor Legacy Code
There's no smoke...


'It's not safe to refactor'


Key element of application


'My boss told me not to'
An Iterative Approach
Start small


Identify target areas


Deploy, deploy, deploy!
Process Plan
Break dependencies with minimal changes;
 apply tests


Make small changes


Clean up tests


Refactor to clean code
Untestable Behaviour
DB connectivity
Web services
Global vars
exit();
File work
System calls
echo(), print(), var_dump(), …
Memcache etc.
How to Break Dependencies
Partial mockery


Dependency injection


Out-of-context testing
Option 1: Partial Mockery
public function __construct() {
    $dbh = new DbConnection('localhost', 'db', 'user', 'pass',
        3306);
    if ($dbh->connection_fail) {exit;}
    if ($GLOBALS['debug mode']) {
        print 'Constructing!';
    }
    $this->doOtherThings();
}
Partial Mocks cont.
public function __construct() {
    $dbh = $this->_getDbConnection();
    //...
}

/**
  * @return DbConnection
  */
protected function _getDbConnection() {
     return new DbConnection('localhost', 'db', 'user', 'pass',
         3306);
}
Partial Mocks cont.
public function setUp() {
    $this->_objectUnderTest = $this->getMock('MyClass',
        array('_getDbConnection', '_doExit', '_sendHttpQuery'),
        array(), '', '', true);

    $this->_mockDbConnection = $this->getMock('DbConnection');

    $this->_objectUnderTest->expects($this->any())
                           ->method('_getDbConnection')
                           ->will($this->returnValue($this->
                                 _mockDbConnection));
}
Option 2: Dependency Injection
public function __construct() {
    $dbh = $this->_yadifContainer->getComponent('DbConnection');
    //...
}
Option 3: Out-of-Context Testing
 Fake objects


 set_include_path('');


 runkit.internal_override &
  runkit_function_redefine()
Next Steps
Provide satisfactory test coverage, and
 refactor...


Add tests for constructor
Comment code to help plan tests
Cover other code addressed in this iteration
Add Comments...
public function massiveMethod($param = 'hello world') {

   // Check if DB knows how awesome we are
   $dbConnection = $this->_getDbConnection();
   $resultSet = $dbConnection->executeSql(
       'SELECT group_of_developers FROM london WHERE everyone_is
       LIKE "%we're the best php%" GROUP BY miles');
   $dbRes = count($resultSet) > 0;

   // Calculate something else
   $aString = $param;
   $aString .= 'more string';
   $aString .= 'more string';
   $aString .= 'more string';
   $aString .= 'more string';
...Remove Comments
public function massiveMethod($param = 'hello world') {


   $dbRes = $this->_checkIfDbKnowsHowAwesomeWeAre();




   $aString   = $this->_generateSomeString($param);
Things to Bear in Mind When
Breaking Up Large Functions

Method name reflects comment


Test section before moving it


Parameter count
Looking Inside Large Methods
Sensing variables
  if () {
      foreach () {
          if () {
              $this->_privateAttrib = 'something';
              $this->sensingVariable = true;
          }
      }
  }


Indecent exposure


Partially mock most of class
Cleaning Up Production Code
Minimise public API


Remove unnecessary comments


Roll out dependency injection


Be sure to remove methods for partial
 mocking
Refactoring Tests
Inject mock objects via DI


Stop testing partial mock


Remove 'out-of-context' setup


Remove single-line constructor tests,
 sensing variable tests etc.
Summary
Break dependencies


Apply tests


Refactor production code


Refactor tests
samthephpdev@gmail.com

     @AgileTillIDie

Mais conteúdo relacionado

Mais procurados

Benchmarking Perl Lightning Talk (NPW 2007)
Benchmarking Perl Lightning Talk (NPW 2007)Benchmarking Perl Lightning Talk (NPW 2007)
Benchmarking Perl Lightning Talk (NPW 2007)
brian d foy
 

Mais procurados (20)

14922 java script built (1)
14922 java script built (1)14922 java script built (1)
14922 java script built (1)
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Benchmarking Perl Lightning Talk (NPW 2007)
Benchmarking Perl Lightning Talk (NPW 2007)Benchmarking Perl Lightning Talk (NPW 2007)
Benchmarking Perl Lightning Talk (NPW 2007)
 
Deploying Straight to Production
Deploying Straight to ProductionDeploying Straight to Production
Deploying Straight to Production
 
The secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutThe secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you about
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Oracle PL/SQL - Creative Conditional Compilation
Oracle PL/SQL - Creative Conditional CompilationOracle PL/SQL - Creative Conditional Compilation
Oracle PL/SQL - Creative Conditional Compilation
 
The art of readable code (ch1~ch4)
The art of readable code (ch1~ch4)The art of readable code (ch1~ch4)
The art of readable code (ch1~ch4)
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
Moodle Quick Forms
Moodle Quick FormsMoodle Quick Forms
Moodle Quick Forms
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHP
 
Using of TDD practices for Magento
Using of TDD practices for MagentoUsing of TDD practices for Magento
Using of TDD practices for Magento
 
What's new with PHP7
What's new with PHP7What's new with PHP7
What's new with PHP7
 

Destaque

Practical way to experience of Specification by Example
Practical way to experience of Specification by ExamplePractical way to experience of Specification by Example
Practical way to experience of Specification by Example
Larry Cai
 

Destaque (20)

Fault-tolerance on the Cheap: Making Systems That (Probably) Won't Fall Over
Fault-tolerance on the Cheap: Making Systems That (Probably) Won't Fall Over Fault-tolerance on the Cheap: Making Systems That (Probably) Won't Fall Over
Fault-tolerance on the Cheap: Making Systems That (Probably) Won't Fall Over
 
Tour d'horizon de Domain-Driven Design Avril 2012 autour d'un retour d'expéri...
Tour d'horizon de Domain-Driven Design Avril 2012 autour d'un retour d'expéri...Tour d'horizon de Domain-Driven Design Avril 2012 autour d'un retour d'expéri...
Tour d'horizon de Domain-Driven Design Avril 2012 autour d'un retour d'expéri...
 
Augmenting your Technical Documentation with User-Generated Content
Augmenting your Technical Documentation with User-Generated ContentAugmenting your Technical Documentation with User-Generated Content
Augmenting your Technical Documentation with User-Generated Content
 
Ur Domain Haz Monoids
Ur Domain Haz MonoidsUr Domain Haz Monoids
Ur Domain Haz Monoids
 
Death to project documentation with eXtreme Programming
Death to project documentation with eXtreme ProgrammingDeath to project documentation with eXtreme Programming
Death to project documentation with eXtreme Programming
 
Refactor your specs! Øredev 2013
Refactor your specs! Øredev 2013Refactor your specs! Øredev 2013
Refactor your specs! Øredev 2013
 
Instrumentation as a Living Documentation: Teaching Humans About Complex Systems
Instrumentation as a Living Documentation: Teaching Humans About Complex SystemsInstrumentation as a Living Documentation: Teaching Humans About Complex Systems
Instrumentation as a Living Documentation: Teaching Humans About Complex Systems
 
Ur Domain Haz Monoids DDDx NYC 2014
Ur Domain Haz Monoids DDDx NYC 2014Ur Domain Haz Monoids DDDx NYC 2014
Ur Domain Haz Monoids DDDx NYC 2014
 
Bdd for legacy system
Bdd for legacy systemBdd for legacy system
Bdd for legacy system
 
Writing the docs
Writing the docsWriting the docs
Writing the docs
 
Documentation avoidance for developers
Documentation avoidance for developersDocumentation avoidance for developers
Documentation avoidance for developers
 
Practical way to experience of Specification by Example
Practical way to experience of Specification by ExamplePractical way to experience of Specification by Example
Practical way to experience of Specification by Example
 
Domain-Driven Design in legacy application
Domain-Driven Design in legacy applicationDomain-Driven Design in legacy application
Domain-Driven Design in legacy application
 
(Moonconf 2016) Fetching Moths from the Works: Correctness Methods in Software
(Moonconf 2016) Fetching Moths from the Works: Correctness Methods in Software(Moonconf 2016) Fetching Moths from the Works: Correctness Methods in Software
(Moonconf 2016) Fetching Moths from the Works: Correctness Methods in Software
 
Selling ddd
Selling dddSelling ddd
Selling ddd
 
Websauna - introduction to the best Python web framework
Websauna - introduction to the best Python web frameworkWebsauna - introduction to the best Python web framework
Websauna - introduction to the best Python web framework
 
Cross mobile testautomation mit Xamarin & SpecFlow
Cross mobile testautomation mit Xamarin & SpecFlowCross mobile testautomation mit Xamarin & SpecFlow
Cross mobile testautomation mit Xamarin & SpecFlow
 
DDD session BrownBagLunch (FR)
DDD session BrownBagLunch (FR)DDD session BrownBagLunch (FR)
DDD session BrownBagLunch (FR)
 
Impact Maps/Story Maps - liefern was wirklich zählt
Impact Maps/Story Maps - liefern was wirklich zähltImpact Maps/Story Maps - liefern was wirklich zählt
Impact Maps/Story Maps - liefern was wirklich zählt
 
Scrum + bdd + ddd
Scrum + bdd + dddScrum + bdd + ddd
Scrum + bdd + ddd
 

Semelhante a Modernising Legacy Code

Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)
Pavel Novitsky
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
mfrost503
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
archwisp
 

Semelhante a Modernising Legacy Code (20)

Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Php Unit With Zend Framework Zendcon09
Php Unit With Zend Framework   Zendcon09Php Unit With Zend Framework   Zendcon09
Php Unit With Zend Framework Zendcon09
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)Meet Magento Belarus debug Pavel Novitsky (eng)
Meet Magento Belarus debug Pavel Novitsky (eng)
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStorm
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
My Development Story
My Development StoryMy Development Story
My Development Story
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards
 

Último

Último (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 

Modernising Legacy Code

  • 1. Modernising Legacy Code Sam Harwood
  • 2. What is Legacy Code? Old Fragile Incomprehensible Not under test
  • 3. Why Modernise Legacy Code? New development Bug fixes Change requests To reduce maintenance costs
  • 4. When to Refactor Legacy Code There's no smoke... 'It's not safe to refactor' Key element of application 'My boss told me not to'
  • 5. An Iterative Approach Start small Identify target areas Deploy, deploy, deploy!
  • 6. Process Plan Break dependencies with minimal changes; apply tests Make small changes Clean up tests Refactor to clean code
  • 7. Untestable Behaviour DB connectivity Web services Global vars exit(); File work System calls echo(), print(), var_dump(), … Memcache etc.
  • 8. How to Break Dependencies Partial mockery Dependency injection Out-of-context testing
  • 9. Option 1: Partial Mockery public function __construct() { $dbh = new DbConnection('localhost', 'db', 'user', 'pass', 3306); if ($dbh->connection_fail) {exit;} if ($GLOBALS['debug mode']) { print 'Constructing!'; } $this->doOtherThings(); }
  • 10. Partial Mocks cont. public function __construct() { $dbh = $this->_getDbConnection(); //... } /** * @return DbConnection */ protected function _getDbConnection() { return new DbConnection('localhost', 'db', 'user', 'pass', 3306); }
  • 11. Partial Mocks cont. public function setUp() { $this->_objectUnderTest = $this->getMock('MyClass', array('_getDbConnection', '_doExit', '_sendHttpQuery'), array(), '', '', true); $this->_mockDbConnection = $this->getMock('DbConnection'); $this->_objectUnderTest->expects($this->any()) ->method('_getDbConnection') ->will($this->returnValue($this-> _mockDbConnection)); }
  • 12. Option 2: Dependency Injection public function __construct() { $dbh = $this->_yadifContainer->getComponent('DbConnection'); //... }
  • 13. Option 3: Out-of-Context Testing Fake objects set_include_path(''); runkit.internal_override & runkit_function_redefine()
  • 14. Next Steps Provide satisfactory test coverage, and refactor... Add tests for constructor Comment code to help plan tests Cover other code addressed in this iteration
  • 15. Add Comments... public function massiveMethod($param = 'hello world') { // Check if DB knows how awesome we are $dbConnection = $this->_getDbConnection(); $resultSet = $dbConnection->executeSql( 'SELECT group_of_developers FROM london WHERE everyone_is LIKE "%we're the best php%" GROUP BY miles'); $dbRes = count($resultSet) > 0; // Calculate something else $aString = $param; $aString .= 'more string'; $aString .= 'more string'; $aString .= 'more string'; $aString .= 'more string';
  • 16. ...Remove Comments public function massiveMethod($param = 'hello world') { $dbRes = $this->_checkIfDbKnowsHowAwesomeWeAre(); $aString = $this->_generateSomeString($param);
  • 17. Things to Bear in Mind When Breaking Up Large Functions Method name reflects comment Test section before moving it Parameter count
  • 18. Looking Inside Large Methods Sensing variables if () { foreach () { if () { $this->_privateAttrib = 'something'; $this->sensingVariable = true; } } } Indecent exposure Partially mock most of class
  • 19. Cleaning Up Production Code Minimise public API Remove unnecessary comments Roll out dependency injection Be sure to remove methods for partial mocking
  • 20. Refactoring Tests Inject mock objects via DI Stop testing partial mock Remove 'out-of-context' setup Remove single-line constructor tests, sensing variable tests etc.
  • 21. Summary Break dependencies Apply tests Refactor production code Refactor tests
  • 22. samthephpdev@gmail.com @AgileTillIDie