21 Jan 2012 @ 3:00 PM 

Refactoring legacy code with the regular old incremental approach,

  1. If you have the chance convert to UML and document what little knarly architecture there is.

  2. If you are on version control look into generating some code churn reports and figuring out
    which files and file sections have been changed the most frequently. Make a note of these as
    they will likely be the areas you will want to deal with first.

  3. Before you change any code always try to add some test coverage
    (even ugly full stack functional tests will do).

    If dealing with large messy procedurial code extract logic you intend on changing into some
    reasonably named method or function and if possible add some test cases that verify your
    new method. make whatever god awful hack you have to and if possible paramatize the
    change if it is something commonly tweaked like margin width or title so it will be a little
    more straight forward to update the next time.

  4. Use the adapter pattern and work away at hiding the knarly bits of legacy code under
    a rug of logically named classes and methods so that for most common tasks you and
    the other developers perform you wont need to worry about the scary bits that are going
    on behind your back behind those nice little clean methods and classes you’ve hidden that
    legacy code behind — like those nice families that keep deformed murderous zombie former
    family members in barns so that they don’t spoil the day to day going-on’s of the farm
    . . . normally.

  5. As you continue to whittle away and clean up the sections of the code continue to boost your
    test coverage. Now you can dig down even deeper and “rewrite” even more code when
    needed/desired with ever increasing confidence.

  6. Repeat, or apply additional refactoring approaches to continue to improve your codebase.

Branching By Abstraction

  1. Define the trouble spot in the code you want to remove
    (the persistence layer, the pdf generator, the invoice tally mechanism, the widget generator, etc.).

  2. run (write if necessary) some functional test cases
    (automated or manual but you know automated)
    against the code base that targets this functionality along with general behavior.

  3. Extract logic related to that component from the existing sourcebase into a class
    with some reasonable interface.

  4. Verify all code is now using the new interface to perform activity X
    which was previously dispersed randomly throughout the code
    (Grep the code base, add a trace to the new class and verify pages that
    should be calling it are, etc.), and that you can control which implementation
    will be used by modifying a single file.(object registry, factory class, whatever
    IActivityXClass = Settings.AcitivtyXImplementer();)

  5. rerun functional test cases that verify everything is still functioning with
    all of Activity X throwin into your new class.

  6. Write unit tests where possible around the new activity X wrapper class.
  7. implement a new class with less insane spaghetti logic than the legacy
    implementation that adheres to the same interface as the legacy class.

  8. verify that the new class passes the unit tests you wrote for the legacy class.
  9. update your code by changing the registry/factorymethod/whatever to
    use the new class instead of the old class.

  10. verify that your functional tests still pass.

Open Closed Principle and a Common Business Logic/Persistence Layer

To some extent you might be able to get away with separating out your
presentation, business and persistence layer and writing a new app that
is fully backwards compatible with the legacy solution, or at a minimum
can still handle data inputted by legacy solution. I would probably not
recommend this approach but sometimes it is a reasonable compromise
of time/schedule/resources/required new functionality.

  • At a minimum separate the presentation layer away from the
    business and persistence layers.

  • implement a new ui and better presentation layer that uses
    the same common business and persistence layer.

  • Verify that data created with new ui does not break old ui.
    (you’re going to be in hot water if users of the new tool interrupt users of the old tool).

    If you are striving for full backwards compatibility you should be saving
    everything to the same persistence layers. If you just want forward compatibility
    into the new tool then use a new database and new tables or extension tables
    to track data not in legacy system.

  • For new functionality and persistence layer needs add new tables and methods
    don’t change existing legacy logic, or add columns, constraints to existing tables.

    e.g. if you need to start tracking employers emergency contact and some other fields
    don’t modify the existing employee table
    (we have no idea what assumptions the legacy data makes about that table) add an extension
    table employee_ext id, employee_id, emergency_contact_id, etc_id.

  • Slowly migrate users onto new system. if possible put legacy system into read only mode,
    or just add some warning telling users it will no longer be available after date X.

  • implement any hi priority missed functionality or business requirements in the new ui

  • roll over users base.
  • continue on to clean-up the business logic and persistence layer users other refactoring methodologies.
Posted By: admin
Last Edit: 21 Jan 2012 @ 03:00 PM

EmailPermalinkComments (0)
Tags
Categories: Uncategorized

 Last 50 Posts
 Back
Change Theme...
  • Users » 75
  • Posts/Pages » 14
  • Comments » 10
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

About



    No Child Pages.

About



    No Child Pages.

Resume



    No Child Pages.