Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Code refactoring

Options
  • 07-01-2008 1:44pm
    #1
    Registered Users Posts: 6,790 ✭✭✭


    Hi all. I'm working on a Mac OS app that will be ported to Windows in the coming months. My first task is to seperate as much of the Cocoa code (proprietory Mac code) as possible from any bits of code that might be reusable. This will involve picking apart some massive, badly designed classes.

    Could anyone recommend any books/websites on how best to proceed? Any general tips/tricks/general guidelines would also be welcome, I haven't taken on any design work of this nature before. Thanks.


Comments

  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    Generally speaking, something like this would be what i'd recommend. I'm going to use CD burning as my example.

    So you have your mac application which has hardcoded itself to use the built in CD burning routines, calling directly into native mac code. You want this to work on windows and linux now! Currently the class that deals with this is called MacCDBurner.

    So, one solution is this:
    Create an interface (or a base class) called ICDBurner (or CDBurnerBase) which has all the methods you'd never need when writing to disks. Everywhere you had MacCdBurner in your main program, you replace with ICDBurner.

    You can then create three separate classes, each of which is tailored to use the cd burning routines in a particular operating system. Windows, Linux and Mac.

    Then create a Factory method to instantiate the correct ICDBurner depending on what OS you're on. Inside this method you will have your platform detection logic which will instantiate a WindowsCdBurner, LinuxCDBurner or MacCDBurner at runtime depending on what OS is detected.

    Now, you're done!

    If you're programming language of choice isn't flexible enough to be able to compile both MacCDBurner and LinuxCDBurner when on windows, then you can just #ifdef out the implementation details of MacCDBurner and LinuxCDBurner so that both classes compile when on windows, but don't actually do anything. This way a windows compile will work perfectly as only WindowsCDBurner will be used, and the rest of your code won't be affected because (technically speaking) MacCDBurner and LinuxCDBurner are still there.

    So in short:
    Everywhere you use MacCDBurner, change to ICDBurner.

    Use a factory method to instantiate the right burner based on runtime detection. If you can't do runtime detection, still use a factory method, but you can #ifdef it so that when you do a windows compile, the factory method will always return a WindowsCDBurner.

    Implement an ICDBurner for each OS you want supported, and maybe an UnsupportedOSCDBurner as a placeholder if the OS isn't supported.

    Make sure all platform specific code is in a platform specific class.

    Profit.


  • Registered Users Posts: 6,790 ✭✭✭cornbb


    Thanks for the detailed reply! I'm familiar with the concept of abstracting any relevant OS-specific code and instantiating the correct flavour via #ifdef statements but unfortunately I haven't even gotten that far yet :o

    Our application grew fairly organically from the beginning so unfortunately no provision was made for cross-platform compatibility. I'm focusing on one or two very large classes that should by right have been broken up a long time ago. Our sw architect has asked me to break one of these up (over 4000 lines long!), i.e. remove any methods or parts of methods that rely on certain OS-specific technologies. He will then rewrite the resulting code in the manner you described above.

    So my concern at the moment is how to refactor this class and keep the whole program running without bugs. I've read some refactoring literature on the web but I can't find any detailed information on how to proceed. E.g. how should I handle things if there is a member variable in the old class that is to be shared between several methods which will be extracted and several methods which will remain in the class?

    It'd be handy to have access to resources that explain concepts like this in more detail than I've found so far. Most books/websites on systems design/analysis focus on building apps from scratch, not refactoring.

    Thanks again!


  • Closed Accounts Posts: 2,039 ✭✭✭rmacm


    If you're interested in a book on Refactoring I'd suggest checking out Martin Fowlers book called Refactoring: Improving the Design of Existing Code. I used it a few times in college and it's been recommended to me by a few experienced developers.


Advertisement