import [Link].
ArrayList;
// ==========================================
// 1. THE ABSTRACT CREATOR (The Framework)
// ==========================================
abstract class PizzaStore {
// The order system is consistent across all franchises
public Pizza orderPizza(String type) {
Pizza pizza;
// The factory method is called to create the concrete product
pizza = createPizza(type);
// These activities are localized in the PizzaStore class
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
// The abstract factory method that subclasses MUST implement
protected abstract Pizza createPizza(String type);
// ==========================================
// 2. THE ABSTRACT PRODUCT
// ==========================================
abstract class Pizza {
String name;
String dough;
String sauce;
ArrayList<String> toppings = new ArrayList<>();
void prepare() {
[Link]("Preparing " + name);
[Link]("Tossing dough...");
[Link]("Adding sauce...");
[Link]("Adding toppings: ");
for (String topping : toppings) {
[Link](" " + topping);
void bake() {
[Link]("Bake for 25 minutes at 350");
void cut() {
[Link]("Cutting the pizza into diagonal slices");
void box() {
[Link]("Place pizza in official PizzaStore box");
public String getName() {
return name;
}
// ==========================================
// 3. CONCRETE CREATORS (Regional Stores)
// ==========================================
// New York Store
class NYPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String item) {
if ([Link]("cheese")) {
return new NYStyleCheesePizza();
} else {
return null;
// Chicago Store
class ChicagoPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String item) {
if ([Link]("cheese")) {
return new ChicagoStyleCheesePizza();
} else {
return null;
}
}
// ==========================================
// 4. CONCRETE PRODUCTS (Regional Pizzas)
// ==========================================
class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza() {
name = "NY Style Sauce and Cheese Pizza";
dough = "Thin Crust Dough";
sauce = "Marinara Sauce";
[Link]("Grated Reggiano Cheese");
class ChicagoStyleCheesePizza extends Pizza {
public ChicagoStyleCheesePizza() {
name = "Chicago Style Deep Dish Cheese Pizza";
dough = "Extra Thick Crust Dough";
sauce = "Plum Tomato Sauce";
[Link]("Shredded Mozzarella Cheese");
@Override
void cut() {
[Link]("Cutting the pizza into square slices");
// ==========================================
// 5. TEST DRIVE
// ==========================================
public class PizzaTestDrive {
public static void main(String[] args) {
// Create the concrete stores
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
// Ethan orders from NY
Pizza pizza = [Link]("cheese");
[Link]("Ethan ordered a " + [Link]() + "\n");
// Joel orders from Chicago
pizza = [Link]("cheese");
[Link]("Joel ordered a " + [Link]() + "\n");
// ================================
// ABSTRACT FACTORY + toString DEMO
// ================================
// --------- Ingredient Interfaces ----------
interface Dough {
String toString();
}
interface Sauce {
String toString();
}
interface Cheese {
String toString();
}
// --------- Concrete Ingredients ----------
class ThinCrustDough implements Dough {
public String toString() {
return "Thin Crust Dough";
}
}
class MarinaraSauce implements Sauce {
public String toString() {
return "Marinara Sauce";
}
}
class ReggianoCheese implements Cheese {
public String toString() {
return "Reggiano Cheese";
}
}
// --------- Abstract Factory ----------
interface PizzaIngredientFactory {
Dough createDough();
Sauce createSauce();
Cheese createCheese();
}
// --------- Concrete Factory ----------
class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public Dough createDough() {
return new ThinCrustDough();
}
public Sauce createSauce() {
return new MarinaraSauce();
}
public Cheese createCheese() {
return new ReggianoCheese();
}
}
// --------- Abstract Pizza ----------
abstract class Pizza {
String name;
Dough dough;
Sauce sauce;
Cheese cheese;
abstract void prepare();
void bake() {
[Link]("Bake for 25 minutes at 350");
}
void cut() {
[Link]("Cutting the pizza into diagonal slices");
}
void box() {
[Link]("Place pizza in official box");
}
void printIngredients() {
// toString() called automatically here
[Link]("Dough: " + dough);
[Link]("Sauce: " + sauce);
[Link]("Cheese: " + cheese);
}
void setName(String name) {
[Link] = name;
}
String getName() {
return name;
}
}
// --------- Cheese Pizza ----------
class CheesePizza extends Pizza {
PizzaIngredientFactory ingredientFactory;
CheesePizza(PizzaIngredientFactory ingredientFactory) {
[Link] = ingredientFactory;
}
void prepare() {
[Link]("Preparing " + name);
dough = [Link]();
sauce = [Link]();
cheese = [Link]();
}
}
// --------- Pizza Store (Factory Method) ----------
abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
[Link]();
[Link]();
[Link]();
[Link]();
return pizza;
}
protected abstract Pizza createPizza(String type);
}
// --------- NY Pizza Store ----------
class NYPizzaStore extends PizzaStore {
protected Pizza createPizza(String type) {
PizzaIngredientFactory factory = new NYPizzaIngredientFactory();
Pizza pizza = null;
if ([Link]("cheese")) {
pizza = new CheesePizza(factory);
[Link]("New York Style Cheese Pizza");
}
return pizza;
}
}
// --------- MAIN / CLIENT ----------
public class PizzaTestDrive {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
Pizza pizza = [Link]("cheese");
[Link]("\nOrdered a " + [Link]());
// 👇 toString() CALLED FROM MAIN
[Link]("\nIngredients used:");
[Link]();
}
}