Is it a good design to have a class that is derived from a base class and also contains an instance of it?

advertisements

I am designing a producer/consumer based application and I am stucked at representing Task produced by producer in class representation.

The actual problem goes like: A producer can produce a StandaloneTask which can be directly consumable by a consumer or it can produce a CompressTask which has to be goes through a TaskDecompressor first which extract it first into a number of StandaloneTask which can them be consumed by consumers.

Since there is a lot of commonality between the StandaloneTask and the CompressTask, so I have created a base class called TaskBase which contains all this common information.

class abstract TaskBase
{

}

class StandloneTaskType1: TaskBase
{

}

class StandloneTaskType2: TaskBase
{

}

.
.
.

class StandloneTaskTypeN: TaskBase
{

}

How decompressing of a task works? A task can have one or more parameters which needs to be filled at run time. A compress task consists of a task with parameters and other info about how to get values that need to be filled in those parameters. After getting values, a TaskDecompressor is suppose to fill all these values into the parametrized task to generate one or more standalone task.

I have created a CompressTask class as follow.

class CompressTask: TaskBase
{
    TaskBase task;

    //runtime parameters
}

Now, its looks very weird to me that the CompressTask is derived from TaskBase and it also contains an instance of TaskBase. Is it correct to have such class? Or are there any better class representation of the given case.


Overall this structure is not uncommon, you are somewhat starting to go down the road of the Composite pattern. Your CompressTask is somewhat acting like the Composite and your StandaloneTask is like the Leaf.

I'd recommend reading up on that design pattern and potentially think about making it easier for a consumer to consume any subclass of TaskBase regardless of it being a CompressTask or StandaloneTask. That will strengthen your design and simplify consumption.