views:

166

answers:

3

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...

A: 

Why not make the framework call onto your customisable code ? So your client creates some object, and injects it into the framework. The framework initialises, calls setup() etc., and then calls your client's code. Upon completion (or even after a thrown exception), the framework then calls cleanup() and exits.

So your client would simply implement an interface such as (in Java)

public interface ClientCode {

    void runClientStuff(); // for the sake of argument
}

and the framework code is configured with an implementation of this, and calls runClientStuff() whenever required.

So you don't derive from the application framework, but simply provide a class conforming to a particular contract. You can configure the application setup at runtime (e.g. what class the client will provide to the app) since you're not deriving from the app and so your dependency isn't static.

The above interface can be extended to have multiple methods, and the application can call the required methods at different stages in the lifecycle (e.g. to provide client-specific setup/cleanup) but that's an example of feature creep :-)

Brian Agnew
A: 

Remember, inheritance is only a good choice if all the object that are inheriting reuse the code duo to their similarities. or if you want callers to be able to interact with them in the same fission. if what i just mentioned applies to you then based on my experience its always better to have the common logic in your base/abstract class.

this is how i would re-write your sample app in C#.

abstract class BaseClass
{
    string field1 = "Hello World";
    string field2 = "Goodbye World";

    public void Start()
    {
     Console.WriteLine("Starting.");
     Setup();
     CustomWork();
     Cleanup();
    }

    public virtual void Setup()
    {Console.WriteLine("Doing Base Setup.");}

    public virtual void Cleanup()
    {Console.WriteLine("Doing Base Cleanup.");}

    public abstract void CustomWork();
}

class MyClass : BaseClass
{
    public override void CustomWork()
    {Console.WriteLine("Doing Custome work.");}

    public override void Cleanup()
    {
     Console.WriteLine("Doing Custom Cleanup");
     //You can skip the next line if you want to replace the
     //cleanup code rather than extending it
     base.Cleanup();
    }

}

void Main()
{
    MyClass worker = new MyClass();
    worker.Start();
}
Keivan
+3  A: 

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.

Aaron