First year of Software Engineering, and we're learning OOP within Java. Came across an extension task to gain more credits. But could not think of what to do:

First Step: Design a checkout system

Build a checkout system for a shop which sells 3 products say Bread, Milk, and Bananas. Costs of the products are : Bread - $1, Milk - $0.60 and Banana - $0.40 Build a system to checkout a shopping cart that can have multiples of these 3 products and displays the order total. Examples are: Bread, Milk, Banana = $2.00 Bread, Bread, Milk, Banana = $3.00 Milk, Banana, Milk, Banana = $2.00

As a next step: enhance the code to apply the below discounts and offers

Buy one bread and get another bread for free Buy 3 Milk for the price of 2 Buy 2 Bananas and get one free

First part was rather straightforward, i went on and completed this by doing:

public class Cart {

    List<String> items;
    double total;

    public Cart(){
        items = new ArrayList<String>();

    public void addItems(String item){

    public void removeItems(String item){

    public void getNumberOfItems(){

    public String getItemName(int index){
        return items.get(index);

    public void getTotalOfCart(){
        total = 0;
        for(String x: items){
            if (x.equals("A")){
                total += 3.0;
            }else if (x.equals("B")){
                total += 5.0;
            }else if (x.equals("C")){
                total += 2.50;

But now when it comes to implementing the second part of the challenge. I have no idea where to start and what to do. I'm sure this problem is probably fairly standard in terms of implementing rules for things like discounts etc. I just wanna know what my next step(s) is/should be & where possible to start if i wanted to go further with the theory behind this.

  • I would suggest you start with an item base class that contains the price of the item and implement derived classes for the different items. Keep a list of the items and at check out process the list for the deals and adjust the prices accordingly
    – Mike
    Apr 21, 2017 at 21:27
  • @Milke I tried to go for that approach but I cannot seem to be able to implement an Item Class for each separate items. Probably due to the fact i'm inexperienced with this. Any chance you could help with? Or possibly point me in the right direction Apr 22, 2017 at 0:01
  • Since this is for an OOP assignment, I don't want to take you too far without learning the basics. You should look into classes and inheritance and polymorphism. You cart should contain a list of instances of type item. Each instance will be of a specific derived item type. The Catt should be able to process the list and use logic to apply the discounts. Discounts themselves could also be there own classes and the cart could determine which ones to apply to the total.
    – Mike
    Apr 22, 2017 at 19:24
  • Start small, test and then expand the solution. Maybe start with one type of item and the discount for that. Then add the others. Also you will probably get partial credit for any working example so use source code tool or keep backups of working solutions to be able to hand it in.
    – Mike
    Apr 22, 2017 at 19:27

3 Answers 3


Since you are learnig OOP i help you with the busines part:

You have product specific discounts (discount strategy) that depend on cartitem quantity

Milk $0.60
Buy 3 Milk for the price of 2 = discount is 0.60 per 3 Milk = 0.60*int(cartitem.quantity / 3)

cart has 7 milk á 0.60 = 4.20
minus milk-discount int(quanty/3) * 0.60 = int(7/3) * 0.60 = 2 * 0.60 = 1.2

- 1.2
= 3.00

This should give you enough info to design classes Product , ProductDiscountStrategy, Cart, CartItem


Yes, a common problem in e-commerce sites, not easily solved if you have many product and offers.

My approach is to give each item a price rather than having just a single total price. Think of it as a receipt showing you which items have been reduced.

Have a class Offer which includes required items in the basket for the offer to apply and a pricing function which takes the complete basket and the item to be priced.

select all offers which apply to your basket, for each item call each pricing function and apply the best deal.

Now you will also notice that offers everyone understands like buy one get one free, are in fact more complicated. ie buy one (which has not previously been used to get one free) and get one free.

By passing the entire basket (with pricing, I call it a Receipt) into the pricing function you have enough information to be able to figure this kind of thing out and apply the correct price per item.

  • Right in theory I do see what you're saying and it does make sense. Although i'm finding it hard to see how i could possibly implement the Offer class? Apr 21, 2017 at 15:21
  • in practice. I have worked at more than one large e-company. obvs ive simplified somewhat. but essentialy you make offer classes per type of offer, so OfferBuyXGetYFree would have settings for X Y and product type set on instanciation and calculation code which check how many bought and free products you have inthe basket
    – Ewan
    Apr 21, 2017 at 15:47
  • the problem in real systems is the sales guys make up a new type of offer every other day, forget about the old ones and dont think about how they will interact. "free magazine the first time someone buys product X" "10% off dresses if total spend is over Y not including shoes, but do include sandals" etc
    – Ewan
    Apr 21, 2017 at 15:53
  • which is why the other answer although correct for your problem isnt great. your professor will immediately throw in another type of offer, or a price change and ask how your code would handle it
    – Ewan
    Apr 21, 2017 at 15:58
  • I see yes, that is something which was required was making a system that could work well with offers that would constantly change. Would you say first step to possible have a class which would store all the items? Apr 21, 2017 at 16:19

@Milke I tried to go for that approach but I cannot seem to be able to implement an Item Class for each separate items.

Lessons learned, up front:

  • Don't over analyze. It's clear an item (Product) has a name and price. The rest will evolve with the overall design.
  • Override Equals & ToString is often beneficial. ToString in particular when you know there is output, like a receipt. Each class should worry only about how to output itself.
    • collection classes use equals.
    • "identity" equality is common in the real world.
    • Single Responsibility Principle at its most fundamental.
  • Signs of good design:
    • small classes
    • small methods
    • more classes because each has a "single responsibility"
    • These traits tend to just happen as a consequence of making good self-responsible classes.

NOTE: treat this example as pseudo code. I haven't coded Java in a while. I leave out important stuff like checking for null arguments.


public class Product {
    public Product (string name, decimal price) {
       this.Price = price;
       this.Name = name;

    public decimal GetPrice() { return this.Price; }

    // nobody overrides Equals and ToString. but you should!

    public override bool Equals ( object otherProduct ) {
       return this.Name.Equals(otherProduct.Name);

    public override string ToString () {
       return name + "   " + price;

public class Cart {
    protected List<Product> items;

    public void AddItem( Product newItem ) {  }

    public decimal CartTotal() {
       decimal total = 0;

       foreach (Product thing in items) { total += thing.GetPrice(); }
       return total;


What if I buy multiple items? Well, you add each one - AddItem() - so no problem. Then I see I need to know how many of each kind to calculate total cost. How to implement?

  • Product is just a "thing". not the right place. A product knows about itself. It should not know about the Cart and its other contents.
  • The Cart has a list of everything. This is the right class.
    • a method, likely private, to add up quantities. Even methods need to follow SRP.
    • A dictionary of product types:count. From experience I like this. And the code will benefit from Product.Equals override.


public class Cart {
   protected Dictionary<Product, int> items;
   // I think we can throw away the List<Product>

   public void AddItem ( Product newItem ) {
      if ( ! items.Contains(newItem) )    // SRP in action


   public decimal CartTotal() {
      foreach ( thing in items ) { 
         total += items[thing].GetPrice * items[thing].count;

   // code in "cart"/"shopping" terminology. aka Domain Specific Language - DSL.
   public string Receipt() { return this.ToString(); } 

   public override string ToString() {
      string me = "";

      foreach ( thing in items ) {
         me += items[thing].ToString() + "\n";   // SRP in action

      me += "\n\n Total: " + CartTotal();
      return me;


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.