Calculating the number of candy bars and gumballs that can be redeemed using coupons
Looking at this statement, it looks as if numberOfGumballs and numberOfCandybars are independently derived from numberOfCoupons:


System.out.println(numberOfCandybars(numberOfCoupons)
        + " candybar(s) and " + numberOfGumballs(numberOfCoupons)
        + " gumball(s).");



But they are not independent, because numberOfGumballs actually depends on numberOfCoupons and numberOfCandybars too. Hiding this fact is not a good thing: one might expect that changing the behavior of numberOfCandybars won't affect the behavior of numberOfGumballs, but it actually will, which is confusing.

If you think about it, it would be best if numberOfCandybars returned 2 values:


The number of candy bars our coupons could buy
and, the number of coupons left


With these two values, we could use the number of coupons left to make another call to numberOfGumballs, and keep the number of candy bars for printing later. That way, the relationships between the functions could be well visible.

Of course, Java can only return a single value. But the single value can be an object, which can contain multiple values.

So let's start over. We have items: Candy bar, Gumball. We have some kind of a vending machine, that you put coupons into, select the item you want, and it gives back a number of items and change (remaining coupons).

Let's model the items with an enum, and give them a price too.

enum Item {
    CandyBar(10),
    Gumball(3);

    final int price;

    Item(int price) {
        this.price = price;
    }
}


And let's model the machine and the output it gives:

class AutomaticCandyMachineOutput {
    final Item item;
    final int itemCount;
    final int change;

    AutomaticCandyMachineOutput(Item item, int itemCount, int change) {
        this.item = item;
        this.itemCount = itemCount;
        this.change = change;
    }
}

class AutomaticCandyMachine {
    AutomaticCandyMachineOutput redeemCouponsForItems(int coupons, Item item) {
        int itemCount = coupons / item.price;
        int change = coupons % item.price;
        return new AutomaticCandyMachineOutput(item, itemCount, change);
    }

    AutomaticCandyMachineOutput redeemCouponsForCandybars(int coupons) {
        return redeemCouponsForItems(coupons, Item.CandyBar);
    }

    AutomaticCandyMachineOutput redeemCouponsForGumballs(int coupons) {
        return redeemCouponsForItems(coupons, Item.Gumball);
    }
}


This seems a more natural, flexible and extensible design. Now we can rewrite the original statement like this:

int coupons = 99;
AutomaticCandyMachine machine = new AutomaticCandyMachine();
AutomaticCandyMachineOutput output1 = machine.redeemCouponsForCandybars(coupons);
AutomaticCandyMachineOutput output2 = machine.redeemCouponsForGumballs(output1.change);

String.format(
    "%d candybar(s) and %d gumball(s)",
    output1.itemCount,
    output2.itemCount);