SlideShare una empresa de Scribd logo
1 de 80
Descargar para leer sin conexión
ving
Li
with
Legacy
         Code
@rowan_m
@rowan_m



Plusnet




           Ibuildings
What is
“Legacy Code”?
What is
“Legacy Code”?
   Code without
       tests

    Code you've
    “inherited”

    Code no-one
    understands

   Technical debt
Who has
   never
  created
Legacy Code?
My own
 little

story
Pragmatic, not ideal
                               istic




My own
 little

story
Starting a project
Aim to understand
   the concepts
 and motivations
Try using
the application
Find and then read
     any / all
  documentation
Official:             Che
Project brief   ( )      c   kli
Requirements    ( )             st
Tech. Spec.     ( )

Actual:
Emails          ( )
Meeting notes   ( )

Progress:
Gant charts     ( )
Burndowns       ( )
Overtime logs   ( )

Quality:
Bug tracker     ( )
Complaints      ( )
User Forums     ( )
Talk to the
original developers
Talk to the users




     … especially the
     “different” ones
Approaching
  the code
Catalogue the
live platform
& environment
Recreate it!
Deploy the code
PHP:                          Che
php.ini               (   )      c   kli
PEAR / PECL modules   (   )             st
Compile options       (   )
Patches               (   )

The Rest:
OS                    (   )
Package manager       (   )
Web server            (   )
Web server modules    (   )
Site config.          (   )
Database              (   )
Cache                 (   )
JS libraries          (   )
Firewall rules        (   )
Proxies               (   )
Services running      (   )
Time to enter
  The Code
Time to enter
  The Code




    Reading

Static analysis

Dynamic analysis
http://www.phpdoc.org/
      doc
php

                  Title

        phpdoc -ti 'Sweet Application' 
               -pp -o HTML:Smarty:PHP 
               -d Libraries               Style
               -t Docs
 Code in here



                          Docs out here!
Beware of type-hiding!


                    Type-hinting
/**
 * @param array $opts Current options
 * @return array Options with flag set
 */
function setFlag(array $opts) {
    $opts['flag'] = true;
    return $opts;
}



                                                 Type-hiding
                       /**
                        * @param int $fullPence Full price in pence
                        * @return float Discounted price in pence
                        */
                       function applyDiscount($fullPence) {
                           return ($fullPence * 0.8);
                       }
ygen
dox

               doxygen -s -g ~/doxy.conf
               vim ~/doxy.conf

               # edit at least this
Code in here   OUPUT_DIRECTORY
               # play with the rest

               cd ~/dev/project
                                       Docs out here
               doxygen ~/doxy.conf



  http://www.stack.nl/~dimitri/doxygen/
http://ctags.sourceforge.net/
    ta gs
c
                Code in here
