views:

68

answers:

2

Hello,

For each product there are associated cost calculators like: discount, discount by merchant, bonus by merchant, monthly discount etc. In future, more cost calculators would be added.

We have a concrete product class and many decorators for each cost calculation. All products should use all of the calculators, because the calculators decide to apply their calculations by the product's properties like product merchant id, category id, color etc.

And, there are millions of products in our system which needs to be calculated. So, we better cache the decorated calculators. Because, decorating each product entity in runtime would be expensive. But this is hard with decorator pattern. It seems like a smell to use this pattern in our situation.

What do you suggest? Should we use decorators, strategy or chain-of-responsibility pattern? Or no-pattern.

A: 

In a strategy pattern, the intent of the object changes.

Therefore, I think strategy would be a good choice.

Sujay Ghosh
A: 

All products should use all of the calculators, because the calculators decide to apply their calculations by the product's properties like product merchant id, category id, color etc.

If you need to have all products use all decorators, then you're not really gaining any benefit from the pattern. Does this mean that if you implement a new decorator, all existing entities must be updated to use that new decorator?

Decorators should be applied to products only when necessary, and only those decorators that are needed should be applied.

I think you should remove the decision from within the decorators; something else should decide whether to apply a decorator, in which case it wraps the product in the appropriate decorators. This way you know that if a product is wrapped in a decorator, that decorator is affecting (effecting?) the product.

Shakedown
Decorators do calculation based on product properties, we loop on a list of products to apply these calculations to all of the products. So, decorating each of these products on every iteration, we thought that caching of calculation logic would be good idea. But this is hard to do w/decorators. So, better approach would be to use strategy pattern as a set/get on product.Product p = new Product();p.setCalculationStrategy( listOfCalculators );p.price(); // will invoke all of the calculators, only the interested calculators will calculate
p.price() { return listOfCalculators.price();}listOfCalculators.price() { each calculator do { //.... } return price;}