Breaking Dependencies on Legacy Code

Discussion in 'C++' started by Michael Oswald, Apr 17, 2007.

  1. Hello,

    I have a rather big application with many processes and have to add some
    features. I want to put some classes of it into a test harness with
    cppunit and need to break some dependencies on a vendor GUI library.
    Maybe someone has some thoughts on this.

    Suppose there is a GUI class from the vendor library:

    // Sheet.h:
    class Sheet /*: public Matrix*/
    {
    public:
    Sheet();
    virtual ~Sheet();

    virtual void draw();
    void setSomething();
    virtual void someCallback();
    };

    which is part of a greater hierarchy. It has virtual methods,
    non-virtual methods and some virtual callback methods.

    The application then inherits from this class something like that:


    // EntrySheet.h
    #include <iostream>
    #include "Sheet.h"


    class EntrySheet : public Sheet
    {
    public:
    EntrySheet() : Sheet()
    {}

    virtual ~EntrySheet();

    virtual void someMoreMemberFunc();

    virtual void someCallback()
    {
    std::cout << "Callback called" << std::endl;
    }
    };

    //EntrySheet.cpp:
    #include "EntrySheet.h"

    void EntrySheet::someMoreMemberFunc()
    {
    // do something
    }


    So nothing exciting here. For putting this class in a test harness I
    want to get rid of the GUI class and replace it with a dummy class which
    is more suitable for testing.

    My first idea was to change EntrySheet to something like this:

    //EntrySheet.h:
    #include "Sheet.h"

    template<typename T>
    class EntrySheet : public T
    {
    public:
    typedef T Inherited;

    EntrySheet() : Sheet()
    {}

    virtual ~EntrySheet();

    virtual void someMoreMemberFunc();

    virtual void someCallback();
    };
    #include "EntrySheet.cpp"


    //EntrySheet.cpp:

    template<typename T>
    void EntrySheet<t>::someMoreMemberFunc()
    {
    //do something
    }


    Then the class can be used in the production code with:

    #include "Sheet.h"
    #include "EntrySheet.h"

    typedef EntrySheet<Sheet> IEntrySheet;

    int main(int argc, char** argv)
    {
    IEntrySheet sheet;

    sheet.setSomething();
    sheet.someMoreMemberFunc();
    sheet.draw();

    return 0;
    }


    For the test harness only the typdef needs to be changed

    #include "DummySheet.h"
    #include "EntrySheet.h"

    typedef EntrySheet<DummySheet> IEntrySheet;

    int main(int argc, char** argv)
    {
    IEntrySheet sheet;

    // perform tests

    return 0;
    }


    This method works and the advantages are, that it is relatively easy to
    implement and in DummySheet there need only the member functions to be
    implemented, which are really referenced (Sheet is rather big).

    The big disadvantage is, that EntrySheet is rather big too and in the
    template version it has to be included everytime it is used which
    increases compile time, especially if this dependency breaking method is
    used for more classes.

    In "Working effectively with legacy code" Michael Feathers suggests to
    use wrappers for vendor libraries, but this seems not feasible because I
    need the inheritance to get the someCallback() call from somewhere in
    the vendor library hierarchy.

    Any thoughts on other methods which allow an easy switching between
    dummy and real class for testing and that don't increase the compile time?


    lg,
    Michael
     
    Michael Oswald, Apr 17, 2007
    #1
    1. Advertising

  2. Michael Oswald

    Noah Roberts Guest

    Michael Oswald wrote:

    > The big disadvantage is, that EntrySheet is rather big too and in the
    > template version it has to be included everytime it is used which
    > increases compile time, especially if this dependency breaking method is
    > used for more classes.


    That's a smell of its own that needs dealing with. Split the class up
    first and put its individual components under harness. You might then
    not need put the sheet in at all.
     
    Noah Roberts, Apr 18, 2007
    #2
    1. Advertising

  3. Noah Roberts schrieb:
    > That's a smell of its own that needs dealing with. Split the class up
    > first and put its individual components under harness. You might then
    > not need put the sheet in at all.


    Good point. I'll have a look what's possible.

    lg,
    Michael
     
    Michael Oswald, Apr 18, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy Sutorius via DotNetMonster.com

    ASP.NET (c# code behind) will not load legacy C++ dll

    Andy Sutorius via DotNetMonster.com, Jan 18, 2006, in forum: ASP .Net
    Replies:
    6
    Views:
    4,990
    Andy Sutorius via DotNetMonster.com
    Jan 18, 2006
  2. Amy
    Replies:
    0
    Views:
    532
  3. RajW
    Replies:
    1
    Views:
    318
    Ali R.
    Dec 11, 2003
  4. Suzie
    Replies:
    9
    Views:
    385
    David Hilsee
    Sep 24, 2004
  5. Mark
    Replies:
    4
    Views:
    352
    Sachin Garg
    Sep 27, 2004
Loading...

Share This Page