#!/bin/bash                         Tags out here
cd ~/Dev/ &&
ctags-exuberant -f ~/.vimtags 
-h ".php" -R 
--exclude=".git" 
--links=no 
--totals=yes 
--tag-relative=yes 
--PHP-kinds=+cf 
--regex-PHP='/abstracts+classs+([^ ]+)/1/c/' 
--regex-PHP='/interfaces+([^ ]+)/1/c/' 
--regex-PHP='/(publics+|statics+|abstracts+|protecteds+|privates+) ↵
            functions+&?s*([^ (]+)/2/f/'


                                       Voodoo
ml   http://www.bouml.fr/
bou
ml   http://bouml.free.fr/
bou
ml   http://bouml.free.fr/
bou
ml   http://bouml.free.fr/
bou
ml   http://bouml.free.fr/
bou
ml   http://bouml.free.fr/
bou
ou ml
b
ffer
        esni
co    d

rowan@swordbean:~/Dev/ZendFramework-1.9.4/library/Zend/Service$ phpcs 
                                                              --standard=Zend Exception.php

FILE: /home/rowan/Dev/ZendFramework-1.9.4/library/Zend/Service/Exception.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AND 2 WARNING(S) AFFECTING 3 LINE(S)
--------------------------------------------------------------------------------
 17 | WARNING | Line exceeds 80 characters; contains 87 characters
 32 | WARNING | Line exceeds 80 characters; contains 87 characters
 36 | ERROR   | Opening class brace must be on a line by itself
 36 | ERROR   | Closing brace must be on a line by itself
--------------------------------------------------------------------------------




 http://pear.php.net/package/PHP_CodeSniffer/
t in uous
Con        io n
Inte grat

        http://jenkins-ci.org/


     http://phpundercontrol.org/


      http://sismo.sensiolabs.org/
Decisi
         on tim
               e!
Decisi
                          on tim
                                e!


  Ign
cod ore
   e a    it ,
       nyw
           ay


                                      a cto r,
                                   ref est
                              ite, st, t
                          Rewr , te
                            test
Ignore it,
code anyway
Ignore it,
code anyway




Please don't.
Ignore it,
code anyway




Please don't.




         however...
Deadlines, clients,
    money, etc.
Deadlines, clients,
    money, etc.



  Make everyone
aware of the risks




     Secure a
follow-up project
Why do you need the code?
Why do you need the code?


        simple


   Library dependency

   Adding new behaviour

   Changing behaviour

          complex
Isolate
legacy dependencies
Isolate
legacy dependencies



      Create an
anti-corruption layer
Complete isolation




      Create a
   legacy service
Partial isolation




   Wrapper classes
     or methods
Wrapper class
<?php
include('/home/victorvon/secrets.inc');

/**
 * @param array $person willing volunteer
 */
function extract_brain(&$person) {
    $brain = $person['brain'];
    unset($person['brain']);

}
    return $brain;                             Some code
/**
                                               you need
 * @param array $person
 * @return bool living or not
                                                   :(
 */
function create_life($person) {
    require_once(LIB_DIR.'../nuts_n_bolts.inc');
    kerzap();
    $person['living'] = true;
    return $person;
}
?>
class VictorWrapper
{                                            Wrapper class
    public function __construct()
   {
        require_once '/home/victorvon/tragedy.php';
    }

    public function extractBrain(Person $p) {
        // format to legacy style
        $pLgcy = $this->toArray($p);
        // run legacy code
        $bLgy = extract_brain($pLgcy);
        // format to new style
        $p = $this->toPerson($pLgcy);             Some code
        $b = $this->toBrain($bLgcy);
        return array($p, $b);                    you can use
    }
                                                      :)
     public function createLife(Person $p)
    {
         // validate
         if ($person->isAlive()) throw new LivingException();
         // format to legacy style
         $pLgcy = $this->toArray($p);
         // run legacy code
        $pLgy = create_life($pLgcy);
        // format to new style
        return $this->toPerson($pLgcy);
    }
}
Changing the code
Changing the code



     Take an
  incremental
    approach

 Commit to 1 day
    at a time
Why?



Difficult to estimate

Hidden dependencies

 Unknown behaviour
1. Get it into
version control
2. Identify the
inflection point
3. Create integration
  & acceptance tests
4. Set up your
continuous integration
     environment
5. Rewrite and refactor!
Types
   of
changes
Mixed → Procedural
includes


   HTML              PHP      HTML


HTML             PHP           HTML


 PHP          HTML           PHP


   PHP


       HTML            PHP     HTML


       HTML            PHP     HTML


   PHP
includes


                                                    function


                                                    function


                                                    function
               includes


   HTML              PHP      HTML         HTML       echo     HTML


HTML             PHP           HTML   HTML           echo       HTML


 PHP          HTML           PHP      if              HTML            if


   PHP                                 foreach


       HTML            PHP     HTML          HTML       echo   HTML


       HTML            PHP     HTML          HTML       echo   HTML


   PHP                                 foreach
Procedural → OO
includes



function



function



function




function




free code
includes      includes



function    static method



function    static method



function    static method




function    static method




free code   static method
includes      includes       includes



function    static method   constructor



function    static method     method



function    static method     method




function    static method     method




free code   static method     method
Sprout method / class
public function createInvoice(Account $acc, array $charges)
{
    $invoice = new Invoice();

    foreach ($charges as $chg) {
        $invoice->addLine($chg->getDesc(), $chg->getAmount());
    }

    return $invoice;
}
                                        The existing code




“We just need to be able to give
each client their own personal
 discount on certain charges.”
public function createInvoice(Account $acc, array $charges)
{
    $invoice = new Invoice();

    foreach ($charges as $chg) {
        $invoice->addLine($chg->getDesc(), $chg->getAmount());
    }

    return $invoice;
}




    The new code

private function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = new AccountDiscounter($acc);

    $discountedCharge = $accDisc->calculate($chg);
    return $discountedCharge;
}
public function createInvoice(Account $acc, array $charges)
{
    $invoice = new Invoice();
                                                     Call it
    foreach ($charges as $chg) {

        // Sprout new behaviour!
        $chg = $this->calcDiscount($acc, $chg);
        $invoice->addLine($chg->getDesc(), $chg->getAmount());
    }

    return $invoice;
}




