Background
The company that I work for sells a review course for 2 different medical field licensure exams. For each course, CourseA and CourseB, we offer a Live, in-person version and an Online only version.
We do not use an e-commerce package because the they way our products work is so specialized that using an existing wasn’t feasible, and would be overkill.
The system, as it was originally built wasn’t not intended to have a person registering for more than one version of our course. However, we are finding that many, many of them want to purchase the Live and Online versions together. In order to facilitate this, we are implementing a discount/package system that would give customers a discount for purchasing both. Most of the unique stuff does come into play more when it is a registration for an existing customer than if is a brand new customer
Currently, the system looks like this:
abstract class Registration{}
class CourseALiveRegistration extends Registration{}
class CourseAOnlineRegistration extends Registration{}
class CourseBLiveRegistration extends CourseALiveRegistration{}
class CourseBOnlineRegistration extends CourseAOnlineRegistration{}
The CourseB classes extend the equivalent CourseA classes because each of their requirements are the same, but just things like price, subscription length, and a few other data values differ based on whether the registration is for CourseA or CourseB (For example, CourseA gets access to some content for 1 year while CourseB gets access for only 6 months to the same content).
Right now the registration process uses one of these registration classes to do its work. What I’d like some advice on is how to architect this system so that if, for example I register for both the Live and Online version of CourseA I would get a discount.
The reason for having multiple registration classes is because each type of registration CourseALive, CourseAOnline, CourseBLive, CourseBOnline have different sets of rules that control them. If the only differences were the actual things like cost, I could use just one class. However each has some unique business logic associated with it so each is a unique class to encapsulate the unique functionality. For example, if a customer has already purchase CourseBLive, they are able to purchase CourseALive for a discount (CourseB is a lower level license exam).