vendredi 25 septembre 2015

Is it bad to use interface and then check for implementation type?

Consider the following scenario:

I want to design a discount calculator which gets me the discount that can be applied to an order. There are two types of order: Online and In-Store. Based on type of the order and total amount of the order, a discount calculator calculates the discount.

I programmed to demonstrate the scenario in C# but the problem is language independent. In the below code, DiscountCalculator class calculates the discount by examining the actual type of input parameter.

I feel checking the actual type of IOrder argument in GetDiscount method is code smell; because I hid the implementation details behind the interface IOrder, then I somehow bring out of the box what was meant to be hidden.

    interface IOrder
    {
        int GetTotalPrice();
    }

    class InStoreOrder : IOrder
    {
        public int GetTotalPrice() { // returns the price of order }
    }

    class OnlineOrder : IOrder
    {
        public int GetTotalPrice() { // returns the price of order }
    }

    class DiscountCalculator
    {
        public int GetDiscount(IOrder order)
        {
            Type orderType = order.GetType();
            if (orderType == typeof(OnlineOrder))
            {
                if (order.GetTotalPrice() < 100)
                    return 2;
                else
                    return 5;
            }
            if (orderType == typeof(InStoreOrder))
            {
                if (order.GetTotalPrice() < 100)
                    return 3;
                else
                    return 6;
            }
            else
                throw new Exception("Unknown order type:" + orderType.Name);
        }
    }

Any idea?

Aucun commentaire:

Enregistrer un commentaire