Question

Suppose I have an Item class which is the base class of a composite pattern.

I have two specific subclasses Movie and Music containing different data :

  • Movie : director, producer, list of actors ...
  • Music : chanteur, number of record sold ...

If I want to access Movie data (for example) in a client code, I need to downcast the Item corresponding to it because getProducer() is not a method of the Item class.

I am stuck between three different approach :

  1. Put all the subclass methods in the Item interface
  2. Downcast Item in client code
  3. Use an object that would extract the data from the different Item (using a kind of visitor pattern)

The third proposition seems interesting because it hides Item subclasses to client, but I don't know how to let client update an Item (for example change the producer of a movie).

The Item subclasse types supported by the application will grow through releases, and I want to design it to facilitate those type additions.

Maybe I am totally going in the wrong way and there is a different and better solution.

Was it helpful?

Solution

Option 1 is a bad idea, simply because getProducer() does not belong to an item.

Option 3 would work if you'd also proved setters in addition to the getter methods you were planning to implement there.

Option 2 sounds the most reasonable to me. Casting is a common task in a polymorphic solutions and in your case it is adequate.

OTHER TIPS

IMO, Movie and Music objects are completely different and should not be derived from a common base class. But, if you still want to do it, modify the Item class as shown below (Just an example code. please do not use this code as-is)

abstract class Item
{
    virtual object GetData(string sDataID);
}

Now, in the derived classes you can override this method something like below.

class Movie: Item
{
    private Producer m_Producer = new Producer();
    override object GetData(string sDataID)
    {
        object ret = null;
        switch(sDataID)
        {
            case "Producer":
               ret = m_Producer;
               break;
        }           
    }

And, in the client code you can do something like below.

Item objItem = new Movie();
Producer objProducer = (Producer)objItem.GetData("Producer");

You get the idea!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top