Search code examples
ooparchitecturecode-reuselibrary-design

Architecture of some reusable code


I am writing a number of small, simple applications which share a common structure and need to do some of the same things in the same ways (e.g. logging, database connection setup, environment setup) and I'm looking for some advice in structuring the reusable components. The code is written in a strongly and statically typed language (e.g. Java or C#, I've had to solve this problem in both). At the moment I've got this:

abstract class EmptyApp //this is the reusable bit
{
   //various useful fields: loggers, db connections

   abstract function body()
   function run()
   {
        //do setup
        this.body()
        //do cleanup
   }
}

class theApp extends EmptyApp //this is a given app
{
   function body()
   {
        //do stuff using some fields from EmptyApp
   }

   function main()
   {
        theApp app = new theApp()
        app.run()
   }
 }

Is there a better way? Perhaps as follows? I'm having trouble weighing the trade-offs...

abstract class EmptyApp
{
     //various fields
}

class ReusableBits
{
    static function doSetup(EmptyApp theApp)

    static function doCleanup(EmptyApp theApp)
}

class theApp extends EmptyApp
{
    function main()
    {
         ReusableBits.doSetup(this);
         //do stuff using some fields from EmptyApp
         ReusableBits.doCleanup(this);
    }
}

One obvious tradeoff is that with option 2, the 'framework' can't wrap the app in a try-catch block...


Solution

  • I've always favored re-use through composition (your second option) rather than inheritance (your first option).

    Inheritance should only be used when there is a relationship between the classes rather than for code reuse.

    So for your example I would have multiple ReusableBits classes each doing 1 thing that each application a make use of as/when required.

    This allows each application to re-use the parts of your framework that are relevant for that specific application without being forced to take everything, Allowing the individual applications more freedom. Re-use through inheritance can sometimes become very restrictive if you have some applications in the future that don't exactly fit into the structure you have in mind today.

    You will also find unit testing and test driven development much easier if you break your framework up into separate utilities.