{"id":"packages-layers","slug":"layers","title":"Packages by responsibility","text":"Module 25 split a program into a user interface and its logic, each in a class of its own. Packages make that split visible in the folders. A common layout has three packages, each with one responsibility, inside a package named after the program:\n\n- `quiz.domain`: the classes of the things the program is about, such as a question. They hold their data and the rules about themselves, such as whether a reply is right.\n- `quiz.logic`: what the program does with them. Here, a class `Quiz` keeps the questions, checks the answers and counts the score. The logic doesn't read input and doesn't print.\n- `quiz.ui`: the user interface. `TextUI` reads what the user types, asks the logic to do the work, and prints the results.\n\n`Main` stays at the top and puts the pieces together:\n\n```java\nimport java.util.Scanner;\nimport quiz.domain.Question;\nimport quiz.logic.Quiz;\nimport quiz.ui.TextUI;\n\npublic class Main {\n    public static void main(String[] args) {\n        Quiz quiz = new Quiz();\n        quiz.add(new Question(\"Which planet is the largest?\", \"Jupiter\", 2));\n        quiz.add(new Question(\"What is the chemical symbol for gold?\", \"Au\", 3));\n        quiz.add(new Question(\"How many legs does a spider have?\", \"8\", 2));\n        TextUI ui = new TextUI(new Scanner(System.in), quiz);\n        ui.start();\n    }\n}\n// ==== quiz/domain/Question.java ====\npackage quiz.domain;\n\npublic class Question {\n    private String prompt;\n    private String answer;\n    private int points;\n\n    public Question(String prompt, String answer, int points) {\n        this.prompt = prompt;\n        this.answer = answer;\n        this.points = points;\n    }\n\n    public boolean isRight(String reply) {\n        return reply.trim().equalsIgnoreCase(this.answer);\n    }\n\n    public int getPoints() {\n        return this.points;\n    }\n\n    @Override\n    public String toString() {\n        return this.prompt + \" (\" + this.points + \" points)\";\n    }\n}\n// ==== quiz/logic/Quiz.java ====\npackage quiz.logic;\n\nimport java.util.ArrayList;\nimport quiz.domain.Question;\n\npublic class Quiz {\n    private ArrayList<Question> questions;\n    private int score;\n\n    public Quiz() {\n        this.questions = new ArrayList<>();\n        this.score = 0;\n    }\n\n    public void add(Question question) {\n        this.questions.add(question);\n    }\n\n    public ArrayList<Question> getQuestions() {\n        return this.questions;\n    }\n\n    public boolean answer(Question question, String reply) {\n        if (question.isRight(reply)) {\n            this.score += question.getPoints();\n            return true;\n        }\n        return false;\n    }\n\n    public int getScore() {\n        return this.score;\n    }\n}\n// ==== quiz/ui/TextUI.java ====\npackage quiz.ui;\n\nimport java.util.Scanner;\nimport quiz.domain.Question;\nimport quiz.logic.Quiz;\n\npublic class TextUI {\n    private Scanner scanner;\n    private Quiz quiz;\n\n    public TextUI(Scanner scanner, Quiz quiz) {\n        this.scanner = scanner;\n        this.quiz = quiz;\n    }\n\n    public void start() {\n        for (Question question : this.quiz.getQuestions()) {\n            System.out.println(question);\n            System.out.print(\"> \");\n            String reply = this.scanner.nextLine();\n            if (this.quiz.answer(question, reply)) {\n                System.out.println(\"Right!\");\n            } else {\n                System.out.println(\"Not quite.\");\n            }\n        }\n        System.out.println(\"Your score: \" + this.quiz.getScore());\n    }\n}\n```\n\n```input\njupiter\nAg\n8\n```\n\n```output\nWhich planet is the largest? (2 points)\n> Right!\nWhat is the chemical symbol for gold? (3 points)\n> Not quite.\nHow many legs does a spider have? (2 points)\n> Right!\nYour score: 4\n```\n\nQuiz never prints: `answer` returns `true` or `false`, and TextUI decides what to show. TextUI never counts points: it asks Quiz. And Question knows nothing of either of them.\n\n### Which may use which\n\nThe three packages use each other in one direction only:\n\n- `ui` uses `logic`, and `domain` too: TextUI shows the questions.\n- `logic` uses `domain`.\n- `domain` uses neither of the others.\n\nThe imports at the top of each file show this at a glance. TextUI imports from `quiz.logic` and `quiz.domain`, Quiz from `quiz.domain`, and Question from nothing of the program. An import of `quiz.ui` in a file of `quiz.logic` or `quiz.domain` would mean that the direction is wrong.\n\nWhy one direction?\n\n- The logic and the domain work with any user interface. The same Quiz could get a graphical one, like the programs with windows later in this course, or be run by tests, without a change to its code.\n- A change in how the program looks touches only `ui`, and a change in its rules touches only `logic` or `domain`.\n- Each package is small enough to read on its own. To see how the score is counted, open `logic`.\n\n### Where does a change go?\n\n| The change | The package, and where in it |\n| --- | --- |\n| A question gets a category, such as Science | `domain`: an instance variable and a getter in Question |\n| A wrong answer costs one point | `logic`: the `answer` method of Quiz |\n| The score is shown after every question | `ui`: the loop in TextUI's `start` |\n","task":"A food truck's program has the package `foodtruck.domain`, with the class `Dish`, ready: a dish has a name and a price in whole dollars, with `getName()`, `getPrice()` and a `toString()` like `Taco (4 dollars)`. In `foodtruck/logic/Order.java`, write the logic class `Order`, in the package `foodtruck.logic`:\n\n- a constructor `Order()`, which makes an empty order\n- `add(Dish dish)`, which adds a dish to the order (the same dish can be ordered several times)\n- `count()`, which returns the number of dishes in the order\n- `total()`, which returns the total price of the order\n- `mostExpensive()`, which returns the most expensive dish of the order (the first one ordered, if several cost the most), or `null` for an empty order\n\nOrder is logic: it returns values and prints nothing. The check runs:\n\n```java\nOrder order = new Order();\norder.add(new Dish(\"Taco\", 4));\norder.add(new Dish(\"Burrito\", 9));\norder.add(new Dish(\"Taco\", 4));\nSystem.out.println(order.count() + \" dishes, \" + order.total() + \" dollars\");\nSystem.out.println(\"Most expensive: \" + order.mostExpensive());\n```\n\nand expects:\n\n```\n3 dishes, 17 dollars\nMost expensive: Burrito (9 dollars)\n```\n","kind":"code","seed":"// ==== foodtruck/logic/Order.java ====\n// Write the package line, the imports and the class Order here.\n\n// ==== foodtruck/domain/Dish.java ====\npackage foodtruck.domain;\n\npublic class Dish {\n    private String name;\n    private int price;\n\n    public Dish(String name, int price) {\n        this.name = name;\n        this.price = price;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getPrice() {\n        return this.price;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \" (\" + this.price + \" dollars)\";\n    }\n}\n\n// ==== Main.java ====\nimport foodtruck.domain.Dish;\nimport foodtruck.logic.Order;\n\npublic class Main {\n    public static void main(String[] args) {\n        Order order = new Order();\n        order.add(new Dish(\"Taco\", 4));\n        order.add(new Dish(\"Burrito\", 9));\n        order.add(new Dish(\"Taco\", 4));\n        System.out.println(order.count() + \" dishes, \" + order.total() + \" dollars\");\n        System.out.println(\"Most expensive: \" + order.mostExpensive());\n    }\n}\n","solution":"// ==== foodtruck/logic/Order.java ====\npackage foodtruck.logic;\n\nimport java.util.ArrayList;\nimport foodtruck.domain.Dish;\n\npublic class Order {\n    private ArrayList<Dish> dishes;\n\n    public Order() {\n        this.dishes = new ArrayList<>();\n    }\n\n    public void add(Dish dish) {\n        this.dishes.add(dish);\n    }\n\n    public int count() {\n        return this.dishes.size();\n    }\n\n    public int total() {\n        int total = 0;\n        for (Dish dish : this.dishes) {\n            total += dish.getPrice();\n        }\n        return total;\n    }\n\n    public Dish mostExpensive() {\n        Dish most = null;\n        for (Dish dish : this.dishes) {\n            if (most == null || dish.getPrice() > most.getPrice()) {\n                most = dish;\n            }\n        }\n        return most;\n    }\n}\n\n// ==== foodtruck/domain/Dish.java ====\npackage foodtruck.domain;\n\npublic class Dish {\n    private String name;\n    private int price;\n\n    public Dish(String name, int price) {\n        this.name = name;\n        this.price = price;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getPrice() {\n        return this.price;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \" (\" + this.price + \" dollars)\";\n    }\n}\n\n// ==== Main.java ====\nimport foodtruck.domain.Dish;\nimport foodtruck.logic.Order;\n\npublic class Main {\n    public static void main(String[] args) {\n        Order order = new Order();\n        order.add(new Dish(\"Taco\", 4));\n        order.add(new Dish(\"Burrito\", 9));\n        order.add(new Dish(\"Taco\", 4));\n        System.out.println(order.count() + \" dishes, \" + order.total() + \" dollars\");\n        System.out.println(\"Most expensive: \" + order.mostExpensive());\n    }\n}\n","hints":["The file starts with `package foodtruck.logic;` and imports `java.util.ArrayList` and `foodtruck.domain.Dish`. The order keeps its dishes in an `ArrayList<Dish>`, made in the constructor.","For `mostExpensive`, start with `Dish most = null;` and go through the dishes: a dish replaces `most` when `most` is still `null` or the dish costs more. Use `>`, not `>=`, so that the first of two equal prices stays."],"tests":[{"name":"Test 1","stdin":"","call":"Order order = new Order();\norder.add(new Dish(\"Taco\", 4));\norder.add(new Dish(\"Burrito\", 9));\norder.add(new Dish(\"Taco\", 4));\nSystem.out.println(order.count() + \" dishes, \" + order.total() + \" dollars\");\nSystem.out.println(\"Most expensive: \" + order.mostExpensive());\n","expect":"3 dishes, 17 dollars\nMost expensive: Burrito (9 dollars)","hidden":false},{"name":"Test 2","stdin":"","call":"Order order = new Order();\nSystem.out.println(order.count() + \" \" + order.total() + \" \" + order.mostExpensive());\norder.add(new Dish(\"Nachos\", 6));\norder.add(new Dish(\"Quesadilla\", 7));\norder.add(new Dish(\"Churros\", 7));\norder.add(new Dish(\"Lemonade\", 3));\nSystem.out.println(order.count() + \" \" + order.total() + \" \" + order.mostExpensive());\n","expect":"0 0 null\n4 23 Quesadilla (7 dollars)","hidden":true}],"require":[],"forbid":[{"pattern":"==== foodtruck/logic/Order\\.java ====(?:(?!// ====)[\\s\\S])*System\\.out","raw":true,"message":"Order is logic: its methods return values and print nothing. The class that uses them decides what to print."}],"more":[{"task":"A cattery's program works, but its logic prints: `checkIn` and `checkOut` in `Cattery` print their own messages. No other user interface could use them, and nothing can ask them whether they worked.\n\nChange the two methods in `Cattery.java` so that they print nothing and return a `boolean`: `checkIn` returns whether the cat got a pen, and `checkOut` whether a cat of that name was there to go home. Then make `TextUI.java` print the messages, which stay exactly as they are. For the input shown, the program prints:\n\n```\n> Mochi checked in\n> Bella checked in\n> No free pen for Max\n> Cats: 2\n> No cat called Max\n> Mochi went home\n> Cats: 1\n> Bye!\n```\n","kind":"code","seed":"// ==== cattery/logic/Cattery.java ====\npackage cattery.logic;\n\nimport java.util.ArrayList;\nimport cattery.domain.Cat;\n\npublic class Cattery {\n    private int pens;\n    private ArrayList<Cat> cats;\n\n    public Cattery(int pens) {\n        this.pens = pens;\n        this.cats = new ArrayList<>();\n    }\n\n    public void checkIn(Cat cat) {\n        if (this.cats.size() >= this.pens) {\n            System.out.println(\"No free pen for \" + cat.getName());\n            return;\n        }\n        this.cats.add(cat);\n        System.out.println(cat.getName() + \" checked in\");\n    }\n\n    public void checkOut(String name) {\n        for (Cat cat : this.cats) {\n            if (cat.getName().equals(name)) {\n                this.cats.remove(cat);\n                System.out.println(name + \" went home\");\n                return;\n            }\n        }\n        System.out.println(\"No cat called \" + name);\n    }\n\n    public int count() {\n        return this.cats.size();\n    }\n}\n\n// ==== cattery/ui/TextUI.java ====\npackage cattery.ui;\n\nimport java.util.Scanner;\nimport cattery.domain.Cat;\nimport cattery.logic.Cattery;\n\npublic class TextUI {\n    private Scanner scanner;\n    private Cattery cattery;\n\n    public TextUI(Scanner scanner, Cattery cattery) {\n        this.scanner = scanner;\n        this.cattery = cattery;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"quit\")) {\n                System.out.println(\"Bye!\");\n                break;\n            }\n            if (command.equals(\"in\")) {\n                String name = this.scanner.nextLine();\n                this.cattery.checkIn(new Cat(name));\n            } else if (command.equals(\"out\")) {\n                String name = this.scanner.nextLine();\n                this.cattery.checkOut(name);\n            } else if (command.equals(\"count\")) {\n                System.out.println(\"Cats: \" + this.cattery.count());\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n}\n\n// ==== cattery/domain/Cat.java ====\npackage cattery.domain;\n\npublic class Cat {\n    private String name;\n\n    public Cat(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\nimport cattery.logic.Cattery;\nimport cattery.ui.TextUI;\n\npublic class Main {\n    public static void main(String[] args) {\n        TextUI ui = new TextUI(new Scanner(System.in), new Cattery(2));\n        ui.start();\n    }\n}\n","solution":"// ==== cattery/logic/Cattery.java ====\npackage cattery.logic;\n\nimport java.util.ArrayList;\nimport cattery.domain.Cat;\n\npublic class Cattery {\n    private int pens;\n    private ArrayList<Cat> cats;\n\n    public Cattery(int pens) {\n        this.pens = pens;\n        this.cats = new ArrayList<>();\n    }\n\n    public boolean checkIn(Cat cat) {\n        if (this.cats.size() >= this.pens) {\n            return false;\n        }\n        this.cats.add(cat);\n        return true;\n    }\n\n    public boolean checkOut(String name) {\n        for (Cat cat : this.cats) {\n            if (cat.getName().equals(name)) {\n                this.cats.remove(cat);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public int count() {\n        return this.cats.size();\n    }\n}\n\n// ==== cattery/ui/TextUI.java ====\npackage cattery.ui;\n\nimport java.util.Scanner;\nimport cattery.domain.Cat;\nimport cattery.logic.Cattery;\n\npublic class TextUI {\n    private Scanner scanner;\n    private Cattery cattery;\n\n    public TextUI(Scanner scanner, Cattery cattery) {\n        this.scanner = scanner;\n        this.cattery = cattery;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"quit\")) {\n                System.out.println(\"Bye!\");\n                break;\n            }\n            if (command.equals(\"in\")) {\n                String name = this.scanner.nextLine();\n                if (this.cattery.checkIn(new Cat(name))) {\n                    System.out.println(name + \" checked in\");\n                } else {\n                    System.out.println(\"No free pen for \" + name);\n                }\n            } else if (command.equals(\"out\")) {\n                String name = this.scanner.nextLine();\n                if (this.cattery.checkOut(name)) {\n                    System.out.println(name + \" went home\");\n                } else {\n                    System.out.println(\"No cat called \" + name);\n                }\n            } else if (command.equals(\"count\")) {\n                System.out.println(\"Cats: \" + this.cattery.count());\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n}\n\n// ==== cattery/domain/Cat.java ====\npackage cattery.domain;\n\npublic class Cat {\n    private String name;\n\n    public Cat(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\nimport cattery.logic.Cattery;\nimport cattery.ui.TextUI;\n\npublic class Main {\n    public static void main(String[] args) {\n        TextUI ui = new TextUI(new Scanner(System.in), new Cattery(2));\n        ui.start();\n    }\n}\n","hints":["In Cattery, the headers become `public boolean checkIn(Cat cat)` and `public boolean checkOut(String name)`. Each `System.out.println` turns into `return true;` or `return false;`: the cat got a pen or didn't, the cat was found or wasn't.","In TextUI, use what the method returns: `if (this.cattery.checkIn(new Cat(name))) {` prints `name + \" checked in\"`, and its `else` prints the message about the full cattery. `out` works the same way."],"tests":[{"name":"Test 1","stdin":"in\nMochi\nin\nBella\nin\nMax\ncount\nout\nMax\nout\nMochi\ncount\nquit\n","expect":"> Mochi checked in\n> Bella checked in\n> No free pen for Max\n> Cats: 2\n> No cat called Max\n> Mochi went home\n> Cats: 1\n> Bye!","hidden":false},{"name":"Test 2","stdin":"out\nMochi\nin\nLuna\ncattery\nout\nluna\nout\nLuna\nin\nOtto\nin\nPip\nin\nNala\ncount\nquit\n","expect":"> No cat called Mochi\n> Luna checked in\n> Unknown command: cattery\n> No cat called luna\n> Luna went home\n> Otto checked in\n> Pip checked in\n> No free pen for Nala\n> Cats: 2\n> Bye!","hidden":true},{"name":"Test 3","stdin":"","call":"Cattery cattery = new Cattery(1);\nSystem.out.println(cattery.checkIn(new Cat(\"Mochi\")));\nSystem.out.println(cattery.checkIn(new Cat(\"Bo\")));\nSystem.out.println(cattery.checkOut(\"Bo\") + \" \" + cattery.checkOut(\"Mochi\") + \" \" + cattery.count());\n","expect":"true\nfalse\nfalse true 0","hidden":true}],"require":[],"forbid":[{"pattern":"==== cattery/logic/Cattery\\.java ====(?:(?!// ====)[\\s\\S])*System\\.out","raw":true,"message":"Cattery is logic: it returns `true` or `false`, and TextUI prints the messages."}]},{"task":"The food truck gets its user interface. `Dish.java` and `Order.java` are the ones from the first task, and `Menu.java`, in `foodtruck.logic`, is ready: `add(Dish dish)` puts a dish on the menu, and `find(String name)` returns the dish of that name, with capital letters or not, or `null` if the menu has none. `Main.java` is ready too.\n\nIn `foodtruck/ui/TextUI.java`, write the class `TextUI`, in the package `foodtruck.ui`, with the imports it needs. Its constructor takes a `Scanner`, a `Menu` and an `Order`, and its method `start()` reads commands, with the prompt `> ` before each one:\n\n- `order`: the next line is the name of a dish. If the menu has it, add it to the order and print `Added ` and the dish, like `Added Taco (4 dollars)`. Otherwise print `Not on the menu: ` and the name.\n- `total`: print the number of dishes and the total, like `3 dishes, 17 dollars`.\n- `done`: print `Thank you! You pay ` and the total and ` dollars`, and return.\n- Anything else: print `Unknown command: ` and the command.\n\nFor the input shown, the program prints:\n\n```\n> Added Taco (4 dollars)\n> Added Burrito (9 dollars)\n> Not on the menu: Pizza\n> Added Taco (4 dollars)\n> 3 dishes, 17 dollars\n> Thank you! You pay 17 dollars\n```\n","kind":"code","seed":"// ==== foodtruck/ui/TextUI.java ====\npackage foodtruck.ui;\n\n// Write the imports and the class TextUI here.\n\n// ==== foodtruck/logic/Menu.java ====\npackage foodtruck.logic;\n\nimport java.util.ArrayList;\nimport foodtruck.domain.Dish;\n\npublic class Menu {\n    private ArrayList<Dish> dishes;\n\n    public Menu() {\n        this.dishes = new ArrayList<>();\n    }\n\n    public void add(Dish dish) {\n        this.dishes.add(dish);\n    }\n\n    public Dish find(String name) {\n        for (Dish dish : this.dishes) {\n            if (dish.getName().equalsIgnoreCase(name)) {\n                return dish;\n            }\n        }\n        return null;\n    }\n}\n\n// ==== foodtruck/logic/Order.java ====\npackage foodtruck.logic;\n\nimport java.util.ArrayList;\nimport foodtruck.domain.Dish;\n\npublic class Order {\n    private ArrayList<Dish> dishes;\n\n    public Order() {\n        this.dishes = new ArrayList<>();\n    }\n\n    public void add(Dish dish) {\n        this.dishes.add(dish);\n    }\n\n    public int count() {\n        return this.dishes.size();\n    }\n\n    public int total() {\n        int total = 0;\n        for (Dish dish : this.dishes) {\n            total += dish.getPrice();\n        }\n        return total;\n    }\n\n    public Dish mostExpensive() {\n        Dish most = null;\n        for (Dish dish : this.dishes) {\n            if (most == null || dish.getPrice() > most.getPrice()) {\n                most = dish;\n            }\n        }\n        return most;\n    }\n}\n\n// ==== foodtruck/domain/Dish.java ====\npackage foodtruck.domain;\n\npublic class Dish {\n    private String name;\n    private int price;\n\n    public Dish(String name, int price) {\n        this.name = name;\n        this.price = price;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getPrice() {\n        return this.price;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \" (\" + this.price + \" dollars)\";\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\nimport foodtruck.domain.Dish;\nimport foodtruck.logic.Menu;\nimport foodtruck.logic.Order;\nimport foodtruck.ui.TextUI;\n\npublic class Main {\n    public static void main(String[] args) {\n        Menu menu = new Menu();\n        menu.add(new Dish(\"Taco\", 4));\n        menu.add(new Dish(\"Burrito\", 9));\n        menu.add(new Dish(\"Nachos\", 6));\n        TextUI ui = new TextUI(new Scanner(System.in), menu, new Order());\n        ui.start();\n    }\n}\n","solution":"// ==== foodtruck/ui/TextUI.java ====\npackage foodtruck.ui;\n\nimport java.util.Scanner;\nimport foodtruck.domain.Dish;\nimport foodtruck.logic.Menu;\nimport foodtruck.logic.Order;\n\npublic class TextUI {\n    private Scanner scanner;\n    private Menu menu;\n    private Order order;\n\n    public TextUI(Scanner scanner, Menu menu, Order order) {\n        this.scanner = scanner;\n        this.menu = menu;\n        this.order = order;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"done\")) {\n                System.out.println(\"Thank you! You pay \" + this.order.total() + \" dollars\");\n                break;\n            }\n            if (command.equals(\"order\")) {\n                String name = this.scanner.nextLine();\n                Dish dish = this.menu.find(name);\n                if (dish == null) {\n                    System.out.println(\"Not on the menu: \" + name);\n                } else {\n                    this.order.add(dish);\n                    System.out.println(\"Added \" + dish);\n                }\n            } else if (command.equals(\"total\")) {\n                System.out.println(this.order.count() + \" dishes, \" + this.order.total() + \" dollars\");\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n}\n\n// ==== foodtruck/logic/Menu.java ====\npackage foodtruck.logic;\n\nimport java.util.ArrayList;\nimport foodtruck.domain.Dish;\n\npublic class Menu {\n    private ArrayList<Dish> dishes;\n\n    public Menu() {\n        this.dishes = new ArrayList<>();\n    }\n\n    public void add(Dish dish) {\n        this.dishes.add(dish);\n    }\n\n    public Dish find(String name) {\n        for (Dish dish : this.dishes) {\n            if (dish.getName().equalsIgnoreCase(name)) {\n                return dish;\n            }\n        }\n        return null;\n    }\n}\n\n// ==== foodtruck/logic/Order.java ====\npackage foodtruck.logic;\n\nimport java.util.ArrayList;\nimport foodtruck.domain.Dish;\n\npublic class Order {\n    private ArrayList<Dish> dishes;\n\n    public Order() {\n        this.dishes = new ArrayList<>();\n    }\n\n    public void add(Dish dish) {\n        this.dishes.add(dish);\n    }\n\n    public int count() {\n        return this.dishes.size();\n    }\n\n    public int total() {\n        int total = 0;\n        for (Dish dish : this.dishes) {\n            total += dish.getPrice();\n        }\n        return total;\n    }\n\n    public Dish mostExpensive() {\n        Dish most = null;\n        for (Dish dish : this.dishes) {\n            if (most == null || dish.getPrice() > most.getPrice()) {\n                most = dish;\n            }\n        }\n        return most;\n    }\n}\n\n// ==== foodtruck/domain/Dish.java ====\npackage foodtruck.domain;\n\npublic class Dish {\n    private String name;\n    private int price;\n\n    public Dish(String name, int price) {\n        this.name = name;\n        this.price = price;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getPrice() {\n        return this.price;\n    }\n\n    @Override\n    public String toString() {\n        return this.name + \" (\" + this.price + \" dollars)\";\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\nimport foodtruck.domain.Dish;\nimport foodtruck.logic.Menu;\nimport foodtruck.logic.Order;\nimport foodtruck.ui.TextUI;\n\npublic class Main {\n    public static void main(String[] args) {\n        Menu menu = new Menu();\n        menu.add(new Dish(\"Taco\", 4));\n        menu.add(new Dish(\"Burrito\", 9));\n        menu.add(new Dish(\"Nachos\", 6));\n        TextUI ui = new TextUI(new Scanner(System.in), menu, new Order());\n        ui.start();\n    }\n}\n","hints":["TextUI uses four classes from other packages: `java.util.Scanner`, `foodtruck.domain.Dish`, `foodtruck.logic.Menu` and `foodtruck.logic.Order`. Import each, then keep the three constructor parameters in instance variables.","For `order`, ask the menu first: `Dish dish = this.menu.find(name);`. If `dish` is `null`, print the message about the menu; otherwise add it with `this.order.add(dish)` and print `\"Added \" + dish`."],"tests":[{"name":"Test 1","stdin":"order\nTaco\norder\nburrito\norder\nPizza\norder\nTACO\ntotal\ndone\n","expect":"> Added Taco (4 dollars)\n> Added Burrito (9 dollars)\n> Not on the menu: Pizza\n> Added Taco (4 dollars)\n> 3 dishes, 17 dollars\n> Thank you! You pay 17 dollars","hidden":false},{"name":"Test 2","stdin":"total\nmenu\norder\nnachos\norder\nSalad\norder\nTaco\ntotal\ndone\n","expect":"> 0 dishes, 0 dollars\n> Unknown command: menu\n> Added Nachos (6 dollars)\n> Not on the menu: Salad\n> Added Taco (4 dollars)\n> 2 dishes, 10 dollars\n> Thank you! You pay 10 dollars","hidden":true},{"name":"Test 3","stdin":"","call":"Menu menu = new Menu();\nmenu.add(new Dish(\"Soup\", 5));\nOrder order = new Order();\nTextUI ui = new TextUI(new Scanner(\"order\\nsoup\\norder\\nSoup\\ndone\\n\"), menu, order);\nui.start();\nSystem.out.println(order.count());\n","expect":"> Added Soup (5 dollars)\n> Added Soup (5 dollars)\n> Thank you! You pay 10 dollars\n2","hidden":true}],"require":[],"forbid":[]}]}