private function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = new AccountDiscounter($acc);

    $discountedCharge = $accDisc->calculate($chg);
    return $discountedCharge;
}
Untestable OO → testable OO
Dependency Inversion / Extraction
The Problem
public function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = new AccountDiscounter($acc);

    $discountedCharge = $accDisc->calculate($chg);
    return $discountedCharge;
}                                                    Untestable!
The Problem
public function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = new AccountDiscounter($acc);

    $discountedCharge = $accDisc->calculate($chg);
    return $discountedCharge;
}                                                    Untestable!

class AccountDiscounter
{
    public function __construct(Account $acc)
    {
        // check cache
        // contact the database
        // call a web service
    }
}
Quick Solution
public function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = $this->getAccountDiscounter($acc);

    $discountedCharge = $accDisc->calculate($chg);
    return $discountedCharge;
}




                                Mock object in your test
                                    Override method


protected function getAccountDiscounter(Account $acc)
{
    return new AccountDiscounter($acc);
}
Dependency Injection Solution
public function __construct(AccountDiscounter $ad)
{
    $this->discounter = $ad;
}

                           Pass it into the class


public function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = $this->discounter;

    $discountedCharge = $accDisc->calculate($chg);
    return $discountedCharge;
}
(v2) → Dependency Injection Solution
public function __construct(IAccountDiscounter $ad)
{
    $this->discounter = $ad;
}

                            Make an interface


public function calcDiscount(Account $acc, Charge $chg)
{
     $accDisc = $this->discounter;

     $discountedCharge = $accDisc->calculate($chg);
     return $discountedCharge;
}
Summary
 Analyse

  Plan

  Test

 IsolatE

 Change

Test MORE
Any questions?


          Feedback to:

 https://joind.in/6020

            @rowan_m
Further reading:
          Michael Feathers
           Martin Fowler


http://www.flickr.com/photos/flatlinevision/1514971535/
http://commons.wikimedia.org/wiki/File:Weird_Tales_November_1950.jpg
http://commons.wikimedia.org/wiki/File:AdventuresIntoDarkness1401.jpg
http://www.flickr.com/photos/locationscout/3594432797/
http://www.flickr.com/photos/rawhead/3466304669/
http://commons.wikimedia.org/wiki/File:Rocket_to_the_Moon_54893.jpg
http://commons.wikimedia.org/wiki/File:Weird_Chills_July.jpg
http://commons.wikimedia.org/wiki/File:Terrific_01.jpg
http://commons.wikimedia.org/wiki/File:Strange_Fantasy_01.jpg
http://commons.wikimedia.org/wiki/File:Beware_01.JPG
http://www.flickr.com/photos/erokcom/2873449983/
http://www.flickr.com/photos/locationscout/3594433235/
http://commons.wikimedia.org/wiki/File:Weird_Chills_Sept.JPG
http://commons.wikimedia.org/wiki/File:Weird_Comics_01.JPG
http://www.flickr.com/photos/x-ray_delta_one/3972988193/
http://commons.wikimedia.org/wiki/File:Weird_Tales_January_1950.jpg
                                                                                     ts
                                                                                  di
http://commons.wikimedia.org/wiki/File:Plan_nine_from_outer_space.jpg
http://www.flickr.com/photos/javyer/3545217741/
http://www.flickr.com/photos/76074333@N00/318034222/
http://commons.wikimedia.org/wiki/File:Dime_Mystery_Magazine_July_1934.jpg
http://www.flickr.com/photos/quinnanya/3802177022/                           C re

Más contenido relacionado

La actualidad más candente

Applying TDD to Legacy Code
Applying TDD to Legacy CodeApplying TDD to Legacy Code
Applying TDD to Legacy CodeAlexander Goida
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Codeslicklash
 
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Victor Rentea
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy CodeNaresh Jain
 
Mastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for JavaMastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for JavaDenilson Nastacio
 
20111018 boost and gtest
20111018 boost and gtest20111018 boost and gtest
20111018 boost and gtestWill Shen
 
Node.JS error handling best practices
Node.JS error handling best practicesNode.JS error handling best practices
Node.JS error handling best practicesYoni Goldberg
 
