Simple barista application to calculate the price of a drink based on different ingredients
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
The scenario is that a customer orders a coffee from a vending machine by selecting a choice from several categories,
such as size, flavor, and creamer type.
Given their choices, we then have to figure out the cost.
The twist is that the various creamer choices cost slightly more if you get an extra-large coffee.
For example, if you choose milk as your creamer,
it is normally 50 cents;
but, if you also choose XL as your size, the milk costs 60 cents.
public enum Coffee
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unit_price;
private Coffee(String name, double unit_cost)
this.name = name;
this.unit_price = unit_cost;
public String getName()
return name;
public double getUnit_price()
return unit_price;
public enum Creamer
NONE("None", 0.0),
MILK("Milk", 0.50),
HALF_N_HALF("Half and Half", 0.25),
TALL_MILK("Milk", 0.60),
TALL_HALF_N_HALF("Half and Half", 0.35),
GRANDE_MILK("Grande Milk", 0.65),
GRANDE_HALF_N_HALF("Grande Half and Half", 0.45),
VENTI_MILK("Venti Milk", 0.70),
VENTI_HALF_N_HALF("Venti Half and Half", 0.55),
TRENTA_MILK("Trenta Milk", 0.75),
TRENTA_HALF_N_HALF("Trenta Half and Half", 0.60);
private String name;
private double price;
private Creamer(String name, double price)
this.name= name;
this.price = price;
public String getName()
return name;
public void setName(String name)
this.name = name;
public double getPrice()
return price;
public void setPrice(double price)
this.price = price;
public class PricingEngine
public static double priceBasedOnSize(Map<String, Enum> ingredients)
double totalCost = 0.0;
Coffee coffee = (Coffee) ingredients.get("Coffee");
totalCost += coffee.getUnit_price();
Size size = (Size) ingredients.get("Size");
Creamer creamer = (Creamer) ingredients.get("Creamer");
// get price based on the creamer and cup size
String priceBySize = size.name() + "_" + creamer.name();
totalCost += Creamer.valueOf(priceBySize).getPrice();
return totalCost;
public enum Size
TALL("Tall"),
GRANDE("Grande"),
VENTI("Venti"),
TRENTA("Trenta");
private String name;
private Size(String name)
this.name= name;
public String getName()
return this.name();
public class BaristaMain
public static void main(String args)
Scanner in = new Scanner(System.in);
boolean appRunning = true;
Map<String, Enum> map = new HashMap<String, Enum>();
System.out.println("Welcome to automatic coffee dispensing servicenn");
while (appRunning)
System.out.print("1. Caffe Americano");
System.out.print(" 2. Caffe Latte");
System.out.print(" 3. Caffe Mocha");
System.out.print(" 4. Cappuccino");
System.out.print(" 5. Coffee");
System.out.println(" 6. Decaf Coffee");
System.out.println("Please enter your choice: ");
int chioiceOfCoffee = in.nextInt();
if (chioiceOfCoffee == 1)
map.put("Coffee", Coffee.CAFFEE_AMERICANO);
else if (chioiceOfCoffee == 2)
map.put("Coffee", Coffee.CAFFEE_LATTE);
else if (chioiceOfCoffee == 3)
map.put("Coffee", Coffee.CAFFE_MOCHA);
else if (chioiceOfCoffee == 4)
map.put("Coffee", Coffee.CAPPUCCINO);
else if (chioiceOfCoffee == 5)
map.put("Coffee", Coffee.COFFEE);
else if (chioiceOfCoffee == 6)
map.put("Coffee", Coffee.DECAF_COFFEE);
else
System.out.println("Your entry: " + chioiceOfCoffee + " is not valide. Please enter a valid choice.");
System.out.print("1. Tall(Slept 8-10 Hours)");
System.out.print(" 2. Grande(Slept 5-7 Hours)");
System.out.print(" 3. Venti(Slept 0-4 Hours");
System.out.println(" 4. Trenta(WTF is sleep?)");
System.out.println("Please enter your cup size: ");
int cupSize = in.nextInt();
if (cupSize == 1)
map.put("Size", Size.TALL);
else if (cupSize == 2)
map.put("Size", Size.GRANDE);
else if (cupSize == 3)
map.put("Size", Size.VENTI);
else if (cupSize == 4)
map.put("Size", Size.TRENTA);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.print("1. NONE");
System.out.print(" 2. MILK");
System.out.println(" 3. HALF_N_HALF");
System.out.println("Please enter your choice of creamer: ");
int creamer = in.nextInt();
if (creamer == 1)
map.put("Creamer", Creamer.NONE);
else if (creamer == 2)
map.put("Creamer", Creamer.MILK);
else if (creamer == 3)
map.put("Creamer", Creamer.HALF_N_HALF);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.println();
System.out.println("Dispensing.............");
System.out.println("Total Cost: " + PricingEngine.priceBasedOnSize(map));
System.out.println("Enjoy your coffee!");
I know there are 5 other ways (such as decorator pattern) to do this but for some reasons the solution has to have enum.
Let me know what you guys think about this solution. Any improvement on the pricing engine will be helpful.
There can be other categories as well that can change the price of the coffee.
java enum
add a comment |Â
up vote
1
down vote
favorite
The scenario is that a customer orders a coffee from a vending machine by selecting a choice from several categories,
such as size, flavor, and creamer type.
Given their choices, we then have to figure out the cost.
The twist is that the various creamer choices cost slightly more if you get an extra-large coffee.
For example, if you choose milk as your creamer,
it is normally 50 cents;
but, if you also choose XL as your size, the milk costs 60 cents.
public enum Coffee
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unit_price;
private Coffee(String name, double unit_cost)
this.name = name;
this.unit_price = unit_cost;
public String getName()
return name;
public double getUnit_price()
return unit_price;
public enum Creamer
NONE("None", 0.0),
MILK("Milk", 0.50),
HALF_N_HALF("Half and Half", 0.25),
TALL_MILK("Milk", 0.60),
TALL_HALF_N_HALF("Half and Half", 0.35),
GRANDE_MILK("Grande Milk", 0.65),
GRANDE_HALF_N_HALF("Grande Half and Half", 0.45),
VENTI_MILK("Venti Milk", 0.70),
VENTI_HALF_N_HALF("Venti Half and Half", 0.55),
TRENTA_MILK("Trenta Milk", 0.75),
TRENTA_HALF_N_HALF("Trenta Half and Half", 0.60);
private String name;
private double price;
private Creamer(String name, double price)
this.name= name;
this.price = price;
public String getName()
return name;
public void setName(String name)
this.name = name;
public double getPrice()
return price;
public void setPrice(double price)
this.price = price;
public class PricingEngine
public static double priceBasedOnSize(Map<String, Enum> ingredients)
double totalCost = 0.0;
Coffee coffee = (Coffee) ingredients.get("Coffee");
totalCost += coffee.getUnit_price();
Size size = (Size) ingredients.get("Size");
Creamer creamer = (Creamer) ingredients.get("Creamer");
// get price based on the creamer and cup size
String priceBySize = size.name() + "_" + creamer.name();
totalCost += Creamer.valueOf(priceBySize).getPrice();
return totalCost;
public enum Size
TALL("Tall"),
GRANDE("Grande"),
VENTI("Venti"),
TRENTA("Trenta");
private String name;
private Size(String name)
this.name= name;
public String getName()
return this.name();
public class BaristaMain
public static void main(String args)
Scanner in = new Scanner(System.in);
boolean appRunning = true;
Map<String, Enum> map = new HashMap<String, Enum>();
System.out.println("Welcome to automatic coffee dispensing servicenn");
while (appRunning)
System.out.print("1. Caffe Americano");
System.out.print(" 2. Caffe Latte");
System.out.print(" 3. Caffe Mocha");
System.out.print(" 4. Cappuccino");
System.out.print(" 5. Coffee");
System.out.println(" 6. Decaf Coffee");
System.out.println("Please enter your choice: ");
int chioiceOfCoffee = in.nextInt();
if (chioiceOfCoffee == 1)
map.put("Coffee", Coffee.CAFFEE_AMERICANO);
else if (chioiceOfCoffee == 2)
map.put("Coffee", Coffee.CAFFEE_LATTE);
else if (chioiceOfCoffee == 3)
map.put("Coffee", Coffee.CAFFE_MOCHA);
else if (chioiceOfCoffee == 4)
map.put("Coffee", Coffee.CAPPUCCINO);
else if (chioiceOfCoffee == 5)
map.put("Coffee", Coffee.COFFEE);
else if (chioiceOfCoffee == 6)
map.put("Coffee", Coffee.DECAF_COFFEE);
else
System.out.println("Your entry: " + chioiceOfCoffee + " is not valide. Please enter a valid choice.");
System.out.print("1. Tall(Slept 8-10 Hours)");
System.out.print(" 2. Grande(Slept 5-7 Hours)");
System.out.print(" 3. Venti(Slept 0-4 Hours");
System.out.println(" 4. Trenta(WTF is sleep?)");
System.out.println("Please enter your cup size: ");
int cupSize = in.nextInt();
if (cupSize == 1)
map.put("Size", Size.TALL);
else if (cupSize == 2)
map.put("Size", Size.GRANDE);
else if (cupSize == 3)
map.put("Size", Size.VENTI);
else if (cupSize == 4)
map.put("Size", Size.TRENTA);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.print("1. NONE");
System.out.print(" 2. MILK");
System.out.println(" 3. HALF_N_HALF");
System.out.println("Please enter your choice of creamer: ");
int creamer = in.nextInt();
if (creamer == 1)
map.put("Creamer", Creamer.NONE);
else if (creamer == 2)
map.put("Creamer", Creamer.MILK);
else if (creamer == 3)
map.put("Creamer", Creamer.HALF_N_HALF);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.println();
System.out.println("Dispensing.............");
System.out.println("Total Cost: " + PricingEngine.priceBasedOnSize(map));
System.out.println("Enjoy your coffee!");
I know there are 5 other ways (such as decorator pattern) to do this but for some reasons the solution has to have enum.
Let me know what you guys think about this solution. Any improvement on the pricing engine will be helpful.
There can be other categories as well that can change the price of the coffee.
java enum
1
...for some reasons the solution has to have enum...
could you elaborate on this, it seems like an artificial constraint, and the constraint may also affect answers
â jrtapsell
Feb 4 at 21:27
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
The scenario is that a customer orders a coffee from a vending machine by selecting a choice from several categories,
such as size, flavor, and creamer type.
Given their choices, we then have to figure out the cost.
The twist is that the various creamer choices cost slightly more if you get an extra-large coffee.
For example, if you choose milk as your creamer,
it is normally 50 cents;
but, if you also choose XL as your size, the milk costs 60 cents.
public enum Coffee
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unit_price;
private Coffee(String name, double unit_cost)
this.name = name;
this.unit_price = unit_cost;
public String getName()
return name;
public double getUnit_price()
return unit_price;
public enum Creamer
NONE("None", 0.0),
MILK("Milk", 0.50),
HALF_N_HALF("Half and Half", 0.25),
TALL_MILK("Milk", 0.60),
TALL_HALF_N_HALF("Half and Half", 0.35),
GRANDE_MILK("Grande Milk", 0.65),
GRANDE_HALF_N_HALF("Grande Half and Half", 0.45),
VENTI_MILK("Venti Milk", 0.70),
VENTI_HALF_N_HALF("Venti Half and Half", 0.55),
TRENTA_MILK("Trenta Milk", 0.75),
TRENTA_HALF_N_HALF("Trenta Half and Half", 0.60);
private String name;
private double price;
private Creamer(String name, double price)
this.name= name;
this.price = price;
public String getName()
return name;
public void setName(String name)
this.name = name;
public double getPrice()
return price;
public void setPrice(double price)
this.price = price;
public class PricingEngine
public static double priceBasedOnSize(Map<String, Enum> ingredients)
double totalCost = 0.0;
Coffee coffee = (Coffee) ingredients.get("Coffee");
totalCost += coffee.getUnit_price();
Size size = (Size) ingredients.get("Size");
Creamer creamer = (Creamer) ingredients.get("Creamer");
// get price based on the creamer and cup size
String priceBySize = size.name() + "_" + creamer.name();
totalCost += Creamer.valueOf(priceBySize).getPrice();
return totalCost;
public enum Size
TALL("Tall"),
GRANDE("Grande"),
VENTI("Venti"),
TRENTA("Trenta");
private String name;
private Size(String name)
this.name= name;
public String getName()
return this.name();
public class BaristaMain
public static void main(String args)
Scanner in = new Scanner(System.in);
boolean appRunning = true;
Map<String, Enum> map = new HashMap<String, Enum>();
System.out.println("Welcome to automatic coffee dispensing servicenn");
while (appRunning)
System.out.print("1. Caffe Americano");
System.out.print(" 2. Caffe Latte");
System.out.print(" 3. Caffe Mocha");
System.out.print(" 4. Cappuccino");
System.out.print(" 5. Coffee");
System.out.println(" 6. Decaf Coffee");
System.out.println("Please enter your choice: ");
int chioiceOfCoffee = in.nextInt();
if (chioiceOfCoffee == 1)
map.put("Coffee", Coffee.CAFFEE_AMERICANO);
else if (chioiceOfCoffee == 2)
map.put("Coffee", Coffee.CAFFEE_LATTE);
else if (chioiceOfCoffee == 3)
map.put("Coffee", Coffee.CAFFE_MOCHA);
else if (chioiceOfCoffee == 4)
map.put("Coffee", Coffee.CAPPUCCINO);
else if (chioiceOfCoffee == 5)
map.put("Coffee", Coffee.COFFEE);
else if (chioiceOfCoffee == 6)
map.put("Coffee", Coffee.DECAF_COFFEE);
else
System.out.println("Your entry: " + chioiceOfCoffee + " is not valide. Please enter a valid choice.");
System.out.print("1. Tall(Slept 8-10 Hours)");
System.out.print(" 2. Grande(Slept 5-7 Hours)");
System.out.print(" 3. Venti(Slept 0-4 Hours");
System.out.println(" 4. Trenta(WTF is sleep?)");
System.out.println("Please enter your cup size: ");
int cupSize = in.nextInt();
if (cupSize == 1)
map.put("Size", Size.TALL);
else if (cupSize == 2)
map.put("Size", Size.GRANDE);
else if (cupSize == 3)
map.put("Size", Size.VENTI);
else if (cupSize == 4)
map.put("Size", Size.TRENTA);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.print("1. NONE");
System.out.print(" 2. MILK");
System.out.println(" 3. HALF_N_HALF");
System.out.println("Please enter your choice of creamer: ");
int creamer = in.nextInt();
if (creamer == 1)
map.put("Creamer", Creamer.NONE);
else if (creamer == 2)
map.put("Creamer", Creamer.MILK);
else if (creamer == 3)
map.put("Creamer", Creamer.HALF_N_HALF);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.println();
System.out.println("Dispensing.............");
System.out.println("Total Cost: " + PricingEngine.priceBasedOnSize(map));
System.out.println("Enjoy your coffee!");
I know there are 5 other ways (such as decorator pattern) to do this but for some reasons the solution has to have enum.
Let me know what you guys think about this solution. Any improvement on the pricing engine will be helpful.
There can be other categories as well that can change the price of the coffee.
java enum
The scenario is that a customer orders a coffee from a vending machine by selecting a choice from several categories,
such as size, flavor, and creamer type.
Given their choices, we then have to figure out the cost.
The twist is that the various creamer choices cost slightly more if you get an extra-large coffee.
For example, if you choose milk as your creamer,
it is normally 50 cents;
but, if you also choose XL as your size, the milk costs 60 cents.
public enum Coffee
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unit_price;
private Coffee(String name, double unit_cost)
this.name = name;
this.unit_price = unit_cost;
public String getName()
return name;
public double getUnit_price()
return unit_price;
public enum Creamer
NONE("None", 0.0),
MILK("Milk", 0.50),
HALF_N_HALF("Half and Half", 0.25),
TALL_MILK("Milk", 0.60),
TALL_HALF_N_HALF("Half and Half", 0.35),
GRANDE_MILK("Grande Milk", 0.65),
GRANDE_HALF_N_HALF("Grande Half and Half", 0.45),
VENTI_MILK("Venti Milk", 0.70),
VENTI_HALF_N_HALF("Venti Half and Half", 0.55),
TRENTA_MILK("Trenta Milk", 0.75),
TRENTA_HALF_N_HALF("Trenta Half and Half", 0.60);
private String name;
private double price;
private Creamer(String name, double price)
this.name= name;
this.price = price;
public String getName()
return name;
public void setName(String name)
this.name = name;
public double getPrice()
return price;
public void setPrice(double price)
this.price = price;
public class PricingEngine
public static double priceBasedOnSize(Map<String, Enum> ingredients)
double totalCost = 0.0;
Coffee coffee = (Coffee) ingredients.get("Coffee");
totalCost += coffee.getUnit_price();
Size size = (Size) ingredients.get("Size");
Creamer creamer = (Creamer) ingredients.get("Creamer");
// get price based on the creamer and cup size
String priceBySize = size.name() + "_" + creamer.name();
totalCost += Creamer.valueOf(priceBySize).getPrice();
return totalCost;
public enum Size
TALL("Tall"),
GRANDE("Grande"),
VENTI("Venti"),
TRENTA("Trenta");
private String name;
private Size(String name)
this.name= name;
public String getName()
return this.name();
public class BaristaMain
public static void main(String args)
Scanner in = new Scanner(System.in);
boolean appRunning = true;
Map<String, Enum> map = new HashMap<String, Enum>();
System.out.println("Welcome to automatic coffee dispensing servicenn");
while (appRunning)
System.out.print("1. Caffe Americano");
System.out.print(" 2. Caffe Latte");
System.out.print(" 3. Caffe Mocha");
System.out.print(" 4. Cappuccino");
System.out.print(" 5. Coffee");
System.out.println(" 6. Decaf Coffee");
System.out.println("Please enter your choice: ");
int chioiceOfCoffee = in.nextInt();
if (chioiceOfCoffee == 1)
map.put("Coffee", Coffee.CAFFEE_AMERICANO);
else if (chioiceOfCoffee == 2)
map.put("Coffee", Coffee.CAFFEE_LATTE);
else if (chioiceOfCoffee == 3)
map.put("Coffee", Coffee.CAFFE_MOCHA);
else if (chioiceOfCoffee == 4)
map.put("Coffee", Coffee.CAPPUCCINO);
else if (chioiceOfCoffee == 5)
map.put("Coffee", Coffee.COFFEE);
else if (chioiceOfCoffee == 6)
map.put("Coffee", Coffee.DECAF_COFFEE);
else
System.out.println("Your entry: " + chioiceOfCoffee + " is not valide. Please enter a valid choice.");
System.out.print("1. Tall(Slept 8-10 Hours)");
System.out.print(" 2. Grande(Slept 5-7 Hours)");
System.out.print(" 3. Venti(Slept 0-4 Hours");
System.out.println(" 4. Trenta(WTF is sleep?)");
System.out.println("Please enter your cup size: ");
int cupSize = in.nextInt();
if (cupSize == 1)
map.put("Size", Size.TALL);
else if (cupSize == 2)
map.put("Size", Size.GRANDE);
else if (cupSize == 3)
map.put("Size", Size.VENTI);
else if (cupSize == 4)
map.put("Size", Size.TRENTA);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.print("1. NONE");
System.out.print(" 2. MILK");
System.out.println(" 3. HALF_N_HALF");
System.out.println("Please enter your choice of creamer: ");
int creamer = in.nextInt();
if (creamer == 1)
map.put("Creamer", Creamer.NONE);
else if (creamer == 2)
map.put("Creamer", Creamer.MILK);
else if (creamer == 3)
map.put("Creamer", Creamer.HALF_N_HALF);
else
System.out.println(
"Your entry for cup size : " + cupSize + " is not valide. Please enter a valid choice.");
System.out.println();
System.out.println("Dispensing.............");
System.out.println("Total Cost: " + PricingEngine.priceBasedOnSize(map));
System.out.println("Enjoy your coffee!");
I know there are 5 other ways (such as decorator pattern) to do this but for some reasons the solution has to have enum.
Let me know what you guys think about this solution. Any improvement on the pricing engine will be helpful.
There can be other categories as well that can change the price of the coffee.
java enum
edited Feb 5 at 3:12
Jamalâ¦
30.1k11114225
30.1k11114225
asked Feb 4 at 20:55
Guest
565
565
1
...for some reasons the solution has to have enum...
could you elaborate on this, it seems like an artificial constraint, and the constraint may also affect answers
â jrtapsell
Feb 4 at 21:27
add a comment |Â
1
...for some reasons the solution has to have enum...
could you elaborate on this, it seems like an artificial constraint, and the constraint may also affect answers
â jrtapsell
Feb 4 at 21:27
1
1
...for some reasons the solution has to have enum...
could you elaborate on this, it seems like an artificial constraint, and the constraint may also affect answersâ jrtapsell
Feb 4 at 21:27
...for some reasons the solution has to have enum...
could you elaborate on this, it seems like an artificial constraint, and the constraint may also affect answersâ jrtapsell
Feb 4 at 21:27
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
4
down vote
General Implementation
I would lean towards having a Priceable interface, which the extra enums implement, and having the coffee storing a list of extras, which can be passed the size and return the amount to add to the price.
enum Creamer implements Priceable
NONE
@Override
public double getPrice(Size size)
return 0;
, MILK
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.6;
case GRANDE:
return 0.65;
case VENTI:
return 0.70;
case TRENTA:
return 0.75;
default:
throw new AssertionError("Unknown size");
, HALF_N_HALF
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.35;
case GRANDE:
return 0.45;
case VENTI:
return 0.50;
case TRENTA:
return 0.6;
default:
throw new AssertionError("Unknown size");
;
interface Priceable
public double getPrice(Size size);
Use of double for money
I would try to use int instead of double if possible, so that you do not have to deal with floating point issues.
Input validation
At the moment an exception is thrown if the user makes bad input, you probably want to handle this instead.
Using ordinals
Using the values()
array you can avoid having to switch over the enum members to get them by index.
loved your idea to move towards interface. Much cleaner approach. I made few changes to reflect those changes.
â Guest
Feb 4 at 23:31
add a comment |Â
up vote
2
down vote
Thanks for sharing your code.
I like the enum
approach but it could be improved.
My problem with your approach is that you handle the drink size like an ingredient.
On the other hand you separate the "XL" price of the creamer from the creamer itself where it might be a property of the creamer.
So I'd create a common interface for the coffee types and the creamers, so that I can hold them in the same List:
interface Ingredient
/** @return the ingredient price depending on the drinks size +/
double getPrice(Size size);
The creamer enum
implements this interface:
enum Creamer implements Ingredient
NONE("None")
@override
public double getPrice(Size size)
return 0.0; // same value for all
,
MILK("Milk", 0.50, 0.65, 0.70, 0.75),
HALF_N_HALF("Half and Half", 0.25, 0.45, 0.55, 0.60);
private final double prices;
private final String name;
Creamer(String name, double ... prices)
this.name = name;
this.prices = prices;
@override
public double getPrice(Size size)
return prices[size.ordinal()]; // enum Size should have a dedicated getIndex() method to be independent from order in the enum.
public String getName()
return name;
The my coffee type type will also implement this interface since it no problem for the implementer to ignore the size parameter. Also it makes it easy to introduce size depended prices for the coffees too, but this is a side effect, not intended:
enum Coffe implements Ingredient
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unitPrice;
private Coffee(String name, double unitCost)
this.name = name;
this.unitPrice = unitCost;
public String getName()
return name;
@override
public double gePrice(Size size)
return unitPrice;
Having this I can collect coffee and creamer in a Collection<Ingredient>
(rather than in a Map
) and pass this list along with the selected size to the PricingEngine
:
public class PricingEngine
public static double priceBasedOnSize(Collection<Ingredient> ingredients, Size size)
double totalCost = 0.0;
for(Ingredient ingredient : ingredients)
totalCost += ingredient.getPrice(size);
return totalCost;
// alternative with Java8
return ingredients.stram().
.mapToDouble(ingredient.getPrice(size))
.sum();
Benefit:
- no differentiation between coffee and creamer.
- shorter
- supports more ingredient types (e.g. optional "flavors") without change. But again: this is a side effect, not intended.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
General Implementation
I would lean towards having a Priceable interface, which the extra enums implement, and having the coffee storing a list of extras, which can be passed the size and return the amount to add to the price.
enum Creamer implements Priceable
NONE
@Override
public double getPrice(Size size)
return 0;
, MILK
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.6;
case GRANDE:
return 0.65;
case VENTI:
return 0.70;
case TRENTA:
return 0.75;
default:
throw new AssertionError("Unknown size");
, HALF_N_HALF
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.35;
case GRANDE:
return 0.45;
case VENTI:
return 0.50;
case TRENTA:
return 0.6;
default:
throw new AssertionError("Unknown size");
;
interface Priceable
public double getPrice(Size size);
Use of double for money
I would try to use int instead of double if possible, so that you do not have to deal with floating point issues.
Input validation
At the moment an exception is thrown if the user makes bad input, you probably want to handle this instead.
Using ordinals
Using the values()
array you can avoid having to switch over the enum members to get them by index.
loved your idea to move towards interface. Much cleaner approach. I made few changes to reflect those changes.
â Guest
Feb 4 at 23:31
add a comment |Â
up vote
4
down vote
General Implementation
I would lean towards having a Priceable interface, which the extra enums implement, and having the coffee storing a list of extras, which can be passed the size and return the amount to add to the price.
enum Creamer implements Priceable
NONE
@Override
public double getPrice(Size size)
return 0;
, MILK
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.6;
case GRANDE:
return 0.65;
case VENTI:
return 0.70;
case TRENTA:
return 0.75;
default:
throw new AssertionError("Unknown size");
, HALF_N_HALF
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.35;
case GRANDE:
return 0.45;
case VENTI:
return 0.50;
case TRENTA:
return 0.6;
default:
throw new AssertionError("Unknown size");
;
interface Priceable
public double getPrice(Size size);
Use of double for money
I would try to use int instead of double if possible, so that you do not have to deal with floating point issues.
Input validation
At the moment an exception is thrown if the user makes bad input, you probably want to handle this instead.
Using ordinals
Using the values()
array you can avoid having to switch over the enum members to get them by index.
loved your idea to move towards interface. Much cleaner approach. I made few changes to reflect those changes.
â Guest
Feb 4 at 23:31
add a comment |Â
up vote
4
down vote
up vote
4
down vote
General Implementation
I would lean towards having a Priceable interface, which the extra enums implement, and having the coffee storing a list of extras, which can be passed the size and return the amount to add to the price.
enum Creamer implements Priceable
NONE
@Override
public double getPrice(Size size)
return 0;
, MILK
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.6;
case GRANDE:
return 0.65;
case VENTI:
return 0.70;
case TRENTA:
return 0.75;
default:
throw new AssertionError("Unknown size");
, HALF_N_HALF
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.35;
case GRANDE:
return 0.45;
case VENTI:
return 0.50;
case TRENTA:
return 0.6;
default:
throw new AssertionError("Unknown size");
;
interface Priceable
public double getPrice(Size size);
Use of double for money
I would try to use int instead of double if possible, so that you do not have to deal with floating point issues.
Input validation
At the moment an exception is thrown if the user makes bad input, you probably want to handle this instead.
Using ordinals
Using the values()
array you can avoid having to switch over the enum members to get them by index.
General Implementation
I would lean towards having a Priceable interface, which the extra enums implement, and having the coffee storing a list of extras, which can be passed the size and return the amount to add to the price.
enum Creamer implements Priceable
NONE
@Override
public double getPrice(Size size)
return 0;
, MILK
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.6;
case GRANDE:
return 0.65;
case VENTI:
return 0.70;
case TRENTA:
return 0.75;
default:
throw new AssertionError("Unknown size");
, HALF_N_HALF
@Override
public double getPrice(Size size)
switch (size)
case TALL:
return 0.35;
case GRANDE:
return 0.45;
case VENTI:
return 0.50;
case TRENTA:
return 0.6;
default:
throw new AssertionError("Unknown size");
;
interface Priceable
public double getPrice(Size size);
Use of double for money
I would try to use int instead of double if possible, so that you do not have to deal with floating point issues.
Input validation
At the moment an exception is thrown if the user makes bad input, you probably want to handle this instead.
Using ordinals
Using the values()
array you can avoid having to switch over the enum members to get them by index.
answered Feb 4 at 21:46
jrtapsell
435112
435112
loved your idea to move towards interface. Much cleaner approach. I made few changes to reflect those changes.
â Guest
Feb 4 at 23:31
add a comment |Â
loved your idea to move towards interface. Much cleaner approach. I made few changes to reflect those changes.
â Guest
Feb 4 at 23:31
loved your idea to move towards interface. Much cleaner approach. I made few changes to reflect those changes.
â Guest
Feb 4 at 23:31
loved your idea to move towards interface. Much cleaner approach. I made few changes to reflect those changes.
â Guest
Feb 4 at 23:31
add a comment |Â
up vote
2
down vote
Thanks for sharing your code.
I like the enum
approach but it could be improved.
My problem with your approach is that you handle the drink size like an ingredient.
On the other hand you separate the "XL" price of the creamer from the creamer itself where it might be a property of the creamer.
So I'd create a common interface for the coffee types and the creamers, so that I can hold them in the same List:
interface Ingredient
/** @return the ingredient price depending on the drinks size +/
double getPrice(Size size);
The creamer enum
implements this interface:
enum Creamer implements Ingredient
NONE("None")
@override
public double getPrice(Size size)
return 0.0; // same value for all
,
MILK("Milk", 0.50, 0.65, 0.70, 0.75),
HALF_N_HALF("Half and Half", 0.25, 0.45, 0.55, 0.60);
private final double prices;
private final String name;
Creamer(String name, double ... prices)
this.name = name;
this.prices = prices;
@override
public double getPrice(Size size)
return prices[size.ordinal()]; // enum Size should have a dedicated getIndex() method to be independent from order in the enum.
public String getName()
return name;
The my coffee type type will also implement this interface since it no problem for the implementer to ignore the size parameter. Also it makes it easy to introduce size depended prices for the coffees too, but this is a side effect, not intended:
enum Coffe implements Ingredient
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unitPrice;
private Coffee(String name, double unitCost)
this.name = name;
this.unitPrice = unitCost;
public String getName()
return name;
@override
public double gePrice(Size size)
return unitPrice;
Having this I can collect coffee and creamer in a Collection<Ingredient>
(rather than in a Map
) and pass this list along with the selected size to the PricingEngine
:
public class PricingEngine
public static double priceBasedOnSize(Collection<Ingredient> ingredients, Size size)
double totalCost = 0.0;
for(Ingredient ingredient : ingredients)
totalCost += ingredient.getPrice(size);
return totalCost;
// alternative with Java8
return ingredients.stram().
.mapToDouble(ingredient.getPrice(size))
.sum();
Benefit:
- no differentiation between coffee and creamer.
- shorter
- supports more ingredient types (e.g. optional "flavors") without change. But again: this is a side effect, not intended.
add a comment |Â
up vote
2
down vote
Thanks for sharing your code.
I like the enum
approach but it could be improved.
My problem with your approach is that you handle the drink size like an ingredient.
On the other hand you separate the "XL" price of the creamer from the creamer itself where it might be a property of the creamer.
So I'd create a common interface for the coffee types and the creamers, so that I can hold them in the same List:
interface Ingredient
/** @return the ingredient price depending on the drinks size +/
double getPrice(Size size);
The creamer enum
implements this interface:
enum Creamer implements Ingredient
NONE("None")
@override
public double getPrice(Size size)
return 0.0; // same value for all
,
MILK("Milk", 0.50, 0.65, 0.70, 0.75),
HALF_N_HALF("Half and Half", 0.25, 0.45, 0.55, 0.60);
private final double prices;
private final String name;
Creamer(String name, double ... prices)
this.name = name;
this.prices = prices;
@override
public double getPrice(Size size)
return prices[size.ordinal()]; // enum Size should have a dedicated getIndex() method to be independent from order in the enum.
public String getName()
return name;
The my coffee type type will also implement this interface since it no problem for the implementer to ignore the size parameter. Also it makes it easy to introduce size depended prices for the coffees too, but this is a side effect, not intended:
enum Coffe implements Ingredient
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unitPrice;
private Coffee(String name, double unitCost)
this.name = name;
this.unitPrice = unitCost;
public String getName()
return name;
@override
public double gePrice(Size size)
return unitPrice;
Having this I can collect coffee and creamer in a Collection<Ingredient>
(rather than in a Map
) and pass this list along with the selected size to the PricingEngine
:
public class PricingEngine
public static double priceBasedOnSize(Collection<Ingredient> ingredients, Size size)
double totalCost = 0.0;
for(Ingredient ingredient : ingredients)
totalCost += ingredient.getPrice(size);
return totalCost;
// alternative with Java8
return ingredients.stram().
.mapToDouble(ingredient.getPrice(size))
.sum();
Benefit:
- no differentiation between coffee and creamer.
- shorter
- supports more ingredient types (e.g. optional "flavors") without change. But again: this is a side effect, not intended.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Thanks for sharing your code.
I like the enum
approach but it could be improved.
My problem with your approach is that you handle the drink size like an ingredient.
On the other hand you separate the "XL" price of the creamer from the creamer itself where it might be a property of the creamer.
So I'd create a common interface for the coffee types and the creamers, so that I can hold them in the same List:
interface Ingredient
/** @return the ingredient price depending on the drinks size +/
double getPrice(Size size);
The creamer enum
implements this interface:
enum Creamer implements Ingredient
NONE("None")
@override
public double getPrice(Size size)
return 0.0; // same value for all
,
MILK("Milk", 0.50, 0.65, 0.70, 0.75),
HALF_N_HALF("Half and Half", 0.25, 0.45, 0.55, 0.60);
private final double prices;
private final String name;
Creamer(String name, double ... prices)
this.name = name;
this.prices = prices;
@override
public double getPrice(Size size)
return prices[size.ordinal()]; // enum Size should have a dedicated getIndex() method to be independent from order in the enum.
public String getName()
return name;
The my coffee type type will also implement this interface since it no problem for the implementer to ignore the size parameter. Also it makes it easy to introduce size depended prices for the coffees too, but this is a side effect, not intended:
enum Coffe implements Ingredient
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unitPrice;
private Coffee(String name, double unitCost)
this.name = name;
this.unitPrice = unitCost;
public String getName()
return name;
@override
public double gePrice(Size size)
return unitPrice;
Having this I can collect coffee and creamer in a Collection<Ingredient>
(rather than in a Map
) and pass this list along with the selected size to the PricingEngine
:
public class PricingEngine
public static double priceBasedOnSize(Collection<Ingredient> ingredients, Size size)
double totalCost = 0.0;
for(Ingredient ingredient : ingredients)
totalCost += ingredient.getPrice(size);
return totalCost;
// alternative with Java8
return ingredients.stram().
.mapToDouble(ingredient.getPrice(size))
.sum();
Benefit:
- no differentiation between coffee and creamer.
- shorter
- supports more ingredient types (e.g. optional "flavors") without change. But again: this is a side effect, not intended.
Thanks for sharing your code.
I like the enum
approach but it could be improved.
My problem with your approach is that you handle the drink size like an ingredient.
On the other hand you separate the "XL" price of the creamer from the creamer itself where it might be a property of the creamer.
So I'd create a common interface for the coffee types and the creamers, so that I can hold them in the same List:
interface Ingredient
/** @return the ingredient price depending on the drinks size +/
double getPrice(Size size);
The creamer enum
implements this interface:
enum Creamer implements Ingredient
NONE("None")
@override
public double getPrice(Size size)
return 0.0; // same value for all
,
MILK("Milk", 0.50, 0.65, 0.70, 0.75),
HALF_N_HALF("Half and Half", 0.25, 0.45, 0.55, 0.60);
private final double prices;
private final String name;
Creamer(String name, double ... prices)
this.name = name;
this.prices = prices;
@override
public double getPrice(Size size)
return prices[size.ordinal()]; // enum Size should have a dedicated getIndex() method to be independent from order in the enum.
public String getName()
return name;
The my coffee type type will also implement this interface since it no problem for the implementer to ignore the size parameter. Also it makes it easy to introduce size depended prices for the coffees too, but this is a side effect, not intended:
enum Coffe implements Ingredient
CAFFEE_AMERICANO("Coffee", .75),
CAFFEE_LATTE("Caffee Latte" , .50),
CAFFE_MOCHA("Caffee Mocha" , .65),
CAPPUCCINO("Cappuccino" , .85),
COFFEE("Caffee" , .95),
DECAF_COFFEE("Decaf Coffee" , .45);
private final String name;
private final double unitPrice;
private Coffee(String name, double unitCost)
this.name = name;
this.unitPrice = unitCost;
public String getName()
return name;
@override
public double gePrice(Size size)
return unitPrice;
Having this I can collect coffee and creamer in a Collection<Ingredient>
(rather than in a Map
) and pass this list along with the selected size to the PricingEngine
:
public class PricingEngine
public static double priceBasedOnSize(Collection<Ingredient> ingredients, Size size)
double totalCost = 0.0;
for(Ingredient ingredient : ingredients)
totalCost += ingredient.getPrice(size);
return totalCost;
// alternative with Java8
return ingredients.stram().
.mapToDouble(ingredient.getPrice(size))
.sum();
Benefit:
- no differentiation between coffee and creamer.
- shorter
- supports more ingredient types (e.g. optional "flavors") without change. But again: this is a side effect, not intended.
answered Feb 4 at 22:19
Timothy Truckle
4,673316
4,673316
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186756%2fsimple-barista-application-to-calculate-the-price-of-a-drink-based-on-different%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
...for some reasons the solution has to have enum...
could you elaborate on this, it seems like an artificial constraint, and the constraint may also affect answersâ jrtapsell
Feb 4 at 21:27