/* In computer science, "spaghetti code" refers to code that has little or no structure, typically involving convoluted, nested loops and if-else statments, atypical control behavior, and no clearly defined scope (imagine a large program all inside main). Spaghetti code is hard to find invariants for. Such code is hard to understand, hard to debug, and hard to transport to a different environment without wrecking havoc. It is also difficult to augment spaghetti code with additional functionality. Many of years of research has been devoted to reduce the reliance on such unstructured code, including the design of new programming languages and paradigms. But just because we're using a modern "oop" language, doesn't mean that we can automatically avoid this form of programming. Imagine that we are in the food business and we have to write a program that describes several different types of food. Suppose our "food factory" makes pizzas and sandwiches. There are many different kinds of pizzas and sandwiches. Each differ from the other in various ways including the number of calories and the price we charge. Sandwiches will have the option of including mayonnaise or not. Hopefully nobody will put mayonnaise on pizza. Let us first limit ourselfs to four different kinds of food: plain pizza, pepperoni pizza, ham and cheese sandwich, and blt sandwich. */ import java.util.ArrayList; // built-in data structure: class food // class representing a food item { public String name; // name of food item public int cals; // number of calories of food item public boolean mayo = false; // determine if mayonnaise will be included ArrayList Ingredients; // constructor assigns name and computes calories public food(String n) { name = n; Ingredients = new ArrayList(); if (name.equals("cheesepizza")) { Ingredients.add("dough"); Ingredients.add("tomato sauce"); Ingredients.add("cheese"); cals = 1000; } else if (name.equals("pepperonipizza")) { Ingredients.add("dough"); Ingredients.add("tomato sauce"); Ingredients.add("cheese"); Ingredients.add("pepperoni"); cals = 1400; } else if (name.equals("hamandcheese")) { Ingredients.add("bread"); Ingredients.add("ham"); Ingredients.add("cheese"); cals = 600; } else if (name.equals("blt")) { Ingredients.add("bread"); Ingredients.add("bacon"); Ingredients.add("lettuce"); Ingredients.add("tomato"); cals = 800; } } // constructor public String type() // returns pizza or sandwich by looking at name { int n = name.length(); if (n>4 && name.substring(n-5,n).equals("pizza")) return "pizza"; else return "sandwich"; } /* algorithm for computing price */ public double price() { if (type().equals("sandwich")) return 2.0*Ingredients.size(); if (name.equals("cheesepizza")) return 10.00; if (name.equals("pepperonipizza")) return 13.00; return 0; // need to always return something } }// food public class spaghetticode { public static void main(String[] args) { ArrayList myorder = new ArrayList(); myorder.add(new food("blt")); myorder.add(new food("pepperonipizza")); myorder.add(new food("hamandcheese")); double totalprice = 0; for (food item:myorder) totalprice += item.price(); System.out.printf("my order costs %.2f\n",totalprice); // But now: myorder.add(new food("chesspizza")); // oops, is that edible? food mylunch = new food("hamandcheese"); food yourlunch = new food("pepperonipizza"); mylunch.mayo = true; // yummy yourlunch.mayo = true; // disgusting! that shouldn't be allowed! }//main } /* what if I only wanted to have the sandwich food items to have a "mayo" option - a true/false boolean variable. what if I misspell a food item what if I wanted a order with only sandwiches and no pizzas? what if I wanted to add a new type of pizza or sandwich, or something else to eat altogether, like soup? */ /* What should you avoid if-elses? Are the following segments of code equivalent? int x = ((int)(Math.random()*11)-5; // random number between -5 and + 5 if (x<0) System.out.println("x is negative"); // segment 1 else if (x>0) System.out.println("x is positive"); else System.out.println("x is zero"); if (x==0) System.out.println("x is zero"); // segment 2 if (x>0) System.out.println("x is positive"); else System.out.println("x is negative"); */