Refactoring - An Introduction
Refactoring - An IntroductionRefactoring - An Introduction
Refactoring - An IntroductionGiorgio Vespucci
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideVictor Rentea
 
JAVASCRIPT Test Driven Development & Jasmine
JAVASCRIPT Test Driven Development & JasmineJAVASCRIPT Test Driven Development & Jasmine
JAVASCRIPT Test Driven Development & JasmineAnup Singh
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015CiaranMcNulty
 
cf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Woodcf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad WoodOrtus Solutions, Corp
 
Pure Functions and Immutable Objects
Pure Functions and Immutable ObjectsPure Functions and Immutable Objects
Pure Functions and Immutable ObjectsVictor Rentea
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesHarry Potter
 
Clean code & design patterns
Clean code & design patternsClean code & design patterns
Clean code & design patternsPascal Larocque
 
Testing in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkTesting in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkArulalan T
 
Automated testing in Python and beyond
Automated testing in Python and beyondAutomated testing in Python and beyond
Automated testing in Python and beyonddn
 
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...Victor Rentea
 

La actualidad más candente (20)

Cursus phpunit
Cursus phpunitCursus phpunit
Cursus phpunit
 
Applying TDD to Legacy Code
Applying TDD to Legacy CodeApplying TDD to Legacy Code
Applying TDD to Legacy Code
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
 
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Mastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for JavaMastering Mock Objects - Advanced Unit Testing for Java
Mastering Mock Objects - Advanced Unit Testing for Java
 
20111018 boost and gtest
20111018 boost and gtest20111018 boost and gtest
20111018 boost and gtest
 
Node.JS error handling best practices
Node.JS error handling best practicesNode.JS error handling best practices
Node.JS error handling best practices
 
Refactoring - An Introduction
Refactoring - An IntroductionRefactoring - An Introduction
Refactoring - An Introduction
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
 
JAVASCRIPT Test Driven Development & Jasmine
JAVASCRIPT Test Driven Development & JasmineJAVASCRIPT Test Driven Development & Jasmine
JAVASCRIPT Test Driven Development & Jasmine
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015
 
cf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Woodcf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Wood
 
Pure Functions and Immutable Objects
Pure Functions and Immutable ObjectsPure Functions and Immutable Objects
Pure Functions and Immutable Objects
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Clean code & design patterns
Clean code & design patternsClean code & design patterns
Clean code & design patterns
 
Testing in-python-and-pytest-framework
Testing in-python-and-pytest-frameworkTesting in-python-and-pytest-framework
Testing in-python-and-pytest-framework
 
Automated testing in Python and beyond
Automated testing in Python and beyondAutomated testing in Python and beyond
Automated testing in Python and beyond
 
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
 
Clean Code
Clean CodeClean Code
Clean Code
 

Destacado

Manual de bouml
Manual de boumlManual de bouml
Manual de boumlULEAM
 
11 diagrama de clases en bouml
11 diagrama de clases en bouml11 diagrama de clases en bouml
11 diagrama de clases en boumlMauricio Alarcon
 
Dealing With Legacy PHP Applications
Dealing With Legacy PHP ApplicationsDealing With Legacy PHP Applications
Dealing With Legacy PHP ApplicationsViget Labs
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsClinton Dreisbach
 
PHP 7.1 : elegance of our legacy
PHP 7.1 : elegance of our legacyPHP 7.1 : elegance of our legacy
PHP 7.1 : elegance of our legacyDamien Seguy
 
Working with Legacy Code
Working with Legacy CodeWorking with Legacy Code
Working with Legacy CodeEyal Golan
 
Adding Unit Test To Legacy Code
Adding Unit Test To Legacy CodeAdding Unit Test To Legacy Code
Adding Unit Test To Legacy CodeTerry Yin
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy CodeAndrea Polci
 
Transforming legacy PHP applications with Symfony2 and Varnish
Transforming legacy PHP applications with Symfony2 and VarnishTransforming legacy PHP applications with Symfony2 and Varnish
Transforming legacy PHP applications with Symfony2 and VarnishCraig Marvelley
 
Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014
Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014
Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014Michelangelo van Dam
 
XPDays Ukraine: Legacy
XPDays Ukraine: LegacyXPDays Ukraine: Legacy
XPDays Ukraine: LegacyVictor_Cr
 
XP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy codeXP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy codeDmytro Mindra
 
