diff --git a/Ch4PizzaStore/Ch4PizzaStore.csproj b/Ch4PizzaStore/Ch4PizzaStore.csproj
new file mode 100644
index 0000000..46e6c92
--- /dev/null
+++ b/Ch4PizzaStore/Ch4PizzaStore.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net9.0
+ latestmajor
+ enable
+ enable
+
+
+
diff --git a/Ch4PizzaStore/Pizza.cs b/Ch4PizzaStore/Pizza.cs
new file mode 100644
index 0000000..31fb159
--- /dev/null
+++ b/Ch4PizzaStore/Pizza.cs
@@ -0,0 +1,70 @@
+namespace Ch4PizzaStore;
+
+public abstract class Pizza(string name, string dough, string sauce, List toppings) {
+ public string Name { get; } = name;
+
+ internal void Prepare() {
+ Console.WriteLine($"Preparing {Name}");
+ Console.WriteLine($"Tossing {dough} dough...");
+ Console.WriteLine($"Adding {sauce} sauce...");
+ Console.WriteLine("Adding toppings:");
+ foreach (var topping in toppings) {
+ Console.WriteLine($"\t{topping}");
+ }
+ }
+
+ // While in Java all methods are by default `virtual`, C# is the same as C++,
+ // all methods are final/selaed until explicitly marked as virtual.
+ internal virtual void Bake() {
+ Console.WriteLine("Bake for 25 minutes at 350");
+ }
+
+ internal virtual void Cut() {
+ Console.WriteLine("Cutting the pizza into diagonal slices");
+ }
+
+ internal virtual void Box() {
+ Console.WriteLine("Place pizza in official PizzaStore box");
+ }
+}
+
+public class NYStyleCheesePizza() : Pizza("NY Style Sauce and Cheese Pizza", "Thin Crust Dough", "Marinara Sauce",
+ ["Grated Reggiano Cheese"]);
+
+public class ChicagoStyleCheesePizza() : Pizza("Chicago Style Deep Dish Cheese Pizza", "Extra Thick Crust Dough",
+ "Plum Tomato Sauce", ["Shredded Mozzarella Cheese"]) {
+ internal override void Cut() {
+ Console.WriteLine("Cutting the pizza into square slices");
+ }
+}
+
+public abstract class PizzaStore {
+ protected abstract Pizza CreatePizza(string type);
+
+ public Pizza OrderPizza(string type) {
+ var pizza = CreatePizza(type);
+ pizza.Prepare();
+ pizza.Bake();
+ pizza.Cut();
+ pizza.Box();
+ return pizza;
+ }
+}
+
+public class NYPizzaStore : PizzaStore {
+ protected override Pizza CreatePizza(string type) {
+ return type switch {
+ "cheese" => new NYStyleCheesePizza(),
+ _ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
+ };
+ }
+}
+
+public class ChicagoPizzaStore : PizzaStore {
+ protected override Pizza CreatePizza(string type) {
+ return type switch {
+ "cheese" => new ChicagoStyleCheesePizza(),
+ _ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
+ };
+ }
+}
\ No newline at end of file
diff --git a/Ch4PizzaStore/Program.cs b/Ch4PizzaStore/Program.cs
new file mode 100644
index 0000000..5ff470a
--- /dev/null
+++ b/Ch4PizzaStore/Program.cs
@@ -0,0 +1,11 @@
+// See https://aka.ms/new-console-template for more information
+
+using Ch4PizzaStore;
+
+PizzaStore nyStore = new NYPizzaStore();
+PizzaStore chicagoStore = new ChicagoPizzaStore();
+
+var pizza = nyStore.OrderPizza("cheese");
+Console.WriteLine($"Ethan ordered a {pizza.Name}\n");
+pizza = chicagoStore.OrderPizza("cheese");
+Console.WriteLine($"Joel ordered a {pizza.Name}\n");
\ No newline at end of file
diff --git a/HeadFirstDesignPatterns.sln b/HeadFirstDesignPatterns.sln
index 6532c04..14485aa 100644
--- a/HeadFirstDesignPatterns.sln
+++ b/HeadFirstDesignPatterns.sln
@@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch2Weather", "Ch2Weather\Ch
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch3Beverage", "Ch3Beverage\Ch3Beverage.csproj", "{8F380143-DDBC-4785-B4F2-7B32EBE54515}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ch4PizzaStore", "Ch4PizzaStore\Ch4PizzaStore.csproj", "{EECD03A1-DE37-4E1B-8487-0A6DE21FBDB3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -24,5 +26,9 @@ Global
{8F380143-DDBC-4785-B4F2-7B32EBE54515}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8F380143-DDBC-4785-B4F2-7B32EBE54515}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F380143-DDBC-4785-B4F2-7B32EBE54515}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EECD03A1-DE37-4E1B-8487-0A6DE21FBDB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EECD03A1-DE37-4E1B-8487-0A6DE21FBDB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EECD03A1-DE37-4E1B-8487-0A6DE21FBDB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EECD03A1-DE37-4E1B-8487-0A6DE21FBDB3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/HeadFirstDesignPatterns.sln.DotSettings b/HeadFirstDesignPatterns.sln.DotSettings
new file mode 100644
index 0000000..5d3463e
--- /dev/null
+++ b/HeadFirstDesignPatterns.sln.DotSettings
@@ -0,0 +1,2 @@
+
+ NY
\ No newline at end of file