Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class Hierarchy

Tags:

c++

Please don't mind about the syntax. I thought of making the post as brief as possible.

We have a class hierarchy as below.

// abstract class.   
class BaseProd   
// concrete classes.   
class Prod1 : public BaseProd   
class Prod2 : public BaseProd   
class Prod3 : public BaseProd   

Each class has 3 sub classes like, Prod1New, Prod1Cancel and Prod1Modify the same case for the other 2 classes. Now, since New, Cancel and Modify are the events, we can represent them using enum.

The problem is, each class has lot of methods that are very specific to each event. Eg.

getRec(); // has specific implementations for each event.   

Let's say there is something like process method.

void Prod1::process()
{
   getRec(); // Each derived class overrides the method.   
   getPayment();// Each derived class overrides the method.   
}  

This way, we have 13 classes for 3 products having 3 events each.
If we have 2 more products the classes would grow by 8.

Can we have any alternate approach to this hierarchy?

UPDATE: The suggestion made by Tyler works only when Prod1's NewEvent and Prod2's NewEvent have the same implementation. Right? But in this case it is not. Atleast for some of the methods it is not.

like image 298
Jagannath Avatar asked Dec 06 '25 10:12

Jagannath


1 Answers

I don't see why the New, Cancel, and Modify messages should be subclasses of the products that they apply to. This doesn't satisfy the "is-a" relationship that should define inheritance. If class D inherits from class B, the statement "Every D is a B" should make sense and always be true. "A Prod1 is a BaseProd" (i.e. "Every specific product is a product") -- that is true and makes sense.

But in the case of events, a Prod1Cancel is not a Prod1. It doesn't make sense to say "Every product1 cancellation event is a product1." Rather, a Prod1Cancel is an event relating to Prod1, so it makes more sense that the Prod1Cancel class should contain a Prod1 object, rather than inheriting from it.

Since all of your products inherit from a BaseProd class, you should really only need one class for each event, and not one class per event per product type, if you define your event classes like this:

class NewProductEvent {

   public:

     explicit NewProductEvent(BaseProd* product)
       : m_product(product)
     { /* ... */ }

     void getRec() { /* ... */ }
     void getPayment() { /* ... */ }

   private:

     BaseProd* m_product; // Use this to access the data that the event 
                          // needs from the product
};

Then, inside your Prod1::process() method, you could generate a NewProductEvent event for the current object, and call the appropriate methods on it:

void Prod1::process()
{
  NewProductEvent event(this);

  event.getRec();
  event.getPayment();
}
like image 163
Tyler McHenry Avatar answered Dec 07 '25 22:12

Tyler McHenry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!