ITGM#4 Технический долг 2.0
ITGM#4 Технический долг 2.0ITGM#4 Технический долг 2.0
ITGM#4 Технический долг 2.0Maxim Shulga
 
From Legacy to DDD in PHP | Tech Talks | Privalia
From Legacy to DDD in PHP | Tech Talks | PrivaliaFrom Legacy to DDD in PHP | Tech Talks | Privalia
From Legacy to DDD in PHP | Tech Talks | PrivaliaJordi Vila Gallardo
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Victor_Cr
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Victor_Cr
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Of Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynote
Of Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynoteOf Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynote
Of Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynoteChristian Heilmann
 

Destacado (20)

Manual de bouml
Manual de boumlManual de bouml
Manual de bouml
 
11 diagrama de clases en bouml
11 diagrama de clases en bouml11 diagrama de clases en bouml
11 diagrama de clases en bouml
 
Dealing With Legacy PHP Applications
Dealing With Legacy PHP ApplicationsDealing With Legacy PHP Applications
Dealing With Legacy PHP Applications
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
PHP 7.1 : elegance of our legacy
PHP 7.1 : elegance of our legacyPHP 7.1 : elegance of our legacy
PHP 7.1 : elegance of our legacy
 
Working with Legacy Code
Working with Legacy CodeWorking with Legacy Code
Working with Legacy Code
 
Adding Unit Test To Legacy Code
Adding Unit Test To Legacy CodeAdding Unit Test To Legacy Code
Adding Unit Test To Legacy Code
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy Code
 
Transforming legacy PHP applications with Symfony2 and Varnish
Transforming legacy PHP applications with Symfony2 and VarnishTransforming legacy PHP applications with Symfony2 and Varnish
Transforming legacy PHP applications with Symfony2 and Varnish
 
Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014
Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014
Pimp legacy PHP apps with Apigility - TrueNorthPHP 2014
 
XPDays Ukraine: Legacy
XPDays Ukraine: LegacyXPDays Ukraine: Legacy
XPDays Ukraine: Legacy
 
XP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy codeXP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy code
 
ITGM#4 Технический долг 2.0
ITGM#4 Технический долг 2.0ITGM#4 Технический долг 2.0
ITGM#4 Технический долг 2.0
 
From Legacy to DDD in PHP | Tech Talks | Privalia
From Legacy to DDD in PHP | Tech Talks | PrivaliaFrom Legacy to DDD in PHP | Tech Talks | Privalia
From Legacy to DDD in PHP | Tech Talks | Privalia
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"
 
Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)Legacy: как победить в гонке (Joker)
Legacy: как победить в гонке (Joker)
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
TDD and Getting Paid
TDD and Getting PaidTDD and Getting Paid
TDD and Getting Paid
 
Sensible scaling
Sensible scalingSensible scaling
Sensible scaling
 
Of Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynote
Of Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynoteOf Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynote
Of Gaps, Fillers and Empty Spaces… Fronteers2015 closing keynote
 

Similar a Living With Legacy Code

PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityGeorgePeterBanyard
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkChristian Trabold
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Bastian Feder
 
Cli the other SAPI confoo11
Cli the other SAPI confoo11Cli the other SAPI confoo11
Cli the other SAPI confoo11Combell NV
 
Php Development With Eclipde PDT
Php Development With Eclipde PDTPhp Development With Eclipde PDT
Php Development With Eclipde PDTBastian Feder
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckrICh morrow
 
Tips
TipsTips
Tipsmclee
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7ZendVN
 
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 tek12Michelangelo van Dam
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbaivibrantuser
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Cli the other sapi pbc11
Cli the other sapi pbc11Cli the other sapi pbc11
Cli the other sapi pbc11Combell NV
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)Oleg Zinchenko
 
course slides -- powerpoint
course slides -- powerpointcourse slides -- powerpoint
course slides -- powerpointwebhostingguy
 
The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5Wim Godden
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010Bastian Feder
 

Similar a Living With Legacy Code (20)

PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009
 
Cli the other SAPI confoo11
Cli the other SAPI confoo11Cli the other SAPI confoo11
Cli the other SAPI confoo11
 
Php Development With Eclipde PDT
Php Development With Eclipde PDTPhp Development With Eclipde PDT
Php Development With Eclipde PDT
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course Deck
 
Tips
TipsTips
Tips
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7
 
Api Design
Api DesignApi Design
Api Design
 
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
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbai
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Cli the other sapi pbc11
Cli the other sapi pbc11Cli the other sapi pbc11
Cli the other sapi pbc11
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)
 
