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.
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
Dinherits from classB, the statement “EveryDis aB” should make sense and always be true. “AProd1is aBaseProd” (i.e. “Every specific product is a product”) — that is true and makes sense.But in the case of events, a
Prod1Cancelis not aProd1. It doesn’t make sense to say “Every product1 cancellation event is a product1.” Rather, aProd1Cancelis an event relating toProd1, so it makes more sense that theProd1Cancelclass should contain aProd1object, rather than inheriting from it.Since all of your products inherit from a
BaseProdclass, 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:Then, inside your
Prod1::process()method, you could generate aNewProductEventevent for the current object, and call the appropriate methods on it: