Carrying on from my previous article about heavy lifting models Heavy lifting models I thought I would write a little about decorators and models.

What is a decorator
Briefly a decorator is an class whose purpose it is to decorate another object adding functionality or adjusting the current functionality. This can sometimes be a good alternative to subclassing.

A quick example

abstract class PricingDecorator implements Pricing {

Pricing price;

public PricingDecorator(Pricing price) {
this.price = price;
}
}

public class DiscountPricingDecorator extends PricingDecorator {

Discount discount;

public DiscountPricingDecorator(Pricing price, Discount discount) {
super(price);
this.discount = discount;
}

@Override
public Float getPrice() {
if (discount.getType() == Discount.DISCOUNT_TYPE_PERCENTAGE) {
return price.getPrice() - (discount.getValue() / 100) * price.getPrice();
} else if (discount.getType() == Discount.DISCOUNT_TYPE_PRICE) {
return discount.getValue();
}
return price.getPrice();
}
}

public class DiscountImp implements Discount {

public int type;
public Float value;

public DiscountImp(int type, Float value) throws InvalidDiscountType {
this.checkType(type);
this.type = type;
this.value = value;
}

@Override
public int getType() {
return type;
}

private void checkType(int type) throws InvalidDiscountType {
if (type == Discount.DISCOUNT_TYPE_PERCENTAGE || type == Discount.DISCOUNT_TYPE_PRICE) {
return;
} else {
throw new InvalidDiscountType("invalid discount type");
}
}

@Override
public void setType(int type) throws InvalidDiscountType {
this.checkType(type);
this.type = type;
}

@Override
public Float getValue() {
return value;
}

@Override
public void setValue(Float value) {
this.value = value;
}

}

So some of the above code is contrived and compacted to save too much code. The above would be used to decorate a Pricing Object with a various Discounts. As shown below:


try{
Discount discount = new DiscountImp(Discount.DISCOUNT_TYPE_PERCENTAGE, new Float(10));
Pricing price = new DiscountPricingDecorator(new ProductPricing(new Float(30)), discount);
System.out.print("discounted price" + price.getPrice());
}catch(InvalidDiscountType e){
e.printStackTrace();
}

It may be tempting to subclass your Pricing Object maybe into a DiscountedPricing:
and this is also an ok solution but in scenarios as seen above, I believe a Decorator is a better way of achieving this solution as I think it is clearer what is happening but because we have stuck to interface driven design we can reuse the decorator with other Pricing implementations and Discount implementations. It also maintains the simplicity of your Pricing Model class.

Sorry, the comment form is closed at this time.

   
© 2012 Craig Brookes Suffusion theme by Sayontan Sinha