course slides -- powerpoint
course slides -- powerpointcourse slides -- powerpoint
course slides -- powerpoint
 
The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010The beautyandthebeast phpbat2010
The beautyandthebeast phpbat2010
 

Más de Rowan Merewood

Estimation or, "How to Dig your Grave"
Estimation or, "How to Dig your Grave"Estimation or, "How to Dig your Grave"
Estimation or, "How to Dig your Grave"Rowan Merewood
 
A Dependency Injection Primer
A Dependency Injection PrimerA Dependency Injection Primer
A Dependency Injection PrimerRowan Merewood
 
Practical Applications of Zend_Acl
Practical Applications of Zend_AclPractical Applications of Zend_Acl
Practical Applications of Zend_AclRowan Merewood
 
Algorithm, Review, Sorting
Algorithm, Review, SortingAlgorithm, Review, Sorting
Algorithm, Review, SortingRowan Merewood
 
State Machines to State of the Art
State Machines to State of the ArtState Machines to State of the Art
State Machines to State of the ArtRowan Merewood
 

Más de Rowan Merewood (6)

Estimation or, "How to Dig your Grave"
Estimation or, "How to Dig your Grave"Estimation or, "How to Dig your Grave"
Estimation or, "How to Dig your Grave"
 
A Dependency Injection Primer
A Dependency Injection PrimerA Dependency Injection Primer
A Dependency Injection Primer
 
Practical Applications of Zend_Acl
Practical Applications of Zend_AclPractical Applications of Zend_Acl
Practical Applications of Zend_Acl
 
Algorithm, Review, Sorting
Algorithm, Review, SortingAlgorithm, Review, Sorting
Algorithm, Review, Sorting
 
Tools and Talent
Tools and TalentTools and Talent
Tools and Talent
 
State Machines to State of the Art
State Machines to State of the ArtState Machines to State of the Art
State Machines to State of the Art
 

Último

Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Último (20)

Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

