Modeling question about categorization. To subtype or not to?
I need some advice on how to model this simple categorization (?) example:
I have a product. A product can be of different typ开发者_运维技巧es, such as ProductType 1, ProductType 2, and ProductType 3. All products have a part number and a name. Where they differ, is the way their prices are calculated.- Products in type 1's price are dependent on how many there are of the product. So if I have 5 products, the price is $x. If I have 20 products, the price is $y, and so on.
- Products in type 2’s price are dependent on each products weight. If the weight is 5 kg, the price is $x, and so on.
- Products in type 3’s have a simple price, like $x for each product.
The way I see it, each “price structure” needs to have a dedicated table/class. A product will then have a reference to its price structure, dependant on the type of the product. Would you just create a “product type” table and have an attribute called Type on the Product class, or would you use generalization, so Product 1/2/3 are a subtype of Product? There will be like 5 different price structures, and the way the price is calculated differs from each type. So the logic calculating the total price for an order is dependent on each product type.
Can you give me some advice on how to model this the best way? If I choose the approach where there’s a Type attribute on the Product class, I imagine that I will get lots of if-else statements in my code. Where if I choose to subclass them, each class can be responsible for calculating the correct price, or whatever it is asked to do.
This sounds to me like a perfect example of when to use the Strategy pattern. If you use class inheritance to define how a product is priced, you'll have to re-compile your entire system if someone later decides WidgetXYZ should now be priced by weight, instead of having a simple price.
I would define each product as having a "PricingStrategy" - in your case this would be either "volumeDiscount", "byWeight", or "simple". You could then use a Factory to provide the correct PriceCalculator object depending on the product's strategy, and that priceCalculator would calculate the product's price accordingly.
My suggestion is that in your relational data model, you will have the type column to distinguish the record type. In the code, you should definitely use sub-classing. The domain model should be independent of the underlying data model as much as possible and your description well support the need of sharing attributes (using ABC - abstract base class for Product), subtype to P1, P2, P3 (give it a meaningful domain name) and polymorphism to vary the price calculation.
Your order will hold a list of base product reference and to get the total, you will ask each product for the price and accumulate them using iterator.
精彩评论