Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
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

   ...
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:...
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
Comp...
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 ...
Beware of type-hiding!


                    Type-hinting
/**
 * @param array $opts Current options
 * @return array Optio...
ygen
dox

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

               # edit at least this
Cod...
http://ctags.sourceforge.net/
    ta gs
c
                Code in here
#!/bin/bash                         Tags out here
c...
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 
                        ...
t in uous
Con        io n
Inte grat

        http://jenkins-ci.org/


     http://phpundercontrol.org/


      http://sism...
Decisi
         on tim
               e!
Decisi
                          on tim
                                e!


  Ign
cod ore
   e a    it ,
       nyw
     ...
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

      ...
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 ex...
class VictorWrapper
{                                            Wrapper class
    public function __construct()
   {
    ...
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


 ...
includes


                                                    function


                                                ...
Procedural → OO
includes



function



function



function




function




free code
includes      includes



function    static method



function    static method



function    static method




function...
includes      includes       includes



function    static method   constructor



function    static method     method

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

    foreach ($charges as $chg...
public function createInvoice(Account $acc, array $charges)
{
    $invoice = new Invoice();

    foreach ($charges as $chg...
public function createInvoice(Account $acc, array $charges)
{
    $invoice = new Invoice();
                              ...
Untestable OO → testable OO
Dependency Inversion / Extraction
The Problem
public function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = new AccountDiscounter($acc);

    $di...
The Problem
public function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = new AccountDiscounter($acc);

    $di...
Quick Solution
public function calcDiscount(Account $acc, Charge $chg)
{
    $accDisc = $this->getAccountDiscounter($acc);...
Dependency Injection Solution
public function __construct(AccountDiscounter $ad)
{
    $this->discounter = $ad;
}

       ...
(v2) → Dependency Injection Solution
public function __construct(IAccountDiscounter $ad)
{
    $this->discounter = $ad;
}
...
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/1514971...
Próximo SlideShare
Cargando en…5
×

de

Living With Legacy Code Slide 1 Living With Legacy Code Slide 2 Living With Legacy Code Slide 3 Living With Legacy Code Slide 4 Living With Legacy Code Slide 5 Living With Legacy Code Slide 6 Living With Legacy Code Slide 7 Living With Legacy Code Slide 8 Living With Legacy Code Slide 9 Living With Legacy Code Slide 10 Living With Legacy Code Slide 11 Living With Legacy Code Slide 12 Living With Legacy Code Slide 13 Living With Legacy Code Slide 14 Living With Legacy Code Slide 15 Living With Legacy Code Slide 16 Living With Legacy Code Slide 17 Living With Legacy Code Slide 18 Living With Legacy Code Slide 19 Living With Legacy Code Slide 20 Living With Legacy Code Slide 21 Living With Legacy Code Slide 22 Living With Legacy Code Slide 23 Living With Legacy Code Slide 24 Living With Legacy Code Slide 25 Living With Legacy Code Slide 26 Living With Legacy Code Slide 27 Living With Legacy Code Slide 28 Living With Legacy Code Slide 29 Living With Legacy Code Slide 30 Living With Legacy Code Slide 31 Living With Legacy Code Slide 32 Living With Legacy Code Slide 33 Living With Legacy Code Slide 34 Living With Legacy Code Slide 35 Living With Legacy Code Slide 36 Living With Legacy Code Slide 37 Living With Legacy Code Slide 38 Living With Legacy Code Slide 39 Living With Legacy Code Slide 40 Living With Legacy Code Slide 41 Living With Legacy Code Slide 42 Living With Legacy Code Slide 43 Living With Legacy Code Slide 44 Living With Legacy Code Slide 45 Living With Legacy Code Slide 46 Living With Legacy Code Slide 47 Living With Legacy Code Slide 48 Living With Legacy Code Slide 49 Living With Legacy Code Slide 50 Living With Legacy Code Slide 51 Living With Legacy Code Slide 52 Living With Legacy Code Slide 53 Living With Legacy Code Slide 54 Living With Legacy Code Slide 55 Living With Legacy Code Slide 56 Living With Legacy Code Slide 57 Living With Legacy Code Slide 58 Living With Legacy Code Slide 59 Living With Legacy Code Slide 60 Living With Legacy Code Slide 61 Living With Legacy Code Slide 62 Living With Legacy Code Slide 63 Living With Legacy Code Slide 64 Living With Legacy Code Slide 65 Living With Legacy Code Slide 66 Living With Legacy Code Slide 67 Living With Legacy Code Slide 68 Living With Legacy Code Slide 69 Living With Legacy Code Slide 70 Living With Legacy Code Slide 71 Living With Legacy Code Slide 72 Living With Legacy Code Slide 73 Living With Legacy Code Slide 74 Living With Legacy Code Slide 75 Living With Legacy Code Slide 76 Living With Legacy Code Slide 77 Living With Legacy Code Slide 78 Living With Legacy Code Slide 79 Living With Legacy Code Slide 80
Próximo SlideShare
Manual de bouml
Siguiente
Descargar para leer sin conexión y ver en pantalla completa.

16 recomendaciones

Compartir

Descargar para leer sin conexión

Living With Legacy Code

Descargar para leer sin conexión

Practical tips for dealing with projects involving legacy code. Covers investigating past projects, static analysis of existing code, and methods for changing legacy code.

Presented at PHP Benelux '10

Libros relacionados

Gratis con una prueba de 30 días de Scribd

Ver todo

Audiolibros relacionados

Gratis con una prueba de 30 días de Scribd

Ver todo

Living With Legacy Code

  1. ving Li with Legacy Code
  2. @rowan_m
  3. @rowan_m Plusnet Ibuildings
  4. What is “Legacy Code”?
  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?
  7. My own little story
  8. Pragmatic, not ideal istic My own little story
  9. Starting a project
  10. Aim to understand the concepts and motivations
  11. Try using the application
  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
  16. Approaching the code
  17. Catalogue the live platform & environment
  18. Recreate it!
  19. Deploy the code
  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
  33. ou ml b
  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
  38. Ignore it, code anyway
  39. Ignore it, code anyway Please don't.
  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
  45. Isolate legacy dependencies
  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); } }
  51. Changing the code
  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
  55. 2. Identify the inflection point
  56. 3. Create integration & acceptance tests
  57. 4. Set up your continuous integration environment
  58. 5. Rewrite and refactor!
  59. Types of changes
  60. Mixed → Procedural
  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
  63. Procedural → OO
  64. includes function function function function free code
  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
  67. Sprout method / class
  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
  72. Dependency Inversion / Extraction
  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
  • hanochaloni

    May. 12, 2018
  • PhamManhLan

    Apr. 30, 2017
  • powerirs

    Jan. 20, 2017
  • rakeshnagar

    Sep. 24, 2016
  • kritulrathod

    Feb. 10, 2016
  • wl21st

    Oct. 3, 2015
  • bestlong

    Mar. 16, 2015
  • piotrpasich

    Aug. 25, 2014
  • wgviana

    Jul. 25, 2012
  • jeremykendall

    Aug. 26, 2010
  • DaRaFF

    Apr. 24, 2010
  • quaggar

    Mar. 1, 2010
  • joelg87

    Feb. 26, 2010
  • mirfan

    Feb. 5, 2010
  • DragonBe

    Feb. 2, 2010
  • mwesten

    Jan. 30, 2010

Practical tips for dealing with projects involving legacy code. Covers investigating past projects, static analysis of existing code, and methods for changing legacy code. Presented at PHP Benelux '10

Vistas

Total de vistas

33.570

En Slideshare

0

De embebidos

0

Número de embebidos

3.792

Acciones

Descargas

114

Compartidos

0

Comentarios

0

Me gusta

16

×