Living With Legacy Code

  • 3. @rowan_m Plusnet Ibuildings
  • 5. What is “Legacy Code”? Code without tests Code you've “inherited” Code no-one understands Technical debt
  • 6. Who has never created Legacy Code?
  • 8. Pragmatic, not ideal istic My own little story
  • 10. Aim to understand the concepts and motivations
  • 12. Find and then read any / all documentation
  • 13. Official: Che Project brief ( ) c kli Requirements ( ) st Tech. Spec. ( ) Actual: Emails ( ) Meeting notes ( ) Progress: Gant charts ( ) Burndowns ( ) Overtime logs ( ) Quality: Bug tracker ( ) Complaints ( ) User Forums ( )
  • 14. Talk to the original developers
  • 15. Talk to the users … especially the “different” ones
  • 20. PHP: Che php.ini ( ) c kli PEAR / PECL modules ( ) st Compile options ( ) Patches ( ) The Rest: OS ( ) Package manager ( ) Web server ( ) Web server modules ( ) Site config. ( ) Database ( ) Cache ( ) JS libraries ( ) Firewall rules ( ) Proxies ( ) Services running ( )
  • 21. Time to enter The Code
  • 22. Time to enter The Code Reading Static analysis Dynamic analysis
  • 23. http://www.phpdoc.org/ doc php Title phpdoc -ti 'Sweet Application' -pp -o HTML:Smarty:PHP -d Libraries Style -t Docs Code in here Docs out here!
  • 24. Beware of type-hiding! Type-hinting /** * @param array $opts Current options * @return array Options with flag set */ function setFlag(array $opts) { $opts['flag'] = true; return $opts; } Type-hiding /** * @param int $fullPence Full price in pence * @return float Discounted price in pence */ function applyDiscount($fullPence) { return ($fullPence * 0.8); }
  • 25. ygen dox doxygen -s -g ~/doxy.conf vim ~/doxy.conf # edit at least this Code in here OUPUT_DIRECTORY # play with the rest cd ~/dev/project Docs out here doxygen ~/doxy.conf http://www.stack.nl/~dimitri/doxygen/
  • 26. http://ctags.sourceforge.net/ ta gs c Code in here #!/bin/bash Tags out here cd ~/Dev/ && ctags-exuberant -f ~/.vimtags -h ".php" -R --exclude=".git" --links=no --totals=yes --tag-relative=yes --PHP-kinds=+cf --regex-PHP='/abstracts+classs+([^ ]+)/1/c/' --regex-PHP='/interfaces+([^ ]+)/1/c/' --regex-PHP='/(publics+|statics+|abstracts+|protecteds+|privates+) ↵ functions+&?s*([^ (]+)/2/f/' Voodoo
  • 27. ml http://www.bouml.fr/ bou
  • 28. ml http://bouml.free.fr/ bou
  • 29. ml http://bouml.free.fr/ bou
  • 30. ml http://bouml.free.fr/ bou
  • 31. ml http://bouml.free.fr/ bou
  • 32. ml http://bouml.free.fr/ bou
  • 34. ffer esni co d rowan@swordbean:~/Dev/ZendFramework-1.9.4/library/Zend/Service$ phpcs --standard=Zend Exception.php FILE: /home/rowan/Dev/ZendFramework-1.9.4/library/Zend/Service/Exception.php -------------------------------------------------------------------------------- FOUND 1 ERROR(S) AND 2 WARNING(S) AFFECTING 3 LINE(S) -------------------------------------------------------------------------------- 17 | WARNING | Line exceeds 80 characters; contains 87 characters 32 | WARNING | Line exceeds 80 characters; contains 87 characters 36 | ERROR | Opening class brace must be on a line by itself 36 | ERROR | Closing brace must be on a line by itself -------------------------------------------------------------------------------- http://pear.php.net/package/PHP_CodeSniffer/
  • 35. t in uous Con io n Inte grat http://jenkins-ci.org/ http://phpundercontrol.org/ http://sismo.sensiolabs.org/
  • 36. Decisi on tim e!
  • 37. Decisi on tim e! Ign cod ore e a it , nyw ay a cto r, ref est ite, st, t Rewr , te test
  • 40. Ignore it, code anyway Please don't. however...
  • 41. Deadlines, clients, money, etc.
  • 42. Deadlines, clients, money, etc. Make everyone aware of the risks Secure a follow-up project
  • 43. Why do you need the code?
  • 44. Why do you need the code? simple Library dependency Adding new behaviour Changing behaviour complex
  • 46. Isolate legacy dependencies Create an anti-corruption layer
  • 47. Complete isolation Create a legacy service
  • 48. Partial isolation Wrapper classes or methods
  • 49. Wrapper class <?php include('/home/victorvon/secrets.inc'); /** * @param array $person willing volunteer */ function extract_brain(&$person) { $brain = $person['brain']; unset($person['brain']); } return $brain; Some code /** you need * @param array $person * @return bool living or not :( */ function create_life($person) { require_once(LIB_DIR.'../nuts_n_bolts.inc'); kerzap(); $person['living'] = true; return $person; } ?>
  • 50. class VictorWrapper { Wrapper class public function __construct() { require_once '/home/victorvon/tragedy.php'; } public function extractBrain(Person $p) { // format to legacy style $pLgcy = $this->toArray($p); // run legacy code $bLgy = extract_brain($pLgcy); // format to new style $p = $this->toPerson($pLgcy); Some code $b = $this->toBrain($bLgcy); return array($p, $b); you can use } :) public function createLife(Person $p) { // validate if ($person->isAlive()) throw new LivingException(); // format to legacy style $pLgcy = $this->toArray($p); // run legacy code $pLgy = create_life($pLgcy); // format to new style return $this->toPerson($pLgcy); } }
  • 52. Changing the code Take an incremental approach Commit to 1 day at a time
  • 53. Why? Difficult to estimate Hidden dependencies Unknown behaviour
  • 54. 1. Get it into version control
  • 56. 3. Create integration & acceptance tests
  • 57. 4. Set up your continuous integration environment
  • 58. 5. Rewrite and refactor!
  • 59. Types of changes
  • 61. includes HTML PHP HTML HTML PHP HTML PHP HTML PHP PHP HTML PHP HTML HTML PHP HTML PHP
  • 62. includes function function function includes HTML PHP HTML HTML echo HTML HTML PHP HTML HTML echo HTML PHP HTML PHP if HTML if PHP foreach HTML PHP HTML HTML echo HTML HTML PHP HTML HTML echo HTML PHP foreach
  • 65. includes includes function static method function static method function static method function static method free code static method
  • 66. includes includes includes function static method constructor function static method method function static method method function static method method free code static method method
  • 68. public function createInvoice(Account $acc, array $charges) { $invoice = new Invoice(); foreach ($charges as $chg) { $invoice->addLine($chg->getDesc(), $chg->getAmount()); } return $invoice; } The existing code “We just need to be able to give each client their own personal discount on certain charges.”
  • 69. public function createInvoice(Account $acc, array $charges) { $invoice = new Invoice(); foreach ($charges as $chg) { $invoice->addLine($chg->getDesc(), $chg->getAmount()); } return $invoice; } The new code private function calcDiscount(Account $acc, Charge $chg) { $accDisc = new AccountDiscounter($acc); $discountedCharge = $accDisc->calculate($chg); return $discountedCharge; }
  • 70. public function createInvoice(Account $acc, array $charges) { $invoice = new Invoice(); Call it foreach ($charges as $chg) { // Sprout new behaviour! $chg = $this->calcDiscount($acc, $chg); $invoice->addLine($chg->getDesc(), $chg->getAmount()); } return $invoice; } private function calcDiscount(Account $acc, Charge $chg) { $accDisc = new AccountDiscounter($acc); $discountedCharge = $accDisc->calculate($chg); return $discountedCharge; }
  • 71. Untestable OO → testable OO
  • 73. The Problem public function calcDiscount(Account $acc, Charge $chg) { $accDisc = new AccountDiscounter($acc); $discountedCharge = $accDisc->calculate($chg); return $discountedCharge; } Untestable!
  • 74. The Problem public function calcDiscount(Account $acc, Charge $chg) { $accDisc = new AccountDiscounter($acc); $discountedCharge = $accDisc->calculate($chg); return $discountedCharge; } Untestable! class AccountDiscounter { public function __construct(Account $acc) { // check cache // contact the database // call a web service } }
  • 75. Quick Solution public function calcDiscount(Account $acc, Charge $chg) { $accDisc = $this->getAccountDiscounter($acc); $discountedCharge = $accDisc->calculate($chg); return $discountedCharge; } Mock object in your test Override method protected function getAccountDiscounter(Account $acc) { return new AccountDiscounter($acc); }
  • 76. Dependency Injection Solution public function __construct(AccountDiscounter $ad) { $this->discounter = $ad; } Pass it into the class public function calcDiscount(Account $acc, Charge $chg) { $accDisc = $this->discounter; $discountedCharge = $accDisc->calculate($chg); return $discountedCharge; }
  • 77. (v2) → Dependency Injection Solution public function __construct(IAccountDiscounter $ad) { $this->discounter = $ad; } Make an interface public function calcDiscount(Account $acc, Charge $chg) { $accDisc = $this->discounter; $discountedCharge = $accDisc->calculate($chg); return $discountedCharge; }
  • 78. Summary Analyse Plan Test IsolatE Change Test MORE
  • 79. Any questions? Feedback to: https://joind.in/6020 @rowan_m
  • 80. Further reading: Michael Feathers Martin Fowler http://www.flickr.com/photos/flatlinevision/1514971535/ http://commons.wikimedia.org/wiki/File:Weird_Tales_November_1950.jpg http://commons.wikimedia.org/wiki/File:AdventuresIntoDarkness1401.jpg http://www.flickr.com/photos/locationscout/3594432797/ http://www.flickr.com/photos/rawhead/3466304669/ http://commons.wikimedia.org/wiki/File:Rocket_to_the_Moon_54893.jpg http://commons.wikimedia.org/wiki/File:Weird_Chills_July.jpg http://commons.wikimedia.org/wiki/File:Terrific_01.jpg http://commons.wikimedia.org/wiki/File:Strange_Fantasy_01.jpg http://commons.wikimedia.org/wiki/File:Beware_01.JPG http://www.flickr.com/photos/erokcom/2873449983/ http://www.flickr.com/photos/locationscout/3594433235/ http://commons.wikimedia.org/wiki/File:Weird_Chills_Sept.JPG http://commons.wikimedia.org/wiki/File:Weird_Comics_01.JPG http://www.flickr.com/photos/x-ray_delta_one/3972988193/ http://commons.wikimedia.org/wiki/File:Weird_Tales_January_1950.jpg ts di http://commons.wikimedia.org/wiki/File:Plan_nine_from_outer_space.jpg http://www.flickr.com/photos/javyer/3545217741/ http://www.flickr.com/photos/76074333@N00/318034222/ http://commons.wikimedia.org/wiki/File:Dime_Mystery_Magazine_July_1934.jpg http://www.flickr.com/photos/quinnanya/3802177022/ C re