I was recently rejected from what looked like a really promising string of interviews. I did very well in a questionnaire style review, and then they handed me this assignment (more or less):Design a coffee machine which makes different beverages based on set ingredients. The initialization of the recipes for each drink should be hard-coded, although it should be relatively easy to add new drinks. The machine should display the ingredient stock (+cost) and menu upon startup, and after every piece of valid user input. Drink cost is determined by the combination of ingredients. For example, Coffee is 3 units of coffee (75 cents per), 1 unit of sugar (25 cents per), 1 unit of cream (25 cents per). Ingredients and Menu items should be printed in alphabetical order. If the drink is out of stock, it should print accordingly. If the drink is in stock, it should print Dispensing: . To select a drink, the user should input a relevant number. If they submit r or R the ingredients should restock, and q or Q should quit. Blank lines should be ignored, and invalid input should print an invalid input message.They supplied the default ingredients (&stock @10) and drinks/recipes.They told me to not try and impress, don't overly document (specifically commenting is not required). The code should be scaleable, readable, and just not overly complicated.Anyway, it's more likely that I made some major error in data structure choice or handling drink selections, than me missing some detail. Still, I can privately send the full assignment description if anyone is curious...I just don't want to put it out there since it's a big company currently hiring. I changed the name of some stuff in my code to make the exact assignment less searchable. I actually have a lot of opinions on things I would change in this code, but I have a hard time believing that they are things that would get me rejected. It must be something bigger...(I have since been informed that the team was hoping for A more OO design...felt like I took it in that direction, personally.)DrinkMachineimport java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Collections;import java.util.List;import java.util.ArrayList;import java.util.Map;public class DrinkMachine{    private static List<Drink> drinkList = new ArrayList<Drink>();    private static List<Ingredient> ingredientList = new ArrayList<Ingredient>();    public static void main(String[] args) {        addAllIngredients();        addAllDrinks();        updateCosts();        updateMakeable();        display();        startIO();    }    public static void startIO(){        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));        String input = ;        //running loop        while(true){                        try {                /*I considered using a switch here for more readable code. Elected to have a dynamic drink menu so drinks can be added                 * to addAllDrinks() and this loop would not have to be change. The decision to have slightly less readable code                 * in favor of a dynamic menu was made upon my belief that easily modifiable code is incredibly important.                 */                input = reader.readLine().toLowerCase();                if(input.equals()){                    continue;                }else if (input.equals(q)){                     System.exit(0);                 }else if(input.equals(r)){                     restockIngredients();                    updateMakeable();                }else if(Integer.parseInt(input) > 0 && Integer.parseInt(input) <= drinkList.size()){ //dynamic drink menu selection                    makeDrink(drinkList.get(Integer.parseInt(input)-1));                }else{                    throw new IOException();//legal, but invalid input                }            } catch (Exception e) {                System.out.println(Invalid selection:  + input + \n);//illegal input            }        }//running loop         }    public static void display(){        //The sample IO in the assignment appears to add a blank line after output, so I included that.        System.out.println(Inventory:\n);        for (Ingredient i : ingredientList){            System.out.println(i.getName() + , + i.getStock() + \n);        }        System.out.println(Menu:\n);        int count = 1;        for (Drink d : drinkList){            System.out.printf(%d,%s,$%.2f, + d.getMakeable() + \n\n, count, d.getName(), d.getCost());            count++;        }    }    public static void updateMakeable(){        for (Drink d : drinkList){            Map<String, Integer> currRecipe = d.getRecipe();            for (Ingredient i : ingredientList){                if (currRecipe.containsKey(i.getName()) && i.getStock() < currRecipe.get(i.getName())){                    d.setMakeable(false);                    break;//check next drink                }                d.setMakeable(true);            }//Ingredient loop        }//Drink loop    }    public static void updateCosts(){        for (Drink d : drinkList){            double currCost = 0;            Map<String, Integer> currRecipe = d.getRecipe();            for (Ingredient i : ingredientList){                if (currRecipe.containsKey(i.getName())){                    currCost += i.getCost()*currRecipe.get(i.getName());                }            }//inner            d.setCost(currCost);        }//outer    }    public static void makeDrink(Drink drink){        if(drink.getMakeable()){            System.out.println(Dispensing:  + drink.getName() + \n);            for (Ingredient i : ingredientList){                if(drink.getRecipe().containsKey(i.getName())){                    i.setStock(i.getStock()-drink.getRecipe().get(i.getName()));                }            }        }else{            System.out.println(Out of stock:  + drink.getName() + \n);        }        updateMakeable();        display();    }    public static void restockIngredients(){        for(Ingredient i : ingredientList){            i.setStock(10);        }        updateMakeable();        display();    }    //Add ingredients through addAllIngredients    public static void addIngredient(Ingredient ingredient){        ingredientList.add(ingredient);    }    //Add drinks through addAllDrinks    public static void addDrink(String name, String[] recipe){        drinkList.add(new Drink(name, recipe));    }    public static void addAllIngredients(){        addIngredient(new Ingredient(Coffee, 0.75));        addIngredient(new Ingredient(Decaf Coffee, 0.75));        addIngredient(new Ingredient(Sugar, 0.25));        addIngredient(new Ingredient(Cream, 0.25));        addIngredient(new Ingredient(Steamed Milk, 0.35));        addIngredient(new Ingredient(Foamed Milk, 0.35));        addIngredient(new Ingredient(Espresso, 1.10));        addIngredient(new Ingredient(Cocoa, 0.90));        addIngredient(new Ingredient(Whipped Cream, 1.00));           Collections.sort(ingredientList);    }    public static void addAllDrinks(){          addDrink(Coffee, new String[]{Coffee, Coffee, Coffee, Sugar, Cream});        addDrink(Decaf Coffee, new String[]{Decaf Coffee, Decaf Coffee, Decaf Coffee, Sugar, Cream});        addDrink(Caffe Latte, new String[]{Espresso, Espresso, Steamed Milk});        addDrink(Caffe Americano, new String[]{Espresso, Espresso, Espresso});        addDrink(Caffe Mocha, new String[]{Espresso, Cocoa, Steamed Milk, Whipped Cream});        addDrink(Cappuccino, new String[]{Espresso, Espresso, Steamed Milk, Foamed Milk});        Collections.sort(drinkList);    }}Drinkimport java.util.HashMap;import java.util.Map;public class Drink implements Comparable<Drink>{    private Map<String, Integer> recipe = new HashMap<String, Integer>();//map ingredients to units per    private String name;    private double totalCost = 0;    private boolean makeable = false;    public Drink(String name, String[] recipe){        this.name = name;        setRecipe(recipe);    }    public int compareTo(Drink drink){        return name.compareTo(drink.getName());    }    public void setRecipe(String[] recipe){        for(String s : recipe){            if(this.recipe.containsKey(s)){                this.recipe.put(s, this.recipe.get(s)+1);//increment if multiple units            }else{                this.recipe.put(s, 1);//insert first occurrence of ingredient            }        }    }    public void setName(String name){        this.name = name;    }    public void setCost(double totalCost){        this.totalCost = totalCost;    }    public void setMakeable(boolean makeable){        this.makeable = makeable;    }    public Map<String, Integer> getRecipe(){        return recipe;    }    public double getCost(){        return totalCost;    }    public String getName(){        return name;    }    public boolean getMakeable(){        return makeable;    }}Ingredient    public class Ingredient implements Comparable<Ingredient>{        private String name = ;        private double cost = 0.00;        private int stock = 0;        public Ingredient(String name, double cost){            this.name = name;            this.cost = cost;            this.stock = 10;        }        public int compareTo(Ingredient ingredient) {            return name.compareTo(ingredient.getName());        }        public void setName(String name){            this.name = name;        }        public void setCost(double cost){            this.cost = cost;        }        public void setStock(int stock){            this.stock = stock;        }        public String getName(){            return name;        }        public double getCost(){            return cost;        }        public int getStock(){            return stock;        }    }
Designing a coffee machine
java;object oriented;interview questions;simulation
I have since been informed that the team was hoping for A more OO design...felt like I took it in that direction, personally.All the methods in your DrinkMachine class are static. I believe the ability to have more than one DrinkMachine is a very important feature. DrinkMachines should be able to have different inventories, different products, etc. Now, you might think But I was told to keep it simple!. This is not about trying to impress or anything, this is about reasonable functionality.I am afraid that this staticness of the DrinkMachine cost you a lot of interview-points.Do you really need to be able to change the name of an Ingredient after it has been created?I think you should strive on making some of your fields final. This also helps with tim's point about you don't need to initialize fields if you assign them in a constructor, that's just confusing. - final fields can only be initialized once.