Lets look at the classes

1. Customer class is pretty simple, its a data class

2. LineItem class captures the information regarding the Items

3. Order class has information regarding the Customer and his cart which represents list of LineItems.

4. LineItem class has method to calculate the price of line item based on quantity and price per quantity.

5. Order class has two methods, the first one is total() which finds the actual price and the other one is finalPrice() which computes price after promotional discount.

Now look at the Order class constructor , you see that we accept a parameter of type Promotion, which is an interface.

There are three promotional discount algorithms [ Strategies ] we have.

1. FidelityPromotion: 5% discount for customers with 1000 or more fidelity points

2. BulkPromotion: As the name suggests , 10% discount for each LineItem with 20 or more units

3. LargeOrderPromo: 7% discount for orders with 10 or more distinct items

If you look at the implementation of these classes , its pretty straight forward. Have a some time glancing at these classes.

The main method , really test drives. It creates few customers with varying fidelity score, then it creates some carts for the customers. One cart is simple and its just to show the effect of FidelityPromotion. Other cart creates bulk and large orders respectively.

One interesting thing that we have done here, is we tried to find out what would have been the best promotional strategy for a given customer with specific fidelity score and a particular cart.

fun findBestPromo(order: Order, promos: List<Promotion>): Sequence<Pair<String, Double>>?

{

return promos.asSequence()

.map { Pair(it.toString(),it.discount(order))}

.sortedBy { it.second }

}

This function gets the list of all available promos, then it finds out discount for a given order and returns a Pair to list name of the strategy used and the discount in that strategy. We sort the list of pairs using the discount which is the 2nd variable in the Pair.

Lets look at how to implement this using function rather than using classes for Promotion strategy.

Changes to Promotion Interface and implementations

1.All the classes for Promotion are gone.

2. Interface Promotion is gone

3. Only methods remain as functions and each function of course gets unique name.

Changes to Order Class

Now Order class instead of receiving promo parameter of type Promotion, expects a function that takes Order as input and returns Double.

Changes to findBestPromo()

Changes to main() method

Here is the complete source code.

I hope you enjoyed the article. Don’t forget to clap if you have :-)

I hope to explore further Kotlin and i will share as soon as i have something useful.

Please checkout my other articles and see if you like them. By the way two of them appeared in Kotlin Weekly news letter. so might be worth the read.