├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── DesignPatterns.sln ├── NuGet.Config ├── README.md ├── global.json └── src ├── adapter ├── Ducks │ ├── Adapters │ │ ├── DuckAdapter.cs │ │ └── TurkeyAdapter.cs │ ├── Ducks.csproj │ ├── Models │ │ ├── Ducks │ │ │ ├── IDuck.cs │ │ │ └── MallardDuck.cs │ │ └── Turkeys │ │ │ ├── ITurkey.cs │ │ │ └── WildTurkey.cs │ └── Program.cs └── README.md ├── combined └── DuckSimulator │ ├── AbstractDuckFactory.cs │ ├── CountingDuckFactory.cs │ ├── DecoyDuck.cs │ ├── DuckCall.cs │ ├── DuckFactory.cs │ ├── DuckSimulator.csproj │ ├── Flock.cs │ ├── Goose.cs │ ├── GooseAdapter.cs │ ├── IObserver.cs │ ├── IQuackObservable.cs │ ├── IQuackable.cs │ ├── MallardDuck.cs │ ├── Observable.cs │ ├── Program.cs │ ├── QuackCounter.cs │ ├── Quackologist.cs │ ├── RedheadDuck.cs │ └── RubberDuck.cs ├── command ├── Party │ ├── Commands │ │ ├── Abstractions │ │ │ └── ICommand.cs │ │ ├── CeilingFanHighCommand.cs │ │ ├── CeilingFanMediumCommand.cs │ │ ├── CeilingFanOffCommand.cs │ │ ├── HottubOffCommand.cs │ │ ├── HottubOnCommand.cs │ │ ├── LightOffCommand.cs │ │ ├── LightOnCommand.cs │ │ ├── MacroCommand.cs │ │ ├── NoCommand.cs │ │ ├── StereoOffCommand.cs │ │ ├── StereoOnCommand.cs │ │ ├── StereoOnWithCDCommand.cs │ │ ├── TVOffCommand.cs │ │ └── TVOnCommand.cs │ ├── Invokers │ │ └── RemoteControl.cs │ ├── Party.csproj │ ├── Program.cs │ └── Receivers │ │ ├── CeilingFan.cs │ │ ├── Hottub.cs │ │ ├── Light.cs │ │ ├── Stereo.cs │ │ └── TV.cs ├── README.md ├── RemoteControl │ ├── Commands │ │ ├── Abstractions │ │ │ └── ICommand.cs │ │ ├── CeilingFanOffCommand.cs │ │ ├── CeilingFanOnCommand.cs │ │ ├── GarageDoorDownCommand.cs │ │ ├── GarageDoorUpCommand.cs │ │ ├── HottubOffCommand.cs │ │ ├── HottubOnCommand.cs │ │ ├── LightOffCommand.cs │ │ ├── LightOnCommand.cs │ │ ├── LivingroomLightOffCommand.cs │ │ ├── LivingroomLightOnCommand.cs │ │ ├── NoCommand.cs │ │ ├── StereoOffCommand.cs │ │ └── StereoOnWithCDCommand.cs │ ├── Invokers │ │ └── RemoteControl.cs │ ├── Program.cs │ ├── Receivers │ │ ├── CeilingFan.cs │ │ ├── GarageDoor.cs │ │ ├── Hottub.cs │ │ ├── Light.cs │ │ ├── Stereo.cs │ │ └── TV.cs │ └── RemoteControl.csproj ├── RemoteControlWithUndo │ ├── Commands │ │ ├── Abstractions │ │ │ └── ICommand.cs │ │ ├── CeilingFanHighCommand.cs │ │ ├── CeilingFanLowCommand.cs │ │ ├── CeilingFanMediumCommand.cs │ │ ├── CeilingFanOffCommand.cs │ │ ├── DimmerLightOffCommand.cs │ │ ├── DimmerLightOnCommand.cs │ │ ├── LightOffCommand.cs │ │ ├── LightOnCommand.cs │ │ └── NoCommand.cs │ ├── Invokers │ │ └── RemoteControlWithUndo.cs │ ├── Program.cs │ ├── Receivers │ │ ├── CeilingFan.cs │ │ └── Light.cs │ └── RemoteControlWithUndo.csproj └── SimpleRemoteControl │ ├── Commands │ ├── Abstractions │ │ └── ICommand.cs │ ├── GarageDoorOpenCommand.cs │ ├── LightOffCommand.cs │ └── LightOnCommand.cs │ ├── Invokers │ └── SimpleRemoteControl.cs │ ├── Program.cs │ ├── Receivers │ ├── GarageDoor.cs │ └── Light.cs │ └── SimpleRemoteControl.csproj ├── composite ├── Menu │ ├── Menu.cs │ ├── Menu.csproj │ ├── MenuComponent.cs │ ├── MenuItem.cs │ ├── Program.cs │ └── Waitress.cs ├── MenuIterator │ ├── CompositeIterator.cs │ ├── Menu.cs │ ├── MenuComponent.cs │ ├── MenuItem.cs │ ├── MenuIterator.csproj │ ├── NullIterator.cs │ ├── Program.cs │ └── Waitress.cs └── README.md ├── decorator ├── README.md └── StarbuzzCoffee │ ├── Components │ ├── Abstractions │ │ └── Beverage.cs │ ├── DarkRoast.cs │ ├── Espresso.cs │ └── HouseBlend.cs │ ├── Decorators │ ├── Abstractions │ │ └── CondimentDecorator.cs │ ├── Mocha.cs │ ├── Soy.cs │ └── Whip.cs │ ├── Program.cs │ └── StarbuzzCoffee.csproj ├── facade ├── HomeTheater │ ├── Facade │ │ └── HomeTheaterFacade.cs │ ├── HomeTheater.csproj │ ├── Program.cs │ └── Subsystems │ │ ├── Amplifier.cs │ │ ├── CdPlayer.cs │ │ ├── DvdPlayer.cs │ │ ├── PopcornPopper.cs │ │ ├── Projector.cs │ │ ├── Screen.cs │ │ ├── TheaterLights.cs │ │ └── Tuner.cs └── README.md ├── factory ├── PizzaStoreAbstractFactory │ ├── AbstractFactories │ │ ├── Abstractions │ │ │ └── IPizzaIngredientFactory.cs │ │ ├── ChicagoPizzaIngredientFactory.cs │ │ └── NYPizzaIngredientFactory.cs │ ├── FactoryMethods │ │ ├── Abstractions │ │ │ └── PizzaStore.cs │ │ ├── ChicagoPizzaStore.cs │ │ └── NYPizzaStore.cs │ ├── PizzaStoreAbstractFactory.csproj │ ├── Products │ │ ├── Ingredients │ │ │ ├── Abstractions │ │ │ │ ├── ICheese.cs │ │ │ │ ├── IClams.cs │ │ │ │ ├── IDough.cs │ │ │ │ ├── IPepperoni.cs │ │ │ │ ├── ISauce.cs │ │ │ │ └── IVeggies.cs │ │ │ ├── BlackOlives.cs │ │ │ ├── Eggplant.cs │ │ │ ├── FreshClams.cs │ │ │ ├── FrozenClams.cs │ │ │ ├── Garlic.cs │ │ │ ├── MarinaraSauce.cs │ │ │ ├── MozzarellaCheese.cs │ │ │ ├── Mushroom.cs │ │ │ ├── Onion.cs │ │ │ ├── ParmesanCheese.cs │ │ │ ├── PlumTomatoSauce.cs │ │ │ ├── RedPepper.cs │ │ │ ├── ReggianoCheese.cs │ │ │ ├── SlicedPepperoni.cs │ │ │ ├── Spinach.cs │ │ │ ├── ThickCrustDough.cs │ │ │ └── ThinCrustDough.cs │ │ └── Pizzas │ │ │ ├── Abstractions │ │ │ └── Pizza.cs │ │ │ ├── CheesePizza.cs │ │ │ ├── ClamPizza.cs │ │ │ ├── PepperoniPizza.cs │ │ │ └── VeggiePizza.cs │ └── Program.cs ├── PizzaStoreFactoryMethod │ ├── FactoryMethods │ │ ├── Abstractions │ │ │ └── PizzaStore.cs │ │ ├── ChicagoPizzaStore.cs │ │ └── NYPizzaStore.cs │ ├── PizzaStoreFactoryMethod.csproj │ ├── Products │ │ └── Pizzas │ │ │ ├── Abstractions │ │ │ └── Pizza.cs │ │ │ ├── ChicagoStyleCheesePizza.cs │ │ │ ├── ChicagoStyleClamPizza.cs │ │ │ ├── ChicagoStylePepperoniPizza.cs │ │ │ ├── ChicagoStyleVeggiePizza.cs │ │ │ ├── NYStyleCheesePizza.cs │ │ │ ├── NYStyleClamPizza.cs │ │ │ ├── NYStylePepperoniPizza.cs │ │ │ └── NYStyleVeggiePizza.cs │ └── Program.cs ├── PizzaStoreSimpleFactory │ ├── PizzaStore.cs │ ├── PizzaStoreSimpleFactory.csproj │ ├── Pizzas │ │ ├── Abstractions │ │ │ └── Pizza.cs │ │ ├── CheesePizza.cs │ │ ├── ClamPizza.cs │ │ ├── PepperoniPizza.cs │ │ └── VeggiePizza.cs │ ├── Program.cs │ └── SimpleFactories │ │ └── SimplePizzaFactory.cs └── README.md ├── iterator ├── DinerMerger │ ├── AlternatingDinerMenuIterator.cs │ ├── DinerMenu.cs │ ├── DinerMenuIterator.cs │ ├── DinerMerger.csproj │ ├── IIterator.cs │ ├── IMenu.cs │ ├── MenuItem.cs │ ├── PancakeHouseMenu.cs │ ├── PancakeHouseMenuIterator.cs │ ├── Program.cs │ └── Waitress.cs ├── DinerMergerCafe │ ├── CafeMenu.cs │ ├── DinerMenu.cs │ ├── DinerMenuIterator.cs │ ├── DinerMergerCafe.csproj │ ├── IMenu.cs │ ├── MenuItem.cs │ ├── PancakeHouseMenu.cs │ ├── Program.cs │ └── Waitress.cs └── README.md ├── observer ├── README.md ├── WeatherStation.Observable │ ├── Observers │ │ ├── Abstractions │ │ │ └── IDisplayElement.cs │ │ ├── CurrentConditionsDisplay.cs │ │ ├── ForecastDisplay.cs │ │ ├── HeatIndexDisplay.cs │ │ └── StatisticsDisplay.cs │ ├── Program.cs │ ├── Subjects │ │ └── WeatherData.cs │ └── WeatherStation.Observable.csproj └── WeatherStation │ ├── Observers │ ├── Abstractions │ │ ├── IDisplayElement.cs │ │ └── IObserver.cs │ ├── CurrentConditionsDisplay.cs │ ├── ForecastDisplay.cs │ ├── HeatIndexDisplay.cs │ └── StatisticsDisplay.cs │ ├── Program.cs │ ├── Subjects │ ├── Abstractions │ │ └── ISubject.cs │ └── WeatherData.cs │ └── WeatherStation.csproj ├── proxy └── README.md ├── singleton ├── ChocolateBoiler │ ├── ChocolateBoiler.cs │ ├── ChocolateBoiler.csproj │ └── Program.cs ├── MultipleSingleton │ ├── MultipleSingleton.csproj │ ├── Program.cs │ └── Singletons │ │ ├── ClassicSingleton.cs │ │ ├── DclSingleton.cs │ │ ├── StaticSingleton.cs │ │ ├── Subclasses │ │ ├── BaseSingleton.cs │ │ ├── CoolerSingleton.cs │ │ └── HotterSingleton.cs │ │ └── ThreadSafeSingleton.cs └── README.md ├── state ├── Gumball │ ├── Gumball.csproj │ ├── GumballMachine.cs │ └── Program.cs ├── GumballState │ ├── GumballMachine.cs │ ├── GumballState.csproj │ ├── Program.cs │ └── States │ │ ├── Abstractions │ │ └── IState.cs │ │ ├── HasQuarterState.cs │ │ ├── NoQuarterState.cs │ │ ├── SoldOutState.cs │ │ └── SoldState.cs ├── GumballStateWinner │ ├── GumballMachine.cs │ ├── GumballStateWinner.csproj │ ├── Program.cs │ └── States │ │ ├── Abstractions │ │ └── IState.cs │ │ ├── HasQuarterState.cs │ │ ├── NoQuarterState.cs │ │ ├── SoldOutState.cs │ │ ├── SoldState.cs │ │ └── WinnerState.cs └── README.md ├── strategy ├── MiniDuckSimulator │ ├── Behaviors │ │ ├── Abstractions │ │ │ ├── IFlyBehavior.cs │ │ │ └── IQuackBehavior.cs │ │ ├── FlyNoWay.cs │ │ ├── FlyRocketPowered.cs │ │ ├── FlyWithWings.cs │ │ ├── MuteQuack.cs │ │ ├── Quack.cs │ │ └── Squeak.cs │ ├── Ducks │ │ ├── Abstractions │ │ │ └── Duck.cs │ │ ├── DecoyDuck.cs │ │ ├── MallardDuck.cs │ │ ├── ModelDuck.cs │ │ ├── RedHeadDuck.cs │ │ └── RubberDuck.cs │ ├── MiniDuckSimulator.csproj │ └── Program.cs └── README.md └── templatemethod ├── Barista ├── Barista.csproj ├── CaffeineBeverage.cs ├── CaffeineBeverageWithHook.cs ├── Coffee.cs ├── CoffeeWithHook.cs ├── Program.cs ├── Tea.cs └── TeaWithHook.cs ├── DuckSort ├── Duck.cs ├── DuckSort.csproj └── Program.cs └── README.md /NuGet.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Design Patterns 2 | 3 | 4 | ## OO Patterns 5 | * [Strategy](/src/strategy) 6 | * [Observer](/src/observer) 7 | * [Decorator](/src/decorator) 8 | * [Factory Method](/src/factory) 9 | * [Abstract Factory](/src/factory) 10 | * [Singleton](/src/singleton) 11 | * [Command](/src/command) 12 | * [Adapter](/src/adapter) 13 | * [Facade](/src/facade) 14 | * [Template Method](/src/templatemethod) 15 | * [Iterator](/src/iterator) 16 | * [Composite](/src/composite) 17 | * [State](/src/state) 18 | * [Proxy](/src/proxy) 19 | 20 | ## OO Principles 21 | 22 | * Encapsulates what varies. 23 | * Favor composition over inheritance. 24 | * Program to interfaces, not implementations. 25 | * Strive for loosely coupled designs between objects that interact 26 | * Classes should be open for extension but closed for modification. 27 | * Depend on abstractions. Do not depend on concrete classes. 28 | * Principle of Least Knowledge: talk only to your immediate friends. 29 | * The Hollywood Principle: Don't call us, we'll call you. 30 | * A class should have only one reason to change. 31 | 32 | 33 | 34 | 35 | **You need [.NET 8](https://www.dot.net) to run these examples.** 36 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "8.0.201", 4 | "rollForward": "latestFeature" 5 | } 6 | } -------------------------------------------------------------------------------- /src/adapter/Ducks/Adapters/DuckAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Ducks.Models.Ducks; 3 | using Ducks.Models.Turkeys; 4 | 5 | namespace Ducks.Adapters 6 | { 7 | public class DuckAdapter : ITurkey //target interface 8 | { 9 | //adaptee interface 10 | private readonly IDuck _duck; 11 | private readonly Random _random; 12 | 13 | public DuckAdapter(IDuck duck) 14 | { 15 | _duck = duck; 16 | _random = new Random(); 17 | } 18 | 19 | public void Gobble() 20 | { 21 | _duck.Quack(); 22 | } 23 | 24 | public void Fly() 25 | { 26 | if (_random.Next(5) == 0) 27 | { 28 | _duck.Fly(); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/adapter/Ducks/Adapters/TurkeyAdapter.cs: -------------------------------------------------------------------------------- 1 | using Ducks.Models.Ducks; 2 | using Ducks.Models.Turkeys; 3 | 4 | namespace Ducks.Adapters 5 | { 6 | public class TurkeyAdapter : IDuck //target interface 7 | { 8 | //adaptee interface 9 | private readonly ITurkey _turkey; 10 | 11 | public TurkeyAdapter(ITurkey turkey) 12 | { 13 | _turkey = turkey; 14 | } 15 | 16 | public void Quack() 17 | { 18 | _turkey.Gobble(); 19 | } 20 | 21 | public void Fly() 22 | { 23 | for (int i = 0; i < 5; i++) 24 | { 25 | _turkey.Fly(); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/adapter/Ducks/Ducks.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/adapter/Ducks/Models/Ducks/IDuck.cs: -------------------------------------------------------------------------------- 1 | namespace Ducks.Models.Ducks 2 | { 3 | public interface IDuck 4 | { 5 | void Quack(); 6 | void Fly(); 7 | } 8 | } -------------------------------------------------------------------------------- /src/adapter/Ducks/Models/Ducks/MallardDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ducks.Models.Ducks 4 | { 5 | public class MallardDuck : IDuck 6 | { 7 | public void Quack() 8 | { 9 | Console.WriteLine("Quack"); 10 | } 11 | 12 | public void Fly() 13 | { 14 | Console.WriteLine("I'm flying"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/adapter/Ducks/Models/Turkeys/ITurkey.cs: -------------------------------------------------------------------------------- 1 | namespace Ducks.Models.Turkeys 2 | { 3 | public interface ITurkey 4 | { 5 | void Gobble(); 6 | void Fly(); 7 | } 8 | } -------------------------------------------------------------------------------- /src/adapter/Ducks/Models/Turkeys/WildTurkey.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Ducks.Models.Turkeys 4 | { 5 | public class WildTurkey : ITurkey 6 | { 7 | public void Gobble() 8 | { 9 | Console.WriteLine("Gobble gobble"); 10 | } 11 | 12 | public void Fly() 13 | { 14 | Console.WriteLine("I'm flying a short distance"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/adapter/Ducks/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Ducks.Adapters; 3 | using Ducks.Models.Ducks; 4 | using Ducks.Models.Turkeys; 5 | 6 | namespace Ducks 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | MallardDuck duck = new MallardDuck(); 13 | 14 | WildTurkey turkey = new WildTurkey(); 15 | IDuck turkeyAdapter = new TurkeyAdapter(turkey); 16 | 17 | Console.WriteLine("The Turkey says..."); 18 | turkey.Gobble(); 19 | turkey.Fly(); 20 | 21 | Console.WriteLine("\nThe Duck says..."); 22 | TestDuck(duck); 23 | 24 | Console.WriteLine("\nThe TurkeyAdapter says..."); 25 | TestDuck(turkeyAdapter); 26 | 27 | ITurkey duckAdapter = new DuckAdapter(duck); 28 | 29 | Console.WriteLine(""); 30 | for (int i = 0; i < 10; i++) 31 | { 32 | Console.WriteLine("The DuckAdapter says..."); 33 | duckAdapter.Gobble(); 34 | duckAdapter.Fly(); 35 | } 36 | } 37 | 38 | public static void TestDuck(IDuck duck) 39 | { 40 | duck.Quack(); 41 | duck.Fly(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/adapter/README.md: -------------------------------------------------------------------------------- 1 | **The Adapter Pattern** converts the interface of a class into another interface the clients expect. 2 | Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. -------------------------------------------------------------------------------- /src/combined/DuckSimulator/AbstractDuckFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public abstract class AbstractDuckFactory 4 | { 5 | public abstract IQuackable CreateMallardDuck(); 6 | public abstract IQuackable CreateRedheadDuck(); 7 | public abstract IQuackable CreateDuckCall(); 8 | public abstract IQuackable CreateRubberDuck(); 9 | } 10 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/CountingDuckFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public class CountingDuckFactory : AbstractDuckFactory 4 | { 5 | public override IQuackable CreateDuckCall() => new QuackCounter(new DuckCall()); 6 | 7 | public override IQuackable CreateMallardDuck() => new QuackCounter(new MallardDuck()); 8 | 9 | public override IQuackable CreateRedheadDuck() => new QuackCounter(new RedheadDuck()); 10 | 11 | public override IQuackable CreateRubberDuck() => new QuackCounter(new RubberDuck()); 12 | } 13 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/DecoyDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class DecoyDuck : IQuackable 6 | { 7 | private Observable _observable; 8 | 9 | public DecoyDuck() 10 | { 11 | _observable = new Observable(this); 12 | } 13 | 14 | public void Quack() 15 | { 16 | Console.WriteLine("<< Silence >>"); 17 | NotifyObservers(); 18 | } 19 | 20 | public void RegisterObserver(IObserver observer) => _observable.RegisterObserver(observer); 21 | 22 | public void NotifyObservers() => _observable.NotifyObservers(); 23 | 24 | public override string ToString() => "Decoy Duck"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/DuckCall.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class DuckCall : IQuackable 6 | { 7 | private Observable _observable; 8 | 9 | public DuckCall() 10 | { 11 | _observable = new Observable(this); 12 | } 13 | 14 | public void Quack() 15 | { 16 | Console.WriteLine("Kwak"); 17 | NotifyObservers(); 18 | } 19 | 20 | public void RegisterObserver(IObserver observer) => _observable.RegisterObserver(observer); 21 | 22 | public void NotifyObservers() => _observable.NotifyObservers(); 23 | 24 | public override string ToString() => "Duck Call"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/DuckFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public class DuckFactory : AbstractDuckFactory 4 | { 5 | public override IQuackable CreateDuckCall() => new DuckCall(); 6 | 7 | public override IQuackable CreateMallardDuck() => new MallardDuck(); 8 | 9 | public override IQuackable CreateRedheadDuck() => new RedheadDuck(); 10 | 11 | public override IQuackable CreateRubberDuck() => new RubberDuck(); 12 | } 13 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/DuckSimulator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/combined/DuckSimulator/Flock.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class Flock : IQuackable 6 | { 7 | private List _ducks = new List(); 8 | 9 | public void Add(IQuackable duck) => _ducks.Add(duck); 10 | 11 | public void Quack() 12 | { 13 | foreach (var duck in _ducks) 14 | { 15 | duck.Quack(); 16 | } 17 | } 18 | 19 | public void RegisterObserver(IObserver observer) 20 | { 21 | foreach (var duck in _ducks) 22 | { 23 | duck.RegisterObserver(observer); 24 | } 25 | } 26 | 27 | public void NotifyObservers() {} 28 | 29 | public override string ToString() => "Flock of Ducks"; 30 | } 31 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/Goose.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class Goose 6 | { 7 | public void Honk() => Console.WriteLine("Honk"); 8 | 9 | public override string ToString() => "Goose"; 10 | } 11 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/GooseAdapter.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public class GooseAdapter : IQuackable 4 | { 5 | private Goose _goose; 6 | private Observable _observable; 7 | 8 | public GooseAdapter(Goose goose) 9 | { 10 | _goose = goose; 11 | _observable = new Observable(this); 12 | } 13 | 14 | public void Quack() 15 | { 16 | _goose.Honk(); 17 | } 18 | 19 | public void RegisterObserver(IObserver observer) => _observable.RegisterObserver(observer); 20 | 21 | public void NotifyObservers() => _observable.NotifyObservers(); 22 | 23 | public override string ToString() => "Goose pretending to be a Duck"; 24 | } 25 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/IObserver.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public interface IObserver 4 | { 5 | void Update(IQuackObservable duck); 6 | } 7 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/IQuackObservable.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public interface IQuackObservable 4 | { 5 | void RegisterObserver(IObserver observer); 6 | void NotifyObservers(); 7 | } 8 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/IQuackable.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public interface IQuackable : IQuackObservable 4 | { 5 | void Quack(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/MallardDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class MallardDuck : IQuackable 6 | { 7 | private Observable _observable; 8 | 9 | public MallardDuck() 10 | { 11 | _observable = new Observable(this); 12 | } 13 | 14 | public void Quack() 15 | { 16 | Console.WriteLine("Quack"); 17 | NotifyObservers(); 18 | } 19 | 20 | public void RegisterObserver(IObserver observer) => _observable.RegisterObserver(observer); 21 | 22 | public void NotifyObservers() => _observable.NotifyObservers(); 23 | 24 | public override string ToString() => "Mallard Duck"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/Observable.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class Observable : IQuackObservable 6 | { 7 | private List _observers = new List(); 8 | private IQuackObservable _duck; 9 | 10 | public Observable(IQuackObservable duck) 11 | { 12 | _duck = duck; 13 | } 14 | 15 | public void RegisterObserver(IObserver observer) => _observers.Add(observer); 16 | 17 | public void NotifyObservers() 18 | { 19 | foreach (var observer in _observers) 20 | { 21 | observer.Update(_duck); 22 | } 23 | } 24 | 25 | public IEnumerable GetOberservers => _observers; 26 | } 27 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/QuackCounter.cs: -------------------------------------------------------------------------------- 1 | namespace DuckSimulator 2 | { 3 | public class QuackCounter : IQuackable 4 | { 5 | public static int NumberOfQuacks { get; private set; } 6 | 7 | private IQuackable _duck; 8 | 9 | public QuackCounter(IQuackable duck) 10 | { 11 | _duck = duck; 12 | } 13 | 14 | public void Quack() 15 | { 16 | _duck.Quack(); 17 | NumberOfQuacks++; 18 | } 19 | 20 | public void RegisterObserver(IObserver observer) => _duck.RegisterObserver(observer); 21 | 22 | public void NotifyObservers() => _duck.NotifyObservers(); 23 | 24 | public override string ToString() => _duck.ToString(); 25 | } 26 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/Quackologist.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class Quackologist : IObserver 6 | { 7 | public void Update(IQuackObservable duck) => Console.WriteLine("Quackologist: " + duck + " just quacked."); 8 | 9 | public override string ToString() => "Quackologist"; 10 | } 11 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/RedheadDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class RedheadDuck : IQuackable 6 | { 7 | private Observable _observable; 8 | 9 | public RedheadDuck() 10 | { 11 | _observable = new Observable(this); 12 | } 13 | 14 | public void Quack() 15 | { 16 | Console.WriteLine("Quack"); 17 | NotifyObservers(); 18 | } 19 | 20 | public void RegisterObserver(IObserver observer) => _observable.RegisterObserver(observer); 21 | 22 | public void NotifyObservers() => _observable.NotifyObservers(); 23 | 24 | public override string ToString() => "Redhead Duck"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/combined/DuckSimulator/RubberDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSimulator 4 | { 5 | public class RubberDuck : IQuackable 6 | { 7 | private Observable _observable; 8 | 9 | public RubberDuck() 10 | { 11 | _observable = new Observable(this); 12 | } 13 | 14 | public void Quack() 15 | { 16 | Console.WriteLine("Squeak"); 17 | NotifyObservers(); 18 | } 19 | 20 | public void RegisterObserver(IObserver observer) => _observable.RegisterObserver(observer); 21 | 22 | public void NotifyObservers() => _observable.NotifyObservers(); 23 | 24 | public override string ToString() => "Rubber Duck"; 25 | } 26 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/Abstractions/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace Party.Commands 2 | { 3 | public interface ICommand 4 | { 5 | void Execute(); 6 | void Undo(); 7 | } 8 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/CeilingFanHighCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class CeilingFanHighCommand : ICommand 6 | { 7 | private readonly CeilingFan _ceilingFan; 8 | private int _prevSpeed; 9 | 10 | public CeilingFanHighCommand(CeilingFan ceilingFan) 11 | { 12 | _ceilingFan = ceilingFan; 13 | } 14 | 15 | public void Execute() 16 | { 17 | _prevSpeed = _ceilingFan.GetSpeed(); 18 | _ceilingFan.High(); 19 | } 20 | 21 | public void Undo() 22 | { 23 | switch (_prevSpeed) 24 | { 25 | case CeilingFan.HIGH: 26 | _ceilingFan.High(); 27 | break; 28 | case CeilingFan.MEDIUM: 29 | _ceilingFan.Medium(); 30 | break; 31 | case CeilingFan.LOW: 32 | _ceilingFan.Low(); 33 | break; 34 | case CeilingFan.OFF: 35 | _ceilingFan.Off(); 36 | break; 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/CeilingFanMediumCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class CeilingFanMediumCommand : ICommand 6 | { 7 | private readonly CeilingFan _ceilingFan; 8 | private int _prevSpeed; 9 | 10 | public CeilingFanMediumCommand(CeilingFan ceilingFan) 11 | { 12 | _ceilingFan = ceilingFan; 13 | } 14 | 15 | public void Execute() 16 | { 17 | _prevSpeed = _ceilingFan.GetSpeed(); 18 | _ceilingFan.Medium(); 19 | } 20 | 21 | public void Undo() 22 | { 23 | switch (_prevSpeed) 24 | { 25 | case CeilingFan.HIGH: 26 | _ceilingFan.High(); 27 | break; 28 | case CeilingFan.MEDIUM: 29 | _ceilingFan.Medium(); 30 | break; 31 | case CeilingFan.LOW: 32 | _ceilingFan.Low(); 33 | break; 34 | case CeilingFan.OFF: 35 | _ceilingFan.Off(); 36 | break; 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/CeilingFanOffCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class CeilingFanOffCommand : ICommand 6 | { 7 | private readonly CeilingFan _ceilingFan; 8 | private int _prevSpeed; 9 | 10 | public CeilingFanOffCommand(CeilingFan ceilingFan) 11 | { 12 | _ceilingFan = ceilingFan; 13 | } 14 | 15 | public void Execute() 16 | { 17 | _prevSpeed = _ceilingFan.GetSpeed(); 18 | _ceilingFan.Off(); 19 | } 20 | 21 | public void Undo() 22 | { 23 | switch (_prevSpeed) 24 | { 25 | case CeilingFan.HIGH: 26 | _ceilingFan.High(); 27 | break; 28 | case CeilingFan.MEDIUM: 29 | _ceilingFan.Medium(); 30 | break; 31 | case CeilingFan.LOW: 32 | _ceilingFan.Low(); 33 | break; 34 | case CeilingFan.OFF: 35 | _ceilingFan.Off(); 36 | break; 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/HottubOffCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class HottubOffCommand : ICommand 6 | { 7 | private readonly Hottub _hottub; 8 | 9 | public HottubOffCommand(Hottub hottub) 10 | { 11 | _hottub = hottub; 12 | } 13 | 14 | public void Execute() 15 | { 16 | _hottub.SetTemperature(98); 17 | _hottub.Off(); 18 | } 19 | 20 | public void Undo() => _hottub.On(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/HottubOnCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class HottubOnCommand : ICommand 6 | { 7 | private readonly Hottub _hottub; 8 | 9 | public HottubOnCommand(Hottub hottub) 10 | { 11 | _hottub = hottub; 12 | } 13 | 14 | public void Execute() 15 | { 16 | _hottub.On(); 17 | _hottub.SetTemperature(104); 18 | _hottub.Circulate(); 19 | } 20 | 21 | public void Undo() => _hottub.Off(); 22 | } 23 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/LightOffCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class LightOffCommand : ICommand 6 | { 7 | private readonly Light _light; 8 | 9 | public LightOffCommand(Light light) 10 | { 11 | _light = light; 12 | } 13 | 14 | public void Execute() => _light.Off(); 15 | 16 | public void Undo() => _light.On(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/LightOnCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class LightOnCommand : ICommand 6 | { 7 | private readonly Light _light; 8 | 9 | public LightOnCommand(Light light) 10 | { 11 | _light = light; 12 | } 13 | 14 | public void Execute() => _light.On(); 15 | 16 | public void Undo() => _light.Off(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/MacroCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Party.Commands 2 | { 3 | public class MacroCommand : ICommand 4 | { 5 | private readonly ICommand[] _commands; 6 | 7 | public MacroCommand(ICommand[] commands) 8 | { 9 | _commands = commands; 10 | } 11 | 12 | public void Execute() 13 | { 14 | foreach (ICommand command in _commands) 15 | { 16 | command.Execute(); 17 | } 18 | } 19 | 20 | public void Undo() 21 | { 22 | for (int i = _commands.Length - 1; i >= 0; i--) 23 | { 24 | _commands[i].Undo(); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/NoCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Party.Commands 2 | { 3 | public class NoCommand : ICommand 4 | { 5 | public void Execute() {} 6 | public void Undo() {} 7 | } 8 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/StereoOffCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class StereoOffCommand : ICommand 6 | { 7 | private readonly Stereo _stereo; 8 | 9 | public StereoOffCommand(Stereo stereo) 10 | { 11 | _stereo = stereo; 12 | } 13 | 14 | public void Execute() => _stereo.Off(); 15 | 16 | public void Undo() => _stereo.On(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/StereoOnCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class StereoOnCommand : ICommand 6 | { 7 | private readonly Stereo _stereo; 8 | 9 | public StereoOnCommand(Stereo stereo) 10 | { 11 | _stereo = stereo; 12 | } 13 | 14 | public void Execute() => _stereo.On(); 15 | 16 | public void Undo() => _stereo.Off(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/StereoOnWithCDCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class StereoOnWithCDCommand : ICommand 6 | { 7 | private readonly Stereo _stereo; 8 | 9 | public StereoOnWithCDCommand(Stereo stereo) 10 | { 11 | _stereo = stereo; 12 | } 13 | 14 | public void Execute() 15 | { 16 | _stereo.On(); 17 | _stereo.SetCD(); 18 | _stereo.SetVolume(11); 19 | } 20 | 21 | public void Undo() => _stereo.Off(); 22 | } 23 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/TVOffCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class TVOffCommand : ICommand 6 | { 7 | private readonly TV _tv; 8 | 9 | public TVOffCommand(TV tv) 10 | { 11 | _tv = tv; 12 | } 13 | 14 | public void Execute() => _tv.Off(); 15 | 16 | public void Undo() => _tv.On(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/command/Party/Commands/TVOnCommand.cs: -------------------------------------------------------------------------------- 1 | using Party.Receivers; 2 | 3 | namespace Party.Commands 4 | { 5 | public class TVOnCommand : ICommand 6 | { 7 | private readonly TV _tv; 8 | 9 | public TVOnCommand(TV tv) 10 | { 11 | _tv = tv; 12 | } 13 | 14 | public void Execute() 15 | { 16 | _tv.On(); 17 | _tv.SetInputChannel(); 18 | } 19 | 20 | public void Undo() => _tv.Off(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/command/Party/Party.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/command/Party/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Party.Commands; 3 | using Party.Invokers; 4 | using Party.Receivers; 5 | 6 | namespace Party 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | var remoteControl = new RemoteControl(); 13 | 14 | Light light = new Light("Living Room"); 15 | TV tv = new TV("Living Room"); 16 | Stereo stereo = new Stereo("Living Room"); 17 | Hottub hottub = new Hottub(); 18 | 19 | LightOnCommand lightOn = new LightOnCommand(light); 20 | StereoOnCommand stereoOn = new StereoOnCommand(stereo); 21 | TVOnCommand tvOn = new TVOnCommand(tv); 22 | HottubOnCommand hottubOn = new HottubOnCommand(hottub); 23 | LightOffCommand lightOff = new LightOffCommand(light); 24 | StereoOffCommand stereoOff = new StereoOffCommand(stereo); 25 | TVOffCommand tvOff = new TVOffCommand(tv); 26 | HottubOffCommand hottubOff = new HottubOffCommand(hottub); 27 | 28 | ICommand[] partyOn = { lightOn, stereoOn, tvOn, hottubOn }; 29 | ICommand[] partyOff = { lightOff, stereoOff, tvOff, hottubOff }; 30 | 31 | MacroCommand partyOnMacro = new MacroCommand(partyOn); 32 | MacroCommand partyOffMacro = new MacroCommand(partyOff); 33 | 34 | remoteControl.SetCommand(0, partyOnMacro, partyOffMacro); 35 | 36 | Console.WriteLine(remoteControl); 37 | Console.WriteLine("--- Pushing Macro On---"); 38 | remoteControl.OnButtonWasPushed(0); 39 | Console.WriteLine("--- Pushing Macro Off---"); 40 | remoteControl.OffButtonWasPushed(0); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/command/Party/Receivers/CeilingFan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Party.Receivers 4 | { 5 | public class CeilingFan 6 | { 7 | private readonly string _location; 8 | private int _speed; 9 | 10 | public const int HIGH = 3; 11 | public const int MEDIUM = 2; 12 | public const int LOW = 1; 13 | public const int OFF = 0; 14 | 15 | public CeilingFan(string location) 16 | { 17 | _location = location; 18 | } 19 | 20 | public void High() 21 | { 22 | // turns the ceiling fan on to high 23 | _speed = HIGH; 24 | Console.WriteLine(_location + " ceiling fan is on high"); 25 | } 26 | 27 | public void Medium() 28 | { 29 | // turns the ceiling fan on to medium 30 | _speed = MEDIUM; 31 | Console.WriteLine(_location + " ceiling fan is on medium"); 32 | } 33 | 34 | public void Low() 35 | { 36 | // turns the ceiling fan on to low 37 | _speed = LOW; 38 | Console.WriteLine(_location + " ceiling fan is on low"); 39 | } 40 | 41 | public void Off() 42 | { 43 | // turns the ceiling fan off 44 | _speed = OFF; 45 | Console.WriteLine(_location + " ceiling fan is off"); 46 | } 47 | 48 | public int GetSpeed() => _speed; 49 | } 50 | } -------------------------------------------------------------------------------- /src/command/Party/Receivers/Hottub.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Party.Receivers 4 | { 5 | public class Hottub 6 | { 7 | private bool _on; 8 | private int _temperature; 9 | 10 | public void On() => _on = true; 11 | 12 | public void Off() => _on = false; 13 | 14 | public void Circulate() 15 | { 16 | if (_on) 17 | { 18 | Console.WriteLine("Hottub is bubbling!"); 19 | } 20 | } 21 | 22 | public void JetsOn() 23 | { 24 | if (_on) 25 | { 26 | Console.WriteLine("Hottub jets are on"); 27 | } 28 | } 29 | 30 | public void JetsOff() 31 | { 32 | if (_on) 33 | { 34 | Console.WriteLine("Hottub jets are off"); 35 | } 36 | } 37 | 38 | public void SetTemperature(int temperature) 39 | { 40 | if (temperature > _temperature) 41 | { 42 | Console.WriteLine("Hottub is heating to a steaming " + temperature + " degrees"); 43 | } 44 | else 45 | { 46 | Console.WriteLine("Hottub is cooling to " + temperature + " degrees"); 47 | } 48 | _temperature = temperature; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/command/Party/Receivers/Light.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Party.Receivers 4 | { 5 | public class Light 6 | { 7 | private readonly string _location; 8 | private int _level; 9 | 10 | public Light(string location) 11 | { 12 | _location = location; 13 | } 14 | 15 | public void On() 16 | { 17 | _level = 100; 18 | Console.WriteLine(_location + " light is on"); 19 | } 20 | 21 | public void Off() 22 | { 23 | _level = 0; 24 | Console.WriteLine(_location + " light is off"); 25 | } 26 | 27 | public void Dim(int level) 28 | { 29 | _level = level; 30 | if (level == 0) 31 | { 32 | Off(); 33 | } 34 | else 35 | { 36 | Console.WriteLine("Light is dimmed to " + level + "%"); 37 | } 38 | } 39 | 40 | public int GetLevel() => _level; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/command/Party/Receivers/Stereo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Party.Receivers 4 | { 5 | public class Stereo 6 | { 7 | private readonly string _location; 8 | 9 | public Stereo(string location) 10 | { 11 | _location = location; 12 | } 13 | 14 | public void On() => Console.WriteLine(_location + " stereo is on"); 15 | 16 | public void Off() => Console.WriteLine(_location + " stereo is off"); 17 | 18 | public void SetCD() => Console.WriteLine(_location + " stereo is set for CD input"); 19 | 20 | public void SetDVD() => Console.WriteLine(_location + " stereo is set for DVD input"); 21 | 22 | public void SetRadio() => Console.WriteLine(_location + " stereo is set for Radio"); 23 | 24 | // code to set the volume 25 | // valid range: 1-11 (after all 11 is better than 10, right?) 26 | public void SetVolume(int volume) => Console.WriteLine(_location + " stereo volume set to " + volume); 27 | } 28 | } -------------------------------------------------------------------------------- /src/command/Party/Receivers/TV.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Party.Receivers 4 | { 5 | public class TV 6 | { 7 | private readonly string _location; 8 | private int _channel; 9 | 10 | public TV(string location) 11 | { 12 | _location = location; 13 | } 14 | 15 | public void On() => Console.WriteLine(_location + " TV is on"); 16 | 17 | public void Off() => Console.WriteLine(_location + " TV is off"); 18 | 19 | public void SetInputChannel() 20 | { 21 | _channel = 3; 22 | Console.WriteLine(_location + " TV channel is set for DVD"); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/command/README.md: -------------------------------------------------------------------------------- 1 | **The Command Pattern** encapsulates a request as an object, thereby letting you parameterize other objects with different requests, 2 | queue or log requests, and support undoable oparations. -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/Abstractions/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace RemoteControl.Commands 2 | { 3 | public interface ICommand 4 | { 5 | void Execute(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/CeilingFanOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class CeilingFanOffCommand : ICommand 7 | { 8 | private readonly CeilingFan _ceilingFan; 9 | 10 | public CeilingFanOffCommand(CeilingFan ceilingFan) 11 | { 12 | _ceilingFan = ceilingFan; 13 | } 14 | 15 | public void Execute() => _ceilingFan.Off(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/CeilingFanOnCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class CeilingFanOnCommand : ICommand 7 | { 8 | private readonly CeilingFan _ceilingFan; 9 | 10 | public CeilingFanOnCommand(CeilingFan ceilingFan) 11 | { 12 | _ceilingFan = ceilingFan; 13 | } 14 | 15 | public void Execute() => _ceilingFan.High(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/GarageDoorDownCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class GarageDoorDownCommand : ICommand 7 | { 8 | private readonly GarageDoor _garageDoor; 9 | 10 | public GarageDoorDownCommand(GarageDoor garageDoor) 11 | { 12 | _garageDoor = garageDoor; 13 | } 14 | 15 | public void Execute() => _garageDoor.Down(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/GarageDoorUpCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class GarageDoorUpCommand : ICommand 7 | { 8 | private readonly GarageDoor _garageDoor; 9 | 10 | public GarageDoorUpCommand(GarageDoor garageDoor) 11 | { 12 | _garageDoor = garageDoor; 13 | } 14 | 15 | public void Execute() => _garageDoor.Up(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/HottubOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class HottubOffCommand : ICommand 7 | { 8 | private readonly Hottub _hottub; 9 | 10 | public HottubOffCommand(Hottub hottub) 11 | { 12 | _hottub = hottub; 13 | } 14 | 15 | public void Execute() 16 | { 17 | _hottub.Cool(); 18 | _hottub.Off(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/HottubOnCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class HottubOnCommand : ICommand 7 | { 8 | private readonly Hottub _hottub; 9 | 10 | public HottubOnCommand(Hottub hottub) 11 | { 12 | _hottub = hottub; 13 | } 14 | 15 | public void Execute() 16 | { 17 | _hottub.On(); 18 | _hottub.Heat(); 19 | _hottub.BubblesOn(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/LightOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class LightOffCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | 10 | public LightOffCommand(Light light) 11 | { 12 | _light = light; 13 | } 14 | 15 | public void Execute() => _light.Off(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/LightOnCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class LightOnCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | 10 | public LightOnCommand(Light light) 11 | { 12 | _light = light; 13 | } 14 | 15 | public void Execute() => _light.On(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/LivingroomLightOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class LivingroomLightOffCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | 10 | public LivingroomLightOffCommand(Light light) 11 | { 12 | _light = light; 13 | } 14 | 15 | public void Execute() => _light.Off(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/LivingroomLightOnCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class LivingroomLightOnCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | 10 | public LivingroomLightOnCommand(Light light) 11 | { 12 | _light = light; 13 | } 14 | 15 | public void Execute() => _light.On(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/NoCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using RemoteControl.Commands; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class NoCommand : ICommand 7 | { 8 | public void Execute() {} 9 | } 10 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/StereoOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class StereoOffCommand : ICommand 7 | { 8 | private readonly Stereo _stereo; 9 | 10 | public StereoOffCommand(Stereo stereo) 11 | { 12 | _stereo = stereo; 13 | } 14 | 15 | public void Execute() => _stereo.Off(); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Commands/StereoOnWithCDCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControl.Commands; 2 | using RemoteControl.Receivers; 3 | 4 | namespace RemoteControl.Commands 5 | { 6 | public class StereoOnWithCDCommand : ICommand 7 | { 8 | private readonly Stereo _stereo; 9 | 10 | public StereoOnWithCDCommand(Stereo stereo) 11 | { 12 | _stereo = stereo; 13 | } 14 | 15 | public void Execute() 16 | { 17 | _stereo.On(); 18 | _stereo.SetCD(); 19 | _stereo.SetVolume(11); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Invokers/RemoteControl.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using RemoteControl.Commands; 3 | 4 | namespace RemoteControl.Invokers 5 | { 6 | // 7 | // This is the invoker 8 | // 9 | public class RemoteControl 10 | { 11 | private readonly ICommand[] _onCommands; 12 | private readonly ICommand[] _offCommands; 13 | 14 | public RemoteControl() 15 | { 16 | _onCommands = new ICommand[7]; 17 | _offCommands = new ICommand[7]; 18 | 19 | ICommand noCommand = new NoCommand(); 20 | for (int i = 0; i < 7; i++) 21 | { 22 | _onCommands[i] = noCommand; 23 | _offCommands[i] = noCommand; 24 | } 25 | } 26 | 27 | public void SetCommand(int slot, ICommand onCommand, ICommand offCommand) 28 | { 29 | _onCommands[slot] = onCommand; 30 | _offCommands[slot] = offCommand; 31 | } 32 | 33 | public void OnButtonWasPushed(int slot) 34 | { 35 | _onCommands[slot].Execute(); 36 | } 37 | 38 | public void OffButtonWasPushed(int slot) 39 | { 40 | _offCommands[slot].Execute(); 41 | } 42 | 43 | public override string ToString() 44 | { 45 | var stringBuilder= new StringBuilder(); 46 | stringBuilder.Append("\n------ Remote Control -------\n"); 47 | 48 | for (int i = 0; i < _onCommands.Length; i++) 49 | { 50 | stringBuilder.Append("[slot " + i + "] " + _onCommands[i].GetType().Name + " " + _offCommands[i].GetType().Name + "\n"); 51 | } 52 | 53 | return stringBuilder.ToString(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Receivers/CeilingFan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControl.Receivers 4 | { 5 | public class CeilingFan 6 | { 7 | private readonly string _location; 8 | private int _level; 9 | 10 | public const int HIGH = 2; 11 | public const int MEDIUM = 1; 12 | public const int LOW = 0; 13 | 14 | public CeilingFan(string location) 15 | { 16 | _location = location; 17 | } 18 | 19 | public void High() 20 | { 21 | // turns the ceiling fan on to high 22 | _level = HIGH; 23 | Console.WriteLine(_location + " ceiling fan is on high"); 24 | } 25 | 26 | public void Medium() 27 | { 28 | // turns the ceiling fan on to medium 29 | _level = MEDIUM; 30 | Console.WriteLine(_location + " ceiling fan is on medium"); 31 | } 32 | 33 | public void Low() 34 | { 35 | // turns the ceiling fan on to low 36 | _level = LOW; 37 | Console.WriteLine(_location + " ceiling fan is on low"); 38 | } 39 | 40 | public void Off() 41 | { 42 | // turns the ceiling fan off 43 | _level = 0; 44 | Console.WriteLine(_location + " ceiling fan is off"); 45 | } 46 | 47 | public int GetSpeed() => _level; 48 | } 49 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Receivers/GarageDoor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControl.Receivers 4 | { 5 | public class GarageDoor 6 | { 7 | private readonly string _location; 8 | 9 | public GarageDoor(string location) 10 | { 11 | _location = location; 12 | } 13 | 14 | public void Up() => Console.WriteLine(_location + " garage Door is Open"); 15 | 16 | public void Down() => Console.WriteLine(_location + " garage Door is Closed"); 17 | 18 | public void Stop() => Console.WriteLine(_location + " garage Door is Stopped"); 19 | 20 | public void LightOn() => Console.WriteLine(_location + " garage light is on"); 21 | 22 | public void LightOff() => Console.WriteLine(_location + " garage light is off"); 23 | } 24 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Receivers/Hottub.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControl.Receivers 4 | { 5 | public class Hottub 6 | { 7 | private bool _on; 8 | private int _temperature; 9 | 10 | public void On() => _on = true; 11 | 12 | public void Off() => _on = false; 13 | 14 | public void BubblesOn() 15 | { 16 | if (_on) 17 | { 18 | Console.WriteLine("Hottub is bubbling!"); 19 | } 20 | } 21 | 22 | public void BubblesOff() 23 | { 24 | if (_on) 25 | { 26 | Console.WriteLine("Hottub is not bubbling!"); 27 | } 28 | } 29 | 30 | public void JetsOn() 31 | { 32 | if (_on) 33 | { 34 | Console.WriteLine("Hottub jets are on"); 35 | } 36 | } 37 | 38 | public void JetsOff() 39 | { 40 | if (_on) 41 | { 42 | Console.WriteLine("Hottub jets are off"); 43 | } 44 | } 45 | 46 | public void SetTemperature(int temperature) => _temperature = temperature; 47 | 48 | public void Heat() 49 | { 50 | _temperature = 105; 51 | Console.WriteLine("Hottub is heating to a steaming 105 degrees"); 52 | } 53 | 54 | public void Cool() 55 | { 56 | _temperature = 98; 57 | Console.WriteLine("Hottub is cooling to 98 degrees"); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Receivers/Light.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControl.Receivers 4 | { 5 | public class Light 6 | { 7 | private readonly string _location; 8 | 9 | public Light(string location) 10 | { 11 | _location = location; 12 | } 13 | 14 | public void On() => Console.WriteLine(_location + " light is on"); 15 | 16 | public void Off() => Console.WriteLine(_location + " light is off"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/command/RemoteControl/Receivers/Stereo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControl.Receivers 4 | { 5 | public class Stereo 6 | { 7 | private readonly string _location; 8 | 9 | public Stereo(string location) 10 | { 11 | _location = location; 12 | } 13 | 14 | public void On() => Console.WriteLine(_location + " stereo is on"); 15 | 16 | public void Off() => Console.WriteLine(_location + " stereo is off"); 17 | 18 | public void SetCD() => Console.WriteLine(_location + " stereo is set for CD input"); 19 | 20 | public void SetDVD() => Console.WriteLine(_location + " stereo is set for DVD input"); 21 | 22 | public void SetRadio() => Console.WriteLine(_location + " stereo is set for Radio"); 23 | 24 | public void SetVolume(int volume) => Console.WriteLine(_location + " stereo volume set to " + volume); 25 | } 26 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/Receivers/TV.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControl.Receivers 4 | { 5 | public class TV 6 | { 7 | private string _location; 8 | private int _channel; 9 | 10 | public TV(string location) 11 | { 12 | _location = location; 13 | } 14 | 15 | public void On() => Console.WriteLine("TV is on"); 16 | 17 | public void Off() => Console.WriteLine("TV is off"); 18 | 19 | public void SetInputChannel() 20 | { 21 | _channel = 3; 22 | Console.WriteLine("Channel is set for VCR"); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/command/RemoteControl/RemoteControl.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/Abstractions/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace RemoteControlWithUndo.Commands 2 | { 3 | public interface ICommand 4 | { 5 | void Execute(); 6 | void Undo(); 7 | } 8 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/CeilingFanHighCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class CeilingFanHighCommand : ICommand 7 | { 8 | private readonly CeilingFan _ceilingFan; 9 | private int _prevSpeed; 10 | 11 | public CeilingFanHighCommand(CeilingFan ceilingFan) 12 | { 13 | _ceilingFan = ceilingFan; 14 | } 15 | 16 | public void Execute() 17 | { 18 | _prevSpeed = _ceilingFan.GetSpeed(); 19 | _ceilingFan.High(); 20 | } 21 | 22 | public void Undo() 23 | { 24 | switch (_prevSpeed) 25 | { 26 | case CeilingFan.HIGH: 27 | _ceilingFan.High(); 28 | break; 29 | case CeilingFan.MEDIUM: 30 | _ceilingFan.Medium(); 31 | break; 32 | case CeilingFan.LOW: 33 | _ceilingFan.Low(); 34 | break; 35 | case CeilingFan.OFF: 36 | _ceilingFan.Off(); 37 | break; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/CeilingFanLowCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class CeilingFanLowCommand : ICommand 7 | { 8 | private readonly CeilingFan _ceilingFan; 9 | private int _prevSpeed; 10 | 11 | public CeilingFanLowCommand(CeilingFan ceilingFan) 12 | { 13 | _ceilingFan = ceilingFan; 14 | } 15 | 16 | public void Execute() 17 | { 18 | _prevSpeed = _ceilingFan.GetSpeed(); 19 | _ceilingFan.Low(); 20 | } 21 | 22 | public void Undo() 23 | { 24 | switch (_prevSpeed) 25 | { 26 | case CeilingFan.HIGH: 27 | _ceilingFan.High(); 28 | break; 29 | case CeilingFan.MEDIUM: 30 | _ceilingFan.Medium(); 31 | break; 32 | case CeilingFan.LOW: 33 | _ceilingFan.Low(); 34 | break; 35 | case CeilingFan.OFF: 36 | _ceilingFan.Off(); 37 | break; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/CeilingFanMediumCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class CeilingFanMediumCommand : ICommand 7 | { 8 | private readonly CeilingFan _ceilingFan; 9 | private int _prevSpeed; 10 | 11 | public CeilingFanMediumCommand(CeilingFan ceilingFan) 12 | { 13 | _ceilingFan = ceilingFan; 14 | } 15 | 16 | public void Execute() 17 | { 18 | _prevSpeed = _ceilingFan.GetSpeed(); 19 | _ceilingFan.Medium(); 20 | } 21 | 22 | public void Undo() 23 | { 24 | switch (_prevSpeed) 25 | { 26 | case CeilingFan.HIGH: 27 | _ceilingFan.High(); 28 | break; 29 | case CeilingFan.MEDIUM: 30 | _ceilingFan.Medium(); 31 | break; 32 | case CeilingFan.LOW: 33 | _ceilingFan.Low(); 34 | break; 35 | case CeilingFan.OFF: 36 | _ceilingFan.Off(); 37 | break; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/CeilingFanOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class CeilingFanOffCommand : ICommand 7 | { 8 | private readonly CeilingFan _ceilingFan; 9 | private int _prevSpeed; 10 | 11 | public CeilingFanOffCommand(CeilingFan ceilingFan) 12 | { 13 | _ceilingFan = ceilingFan; 14 | } 15 | 16 | public void Execute() 17 | { 18 | _prevSpeed = _ceilingFan.GetSpeed(); 19 | _ceilingFan.Off(); 20 | } 21 | 22 | public void Undo() 23 | { 24 | switch (_prevSpeed) 25 | { 26 | case CeilingFan.HIGH: 27 | _ceilingFan.High(); 28 | break; 29 | case CeilingFan.MEDIUM: 30 | _ceilingFan.Medium(); 31 | break; 32 | case CeilingFan.LOW: 33 | _ceilingFan.Low(); 34 | break; 35 | case CeilingFan.OFF: 36 | _ceilingFan.Off(); 37 | break; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/DimmerLightOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class DimmerLightOffCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | private int _prevLevel; 10 | 11 | public DimmerLightOffCommand(Light light) 12 | { 13 | _light = light; 14 | _prevLevel = 100; 15 | } 16 | 17 | public void Execute() 18 | { 19 | _prevLevel = _light.GetLevel(); 20 | _light.Off(); 21 | } 22 | 23 | public void Undo() => _light.Dim(_prevLevel); 24 | } 25 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/DimmerLightOnCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class DimmerLightOnCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | private int _prevLevel; 10 | 11 | public DimmerLightOnCommand(Light light) 12 | { 13 | _light = light; 14 | } 15 | 16 | public void Execute() 17 | { 18 | _prevLevel = _light.GetLevel(); 19 | _light.Dim(75); 20 | } 21 | 22 | public void Undo() => _light.Dim(_prevLevel); 23 | } 24 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/LightOffCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class LightOffCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | private int _level; 10 | 11 | public LightOffCommand(Light light) 12 | { 13 | _light = light; 14 | } 15 | 16 | public void Execute() 17 | { 18 | _level = _light.GetLevel(); 19 | _light.Off(); 20 | } 21 | 22 | public void Undo() => _light.Dim(_level); 23 | } 24 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/LightOnCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | using RemoteControlWithUndo.Receivers; 3 | 4 | namespace RemoteControlWithUndo.Commands 5 | { 6 | public class LightOnCommand : ICommand 7 | { 8 | private readonly Light _light; 9 | private int _level; 10 | 11 | public LightOnCommand(Light light) 12 | { 13 | _light = light; 14 | } 15 | 16 | public void Execute() 17 | { 18 | _level = _light.GetLevel(); 19 | _light.On(); 20 | } 21 | 22 | public void Undo() => _light.Dim(_level); 23 | } 24 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Commands/NoCommand.cs: -------------------------------------------------------------------------------- 1 | using RemoteControlWithUndo.Commands; 2 | 3 | namespace RemoteControlWithUndo.Commands 4 | { 5 | public class NoCommand : ICommand 6 | { 7 | public void Execute() {} 8 | public void Undo() {} 9 | } 10 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Receivers/CeilingFan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControlWithUndo.Receivers 4 | { 5 | public class CeilingFan 6 | { 7 | private readonly string _location; 8 | private int _speed; 9 | 10 | public const int HIGH = 3; 11 | public const int MEDIUM = 2; 12 | public const int LOW = 1; 13 | public const int OFF = 0; 14 | 15 | public CeilingFan(string location) 16 | { 17 | _location = location; 18 | } 19 | 20 | public void High() 21 | { 22 | // turns the ceiling fan on to high 23 | _speed = HIGH; 24 | Console.WriteLine(_location + " ceiling fan is on high"); 25 | } 26 | 27 | public void Medium() 28 | { 29 | // turns the ceiling fan on to medium 30 | _speed = MEDIUM; 31 | Console.WriteLine(_location + " ceiling fan is on medium"); 32 | } 33 | 34 | public void Low() 35 | { 36 | // turns the ceiling fan on to low 37 | _speed = LOW; 38 | Console.WriteLine(_location + " ceiling fan is on low"); 39 | } 40 | 41 | public void Off() 42 | { 43 | // turns the ceiling fan off 44 | _speed = OFF; 45 | Console.WriteLine(_location + " ceiling fan is off"); 46 | } 47 | 48 | public int GetSpeed() => _speed; 49 | } 50 | } -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/Receivers/Light.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RemoteControlWithUndo.Receivers 4 | { 5 | public class Light 6 | { 7 | private readonly string _location; 8 | private int _level; 9 | 10 | public Light(string location) 11 | { 12 | _location = location; 13 | } 14 | 15 | public void On() 16 | { 17 | _level = 100; 18 | Console.WriteLine(_location + " light is on"); 19 | } 20 | 21 | public void Off() 22 | { 23 | _level = 0; 24 | Console.WriteLine(_location + " light is off"); 25 | } 26 | 27 | public void Dim(int level) 28 | { 29 | _level = level; 30 | if (level == 0) 31 | { 32 | Off(); 33 | } 34 | else 35 | { 36 | Console.WriteLine("Light is dimmed to " + level + "%"); 37 | } 38 | } 39 | 40 | public int GetLevel() => _level; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/command/RemoteControlWithUndo/RemoteControlWithUndo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Commands/Abstractions/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace SimpleRemoteControl.Commands 2 | { 3 | public interface ICommand 4 | { 5 | void Execute(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Commands/GarageDoorOpenCommand.cs: -------------------------------------------------------------------------------- 1 | using SimpleRemoteControl.Receivers; 2 | 3 | namespace SimpleRemoteControl.Commands 4 | { 5 | public class GarageDoorOpenCommand : ICommand 6 | { 7 | private readonly GarageDoor _garageDoor; 8 | 9 | public GarageDoorOpenCommand(GarageDoor garageDoor) 10 | { 11 | _garageDoor = garageDoor; 12 | } 13 | 14 | public void Execute() => _garageDoor.Up(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Commands/LightOffCommand.cs: -------------------------------------------------------------------------------- 1 | using SimpleRemoteControl.Receivers; 2 | 3 | namespace SimpleRemoteControl.Commands 4 | { 5 | public class LightOffCommand : ICommand 6 | { 7 | private readonly Light _light; 8 | 9 | public LightOffCommand(Light light) 10 | { 11 | _light = light; 12 | } 13 | 14 | public void Execute() => _light.Off(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Commands/LightOnCommand.cs: -------------------------------------------------------------------------------- 1 | using SimpleRemoteControl.Receivers; 2 | 3 | namespace SimpleRemoteControl.Commands 4 | { 5 | public class LightOnCommand : ICommand 6 | { 7 | private readonly Light _light; 8 | 9 | public LightOnCommand(Light light) 10 | { 11 | _light = light; 12 | } 13 | 14 | public void Execute() => _light.On(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Invokers/SimpleRemoteControl.cs: -------------------------------------------------------------------------------- 1 | using SimpleRemoteControl.Commands; 2 | 3 | namespace SimpleRemoteControl.Invokers 4 | { 5 | //This is our invoker 6 | public class SimpleRemoteControl 7 | { 8 | private ICommand _slot; 9 | 10 | public void SetCommand(ICommand command) => _slot = command; 11 | 12 | public void ButtonWasPressed() => _slot.Execute(); 13 | } 14 | } -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SimpleRemoteControl.Commands; 3 | using SimpleRemoteControl.Receivers; 4 | 5 | namespace SimpleRemoteControl 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | var remote = new Invokers.SimpleRemoteControl(); 12 | 13 | var light = new Light(); 14 | var garageDoor = new GarageDoor(); 15 | 16 | var lightOn = new LightOnCommand(light); 17 | var garageOpen = new GarageDoorOpenCommand(garageDoor); 18 | 19 | remote.SetCommand(lightOn); 20 | remote.ButtonWasPressed(); 21 | 22 | remote.SetCommand(garageOpen); 23 | remote.ButtonWasPressed(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Receivers/GarageDoor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SimpleRemoteControl.Receivers 4 | { 5 | public class GarageDoor 6 | { 7 | public void Up() => Console.WriteLine("Garage Door is Open"); 8 | 9 | public void Down() => Console.WriteLine("Garage Door is Closed"); 10 | 11 | public void Stop() => Console.WriteLine("Garage Door is Stopped"); 12 | 13 | public void LightOn() => Console.WriteLine("Garage light is on"); 14 | 15 | public void LightOff() => Console.WriteLine("Garage light is off"); 16 | } 17 | } -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/Receivers/Light.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SimpleRemoteControl.Receivers 4 | { 5 | public class Light 6 | { 7 | public void On() => Console.WriteLine("Light is on"); 8 | 9 | public void Off() => Console.WriteLine("Light is off"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/command/SimpleRemoteControl/SimpleRemoteControl.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/composite/Menu/Menu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Menu 5 | { 6 | public class Menu : MenuComponent 7 | { 8 | private readonly List _menuComponents = new List(); 9 | 10 | public Menu(string name, string description) 11 | { 12 | Name = name; 13 | Description = description; 14 | } 15 | 16 | public override string Name { get; } 17 | 18 | public override string Description { get; } 19 | 20 | public override void Add(MenuComponent menuComponent) 21 | { 22 | _menuComponents.Add(menuComponent); 23 | } 24 | 25 | public override void Remove(MenuComponent menuComponent) 26 | { 27 | _menuComponents.Remove(menuComponent); 28 | } 29 | 30 | public override MenuComponent GetChild(int i) 31 | { 32 | return _menuComponents[i]; 33 | } 34 | 35 | public override void Print() 36 | { 37 | Console.Write("\n" + Name); 38 | Console.WriteLine(", " + Description); 39 | Console.WriteLine("---------------------"); 40 | 41 | var iterator = _menuComponents.GetEnumerator(); 42 | while (iterator.MoveNext()) 43 | { 44 | MenuComponent menuComponent = iterator.Current; 45 | menuComponent?.Print(); 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/composite/Menu/Menu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/composite/Menu/MenuComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Menu 4 | { 5 | public abstract class MenuComponent 6 | { 7 | public virtual string Name 8 | { 9 | get 10 | { 11 | throw new NotImplementedException(); 12 | } 13 | } 14 | 15 | public virtual string Description 16 | { 17 | get 18 | { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | 23 | public virtual decimal Price 24 | { 25 | get 26 | { 27 | throw new NotImplementedException(); 28 | } 29 | } 30 | 31 | public virtual bool IsVegetarian 32 | { 33 | get 34 | { 35 | throw new NotImplementedException(); 36 | } 37 | } 38 | 39 | public virtual void Add(MenuComponent menuComponent) 40 | { 41 | throw new NotImplementedException(); 42 | } 43 | 44 | public virtual void Remove(MenuComponent menuComponent) 45 | { 46 | throw new NotImplementedException(); 47 | } 48 | public virtual MenuComponent GetChild(int i) 49 | { 50 | throw new NotImplementedException(); 51 | } 52 | 53 | public virtual void Print() 54 | { 55 | throw new NotImplementedException(); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/composite/Menu/MenuItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace Menu 5 | { 6 | public class MenuItem : MenuComponent 7 | { 8 | public MenuItem(string name, string description, bool vegetarian, decimal price) 9 | { 10 | Name = name; 11 | Description = description; 12 | IsVegetarian = vegetarian; 13 | Price = price; 14 | } 15 | 16 | public override string Name { get; } 17 | public override string Description { get; } 18 | public override bool IsVegetarian { get; } 19 | public override decimal Price { get; } 20 | 21 | public override void Print() 22 | { 23 | Console.Write(" " + Name); 24 | if (IsVegetarian) 25 | { 26 | Console.Write("(v)"); 27 | } 28 | Console.WriteLine(", " + Price.ToString(CultureInfo.InvariantCulture)); 29 | Console.WriteLine(" --" + Description); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/composite/Menu/Waitress.cs: -------------------------------------------------------------------------------- 1 | namespace Menu 2 | { 3 | public class Waitress 4 | { 5 | private readonly MenuComponent _allMenus; 6 | 7 | public Waitress(MenuComponent allMenus) 8 | { 9 | _allMenus = allMenus; 10 | } 11 | 12 | public void PrintMenu() 13 | { 14 | _allMenus.Print(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/composite/MenuIterator/CompositeIterator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace MenuIterator 6 | { 7 | public class CompositeIterator : IEnumerator 8 | { 9 | private readonly IEnumerator _iterator; 10 | private readonly Stack> _stack = new Stack>(); 11 | private MenuComponent _current; 12 | 13 | public CompositeIterator(IEnumerator iterator) 14 | { 15 | _iterator = iterator; 16 | _stack.Push(iterator); 17 | } 18 | 19 | public void Dispose() 20 | { 21 | } 22 | 23 | public bool MoveNext() 24 | { 25 | if (!_stack.Any()) 26 | { 27 | _current = null; 28 | return false; 29 | } 30 | 31 | var iterator = _stack.Peek(); 32 | if (!iterator.MoveNext()) 33 | { 34 | _stack.Pop(); 35 | return MoveNext(); 36 | } 37 | 38 | _current = iterator.Current; 39 | 40 | if (_current is Menu) 41 | { 42 | _stack.Push(_current.CreateIterator()); 43 | } 44 | 45 | return true; 46 | } 47 | 48 | public void Reset() 49 | { 50 | _current = null; 51 | _stack.Clear(); 52 | _stack.Push(_iterator); 53 | } 54 | 55 | public MenuComponent Current => _current; 56 | 57 | object IEnumerator.Current => Current; 58 | } 59 | } -------------------------------------------------------------------------------- /src/composite/MenuIterator/Menu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MenuIterator 5 | { 6 | public class Menu : MenuComponent 7 | { 8 | private readonly List _menuComponents = new List(); 9 | private CompositeIterator _iterator; 10 | 11 | public Menu(string name, string description) 12 | { 13 | Name = name; 14 | Description = description; 15 | } 16 | 17 | public override string Name { get; } 18 | 19 | public override string Description { get; } 20 | 21 | public override void Add(MenuComponent menuComponent) 22 | { 23 | _menuComponents.Add(menuComponent); 24 | } 25 | 26 | public override void Remove(MenuComponent menuComponent) 27 | { 28 | _menuComponents.Remove(menuComponent); 29 | } 30 | 31 | public override MenuComponent GetChild(int i) 32 | { 33 | return _menuComponents[i]; 34 | } 35 | 36 | public override IEnumerator CreateIterator() 37 | { 38 | return _iterator ?? (_iterator = new CompositeIterator(_menuComponents.GetEnumerator())); 39 | } 40 | 41 | public override void Print() 42 | { 43 | Console.Write("\n" + Name); 44 | Console.WriteLine(", " + Description); 45 | Console.WriteLine("---------------------"); 46 | 47 | var iterator = _menuComponents.GetEnumerator(); 48 | while (iterator.MoveNext()) 49 | { 50 | MenuComponent menuComponent = iterator.Current; 51 | menuComponent?.Print(); 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/composite/MenuIterator/MenuComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MenuIterator 5 | { 6 | public abstract class MenuComponent 7 | { 8 | public virtual string Name 9 | { 10 | get 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | } 15 | 16 | public virtual string Description 17 | { 18 | get 19 | { 20 | throw new NotImplementedException(); 21 | } 22 | } 23 | 24 | public virtual decimal Price 25 | { 26 | get 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | } 31 | 32 | public virtual bool IsVegetarian 33 | { 34 | get 35 | { 36 | throw new NotImplementedException(); 37 | } 38 | } 39 | 40 | public virtual void Add(MenuComponent menuComponent) 41 | { 42 | throw new NotImplementedException(); 43 | } 44 | 45 | public virtual void Remove(MenuComponent menuComponent) 46 | { 47 | throw new NotImplementedException(); 48 | } 49 | public virtual MenuComponent GetChild(int i) 50 | { 51 | throw new NotImplementedException(); 52 | } 53 | 54 | public abstract IEnumerator CreateIterator(); 55 | 56 | public virtual void Print() 57 | { 58 | throw new NotImplementedException(); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/composite/MenuIterator/MenuItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | 5 | namespace MenuIterator 6 | { 7 | public class MenuItem : MenuComponent 8 | { 9 | public MenuItem(string name, string description, bool vegetarian, decimal price) 10 | { 11 | Name = name; 12 | Description = description; 13 | IsVegetarian = vegetarian; 14 | Price = price; 15 | } 16 | 17 | public override string Name { get; } 18 | public override string Description { get; } 19 | public override bool IsVegetarian { get; } 20 | public override decimal Price { get; } 21 | 22 | public override IEnumerator CreateIterator() 23 | { 24 | return new NullIterator(); 25 | } 26 | 27 | public override void Print() 28 | { 29 | Console.Write(" " + Name); 30 | if (IsVegetarian) 31 | { 32 | Console.Write("(v)"); 33 | } 34 | Console.WriteLine(", " + Price.ToString(CultureInfo.InvariantCulture)); 35 | Console.WriteLine(" --" + Description); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/composite/MenuIterator/MenuIterator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/composite/MenuIterator/NullIterator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace MenuIterator 5 | { 6 | public class NullIterator : IEnumerator 7 | { 8 | public void Dispose() { } 9 | 10 | public bool MoveNext() => false; 11 | 12 | public void Reset() { } 13 | 14 | public MenuComponent Current => null; 15 | 16 | object IEnumerator.Current => Current; 17 | } 18 | } -------------------------------------------------------------------------------- /src/composite/MenuIterator/Waitress.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MenuIterator 4 | { 5 | public class Waitress 6 | { 7 | private readonly MenuComponent _allMenus; 8 | 9 | public Waitress(MenuComponent allMenus) 10 | { 11 | _allMenus = allMenus; 12 | } 13 | 14 | public void PrintMenu() 15 | { 16 | _allMenus.Print(); 17 | } 18 | 19 | public void PrintVegetarianMenu() 20 | { 21 | var iterator = _allMenus.CreateIterator(); 22 | 23 | Console.WriteLine("\nVEGETARIAN MENU\n----"); 24 | while (iterator.MoveNext()) 25 | { 26 | MenuComponent menuComponent = iterator.Current; 27 | try 28 | { 29 | if (menuComponent.IsVegetarian) 30 | { 31 | menuComponent.Print(); 32 | } 33 | } 34 | catch (NotImplementedException) { } 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/composite/README.md: -------------------------------------------------------------------------------- 1 | **The Composite Pattern** allows you to compose objects into tree structures to represent part-whole hierarchies. 2 | Composite lets clients treat individual objects and compositions of objects uniformly. -------------------------------------------------------------------------------- /src/decorator/README.md: -------------------------------------------------------------------------------- 1 | **The Decorator Pattern** attaches additional responsibilities to an object dynamically. 2 | Decorators provide a flexible alternative to subclassing for extending functionality. -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Components/Abstractions/Beverage.cs: -------------------------------------------------------------------------------- 1 | namespace StarbuzzCoffee.Components 2 | { 3 | public abstract class Beverage 4 | { 5 | public virtual string Description { get; protected set; } = "Unknown Beverage"; 6 | 7 | public abstract double Cost(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Components/DarkRoast.cs: -------------------------------------------------------------------------------- 1 | using StarbuzzCoffee.Components; 2 | 3 | namespace StarbuzzCoffee.Components 4 | { 5 | public class DarkRoast : Beverage 6 | { 7 | public DarkRoast() 8 | { 9 | Description = "Dark Roast Coffee"; 10 | } 11 | 12 | public override double Cost() 13 | { 14 | return .99; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Components/Espresso.cs: -------------------------------------------------------------------------------- 1 | using StarbuzzCoffee.Components; 2 | 3 | namespace StarbuzzCoffee.Components 4 | { 5 | public class Espresso : Beverage 6 | { 7 | public Espresso() 8 | { 9 | Description = "Espresso"; 10 | } 11 | 12 | public override double Cost() 13 | { 14 | return 1.99; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Components/HouseBlend.cs: -------------------------------------------------------------------------------- 1 | using StarbuzzCoffee.Components; 2 | 3 | namespace StarbuzzCoffee.Components 4 | { 5 | public class HouseBlend : Beverage 6 | { 7 | public HouseBlend() 8 | { 9 | Description = "House Blend Coffee"; 10 | } 11 | 12 | public override double Cost() 13 | { 14 | return .89; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Decorators/Abstractions/CondimentDecorator.cs: -------------------------------------------------------------------------------- 1 | using StarbuzzCoffee.Components; 2 | 3 | namespace StarbuzzCoffee.Decorators 4 | { 5 | public abstract class CondimentDecorator : Beverage 6 | { 7 | public abstract override string Description { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Decorators/Mocha.cs: -------------------------------------------------------------------------------- 1 | using StarbuzzCoffee.Components; 2 | using StarbuzzCoffee.Decorators; 3 | 4 | namespace StarbuzzCoffee.Decorators 5 | { 6 | public class Mocha : CondimentDecorator 7 | { 8 | private readonly Beverage _beverage; 9 | 10 | public Mocha(Beverage beverage) 11 | { 12 | _beverage = beverage; 13 | } 14 | 15 | public override string Description => _beverage.Description + ", Mocha"; 16 | 17 | public override double Cost() 18 | { 19 | return .20 + _beverage.Cost(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Decorators/Soy.cs: -------------------------------------------------------------------------------- 1 | using StarbuzzCoffee.Components; 2 | using StarbuzzCoffee.Decorators; 3 | 4 | namespace StarbuzzCoffee.Decorators 5 | { 6 | public class Soy : CondimentDecorator 7 | { 8 | private readonly Beverage _beverage; 9 | 10 | public Soy(Beverage beverage) 11 | { 12 | _beverage = beverage; 13 | } 14 | 15 | public override double Cost() 16 | { 17 | return .15 + _beverage.Cost(); 18 | } 19 | 20 | public override string Description => _beverage.Description + ", Soy"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Decorators/Whip.cs: -------------------------------------------------------------------------------- 1 | using StarbuzzCoffee.Components; 2 | using StarbuzzCoffee.Decorators; 3 | 4 | namespace StarbuzzCoffee.Decorators 5 | { 6 | public class Whip : CondimentDecorator 7 | { 8 | private readonly Beverage _beverage; 9 | 10 | public Whip(Beverage beverage) 11 | { 12 | _beverage = beverage; 13 | } 14 | 15 | public override double Cost() 16 | { 17 | return .10 + _beverage.Cost(); 18 | } 19 | 20 | public override string Description => _beverage.Description + ", Whip"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StarbuzzCoffee.Components; 3 | using StarbuzzCoffee.Decorators; 4 | 5 | namespace StarbuzzCoffee 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | Beverage beverage = new Espresso(); 12 | Console.WriteLine(beverage.Description + " $" + beverage.Cost()); 13 | 14 | Beverage beverage2 = new DarkRoast(); 15 | beverage2 = new Mocha(beverage2); 16 | beverage2 = new Mocha(beverage2); 17 | beverage2 = new Whip(beverage2); 18 | Console.WriteLine(beverage2.Description + " $" + beverage2.Cost()); 19 | 20 | Beverage beverage3 = new HouseBlend(); 21 | beverage3 = new Soy(beverage3); 22 | beverage3 = new Mocha(beverage3); 23 | beverage3 = new Whip(beverage3); 24 | Console.WriteLine(beverage3.Description + " $" + beverage3.Cost()); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee/StarbuzzCoffee.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/facade/HomeTheater/HomeTheater.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/facade/HomeTheater/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace HomeTheater 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | var amp = new Amplifier("Top-O-Line Amplifier"); 11 | var tuner = new Tuner("Top-O-Line AM/FM Tuner", amp); 12 | var dvd = new DvdPlayer("Top-O-Line DVD Player", amp); 13 | var cd = new CdPlayer("Top-O-Line CD Player", amp); 14 | var projector = new Projector("Top-O-Line Projector", dvd); 15 | var lights = new TheaterLights("Theater Ceiling Lights"); 16 | var screen = new Screen("Theater Screen"); 17 | var popper = new PopcornPopper("Popcorn Popper"); 18 | 19 | var homeTheater = new HomeTheaterFacade(amp, tuner, dvd, cd, projector, screen, lights, popper); 20 | 21 | homeTheater.WatchMovie("Raiders of the Lost Ark"); 22 | homeTheater.EndMovie(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/facade/HomeTheater/Subsystems/PopcornPopper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HomeTheater 4 | { 5 | public class PopcornPopper 6 | { 7 | private readonly string _description; 8 | 9 | public PopcornPopper(string description) 10 | { 11 | _description = description; 12 | } 13 | 14 | public void On() 15 | { 16 | Console.WriteLine($"{_description} on"); 17 | } 18 | 19 | public void Off() 20 | { 21 | Console.WriteLine($"{_description} off"); 22 | } 23 | 24 | public void Pop() 25 | { 26 | Console.WriteLine($"{_description} popping popcorn!"); 27 | } 28 | 29 | public override string ToString() 30 | { 31 | return _description; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/facade/HomeTheater/Subsystems/Projector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HomeTheater 4 | { 5 | public class Projector 6 | { 7 | private readonly string _description; 8 | private readonly DvdPlayer _dvdPlayer; 9 | 10 | public Projector(string description, DvdPlayer dvdPlayer) 11 | { 12 | _description = description; 13 | _dvdPlayer = dvdPlayer; 14 | } 15 | 16 | public void On() 17 | { 18 | Console.WriteLine($"{_description} on"); 19 | } 20 | 21 | public void Off() 22 | { 23 | Console.WriteLine($"{_description} off"); 24 | } 25 | 26 | public void WideScreenMode() 27 | { 28 | Console.WriteLine($"{_description} in widescreen mode (16x9 aspect ratio)"); 29 | } 30 | 31 | public void TvMode() 32 | { 33 | Console.WriteLine($"{_description} in tv mode (4x3 aspect ratio)"); 34 | } 35 | 36 | public override string ToString() 37 | { 38 | return _description; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/facade/HomeTheater/Subsystems/Screen.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HomeTheater 4 | { 5 | public class Screen 6 | { 7 | private readonly string _description; 8 | 9 | public Screen(string description) 10 | { 11 | _description = description; 12 | } 13 | 14 | public void Up() 15 | { 16 | Console.WriteLine($"{_description} going up"); 17 | } 18 | 19 | public void Down() 20 | { 21 | Console.WriteLine($"{_description} going down"); 22 | } 23 | 24 | public override string ToString() 25 | { 26 | return _description; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/facade/HomeTheater/Subsystems/TheaterLights.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HomeTheater 4 | { 5 | public class TheaterLights 6 | { 7 | private readonly string _description; 8 | 9 | public TheaterLights(string description) 10 | { 11 | _description = description; 12 | } 13 | 14 | public void On() 15 | { 16 | Console.WriteLine($"{_description} on"); 17 | } 18 | 19 | public void Off() 20 | { 21 | Console.WriteLine($"{_description} off"); 22 | } 23 | 24 | public void Dim(int level) 25 | { 26 | Console.WriteLine($"{_description} dimming to {level.ToString()}%"); 27 | } 28 | 29 | public override string ToString() 30 | { 31 | return _description; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/facade/HomeTheater/Subsystems/Tuner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace HomeTheater 5 | { 6 | public class Tuner 7 | { 8 | private readonly string _description; 9 | private readonly Amplifier _amplifier; 10 | private double _frequency; 11 | 12 | public Tuner(string description, Amplifier amplifier) 13 | { 14 | _description = description; 15 | _amplifier = amplifier; 16 | } 17 | 18 | public void On() 19 | { 20 | Console.WriteLine($"{_description} on"); 21 | } 22 | 23 | public void Off() 24 | { 25 | Console.WriteLine($"{_description} off"); 26 | } 27 | 28 | public void SetFrequency(double frequency) 29 | { 30 | Console.WriteLine($"{_description} setting frequency to {frequency.ToString(CultureInfo.InvariantCulture)}"); 31 | _frequency = frequency; 32 | } 33 | 34 | public void SetAm() 35 | { 36 | Console.WriteLine($"{_description} setting AM mode"); 37 | } 38 | 39 | public void SetFm() 40 | { 41 | Console.WriteLine($"{_description} setting FM mode"); 42 | } 43 | 44 | public override string ToString() 45 | { 46 | return _description; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/facade/README.md: -------------------------------------------------------------------------------- 1 | **The Facade Pattern** provides a unified interface to a set of interfaces in a subsystem. 2 | Facade defines a higher-level interface that makes the subsystem easier to use. -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/AbstractFactories/Abstractions/IPizzaIngredientFactory.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreAbstractFactory.Products.Ingredients; 2 | 3 | namespace PizzaStoreAbstractFactory.AbstractFactories 4 | { 5 | public interface IPizzaIngredientFactory 6 | { 7 | IDough CreateDough(); 8 | ISauce CreateSauce(); 9 | ICheese CreateCheese(); 10 | IVeggies[] CreateVeggies(); 11 | IPepperoni CreatePepperoni(); 12 | IClams CreateClam(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/AbstractFactories/ChicagoPizzaIngredientFactory.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreAbstractFactory.Products.Ingredients; 2 | 3 | namespace PizzaStoreAbstractFactory.AbstractFactories 4 | { 5 | public class ChicagoPizzaIngredientFactory : IPizzaIngredientFactory 6 | { 7 | public ICheese CreateCheese() 8 | { 9 | return new MozzarellaCheese(); 10 | } 11 | 12 | public IClams CreateClam() 13 | { 14 | return new FrozenClams(); 15 | } 16 | 17 | public IDough CreateDough() 18 | { 19 | return new ThickCrustDough(); 20 | } 21 | 22 | public IPepperoni CreatePepperoni() 23 | { 24 | return new SlicedPepperoni(); 25 | } 26 | 27 | public ISauce CreateSauce() 28 | { 29 | return new PlumTomatoSauce(); 30 | } 31 | 32 | public IVeggies[] CreateVeggies() 33 | { 34 | IVeggies[] veggies = { new BlackOlives(), new Spinach(), new Eggplant() }; 35 | return veggies; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/AbstractFactories/NYPizzaIngredientFactory.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreAbstractFactory.Products.Ingredients; 2 | 3 | namespace PizzaStoreAbstractFactory.AbstractFactories 4 | { 5 | public class NYPizzaIngredientFactory : IPizzaIngredientFactory 6 | { 7 | public ICheese CreateCheese() 8 | { 9 | return new ReggianoCheese(); 10 | } 11 | 12 | public IClams CreateClam() 13 | { 14 | return new FreshClams(); 15 | } 16 | 17 | public IDough CreateDough() 18 | { 19 | return new ThinCrustDough(); 20 | } 21 | 22 | public IPepperoni CreatePepperoni() 23 | { 24 | return new SlicedPepperoni(); 25 | } 26 | 27 | public ISauce CreateSauce() 28 | { 29 | return new MarinaraSauce(); 30 | } 31 | 32 | public IVeggies[] CreateVeggies() 33 | { 34 | IVeggies[] veggies = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() }; 35 | return veggies; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/FactoryMethods/Abstractions/PizzaStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreAbstractFactory.Products.Pizzas; 3 | 4 | namespace PizzaStoreAbstractFactory.FactoryMethods 5 | { 6 | public abstract class PizzaStore 7 | { 8 | protected abstract Pizza CreatePizza(string item); 9 | 10 | public Pizza OrderPizza(string type) 11 | { 12 | Pizza pizza = CreatePizza(type); 13 | Console.WriteLine("--- Making a " + pizza.Name + " ---"); 14 | pizza.Prepare(); 15 | pizza.Bake(); 16 | pizza.Cut(); 17 | pizza.Box(); 18 | return pizza; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/FactoryMethods/ChicagoPizzaStore.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreAbstractFactory.AbstractFactories; 2 | using PizzaStoreAbstractFactory.Products.Pizzas; 3 | 4 | namespace PizzaStoreAbstractFactory.FactoryMethods 5 | { 6 | public class ChicagoPizzaStore : PizzaStore 7 | { 8 | protected override Pizza CreatePizza(string item) 9 | { 10 | Pizza pizza = null; 11 | IPizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory(); 12 | 13 | switch (item) 14 | { 15 | case "cheese": 16 | pizza = new CheesePizza(ingredientFactory) { Name = "Chicago Style Cheese Pizza" }; 17 | break; 18 | case "veggie": 19 | pizza = new VeggiePizza(ingredientFactory) { Name = "Chicago Style Veggie Pizza" }; 20 | break; 21 | case "clam": 22 | pizza = new ClamPizza(ingredientFactory) { Name = "Chicago Style Clam Pizza" }; 23 | break; 24 | case "pepperoni": 25 | pizza = new PepperoniPizza(ingredientFactory) { Name = "Chicago Style Pepperoni Pizza" }; 26 | break; 27 | } 28 | 29 | return pizza; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/FactoryMethods/NYPizzaStore.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreAbstractFactory.AbstractFactories; 2 | using PizzaStoreAbstractFactory.Products.Pizzas; 3 | 4 | namespace PizzaStoreAbstractFactory.FactoryMethods 5 | { 6 | public class NYPizzaStore : PizzaStore 7 | { 8 | protected override Pizza CreatePizza(string item) 9 | { 10 | Pizza pizza = null; 11 | IPizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory(); 12 | 13 | switch (item) 14 | { 15 | case "cheese": 16 | pizza = new CheesePizza(ingredientFactory) { Name = "New York Style Cheese Pizza" }; 17 | break; 18 | case "veggie": 19 | pizza = new VeggiePizza(ingredientFactory) { Name = "New York Style Veggie Pizza" }; 20 | break; 21 | case "clam": 22 | pizza = new ClamPizza(ingredientFactory) { Name = "New York Style Clam Pizza" }; 23 | break; 24 | case "pepperoni": 25 | pizza = new PepperoniPizza(ingredientFactory) { Name = "New York Style Pepperoni Pizza" }; 26 | break; 27 | } 28 | 29 | return pizza; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/PizzaStoreAbstractFactory.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Abstractions/ICheese.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public interface ICheese 4 | { 5 | string ToString(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Abstractions/IClams.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public interface IClams 4 | { 5 | string ToString(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Abstractions/IDough.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public interface IDough 4 | { 5 | string ToString(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Abstractions/IPepperoni.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public interface IPepperoni 4 | { 5 | string ToString(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Abstractions/ISauce.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public interface ISauce 4 | { 5 | string ToString(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Abstractions/IVeggies.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public interface IVeggies 4 | { 5 | string ToString(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/BlackOlives.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class BlackOlives : IVeggies 4 | { 5 | string IVeggies.ToString() 6 | { 7 | return "Black Olives"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Eggplant.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class Eggplant : IVeggies 4 | { 5 | string IVeggies.ToString() 6 | { 7 | return "Eggplant"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/FreshClams.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class FreshClams : IClams 4 | { 5 | string IClams.ToString() 6 | { 7 | return "Fresh Clams from Long Island Sound"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/FrozenClams.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class FrozenClams : IClams 4 | { 5 | string IClams.ToString() 6 | { 7 | return "Frozen Clams from Chesapeake Bay"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Garlic.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class Garlic : IVeggies 4 | { 5 | string IVeggies.ToString() 6 | { 7 | return "Garlic"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/MarinaraSauce.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class MarinaraSauce : ISauce 4 | { 5 | string ISauce.ToString() 6 | { 7 | return "Marinara Sauce"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/MozzarellaCheese.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class MozzarellaCheese : ICheese 4 | { 5 | string ICheese.ToString() 6 | { 7 | return "MozzarellaCheese"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Mushroom.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class Mushroom : IVeggies 4 | { 5 | string IVeggies.ToString() 6 | { 7 | return "Mushrooms"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Onion.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class Onion : IVeggies 4 | { 5 | string IVeggies.ToString() 6 | { 7 | return "Onion"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/ParmesanCheese.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class ParmesanCheese : ICheese 4 | { 5 | string ICheese.ToString() 6 | { 7 | return "Shredded Parmesan"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/PlumTomatoSauce.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class PlumTomatoSauce : ISauce 4 | { 5 | string ISauce.ToString() 6 | { 7 | return "Tomato sauce with plum tomatoes"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/RedPepper.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class RedPepper : IVeggies 4 | { 5 | string IVeggies.ToString() 6 | { 7 | return "Red Pepper"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/ReggianoCheese.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class ReggianoCheese : ICheese 4 | { 5 | string ICheese.ToString() 6 | { 7 | return "Reggiano Cheese"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/SlicedPepperoni.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class SlicedPepperoni : IPepperoni 4 | { 5 | string IPepperoni.ToString() 6 | { 7 | return "Sliced Pepperoni"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/Spinach.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class Spinach : IVeggies 4 | { 5 | string IVeggies.ToString() 6 | { 7 | return "Spinach"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/ThickCrustDough.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class ThickCrustDough : IDough 4 | { 5 | string IDough.ToString() 6 | { 7 | return "ThickCrust style extra thick crust dough"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Ingredients/ThinCrustDough.cs: -------------------------------------------------------------------------------- 1 | namespace PizzaStoreAbstractFactory.Products.Ingredients 2 | { 3 | public class ThinCrustDough : IDough 4 | { 5 | string IDough.ToString() 6 | { 7 | return "Thin Crust Dough"; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Pizzas/CheesePizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreAbstractFactory.AbstractFactories; 3 | 4 | namespace PizzaStoreAbstractFactory.Products.Pizzas 5 | { 6 | public class CheesePizza : Pizza 7 | { 8 | private readonly IPizzaIngredientFactory _ingredientFactory; 9 | 10 | public CheesePizza(IPizzaIngredientFactory ingredientFactory) 11 | { 12 | _ingredientFactory = ingredientFactory; 13 | } 14 | 15 | public override void Prepare() 16 | { 17 | Console.WriteLine("Preparing " + Name); 18 | Dough = _ingredientFactory.CreateDough(); 19 | Sauce = _ingredientFactory.CreateSauce(); 20 | Cheese = _ingredientFactory.CreateCheese(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Pizzas/ClamPizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreAbstractFactory.AbstractFactories; 3 | 4 | namespace PizzaStoreAbstractFactory.Products.Pizzas 5 | { 6 | public class ClamPizza : Pizza 7 | { 8 | private readonly IPizzaIngredientFactory _ingredientFactory; 9 | 10 | public ClamPizza(IPizzaIngredientFactory ingredientFactory) 11 | { 12 | _ingredientFactory = ingredientFactory; 13 | } 14 | 15 | public override void Prepare() 16 | { 17 | Console.WriteLine("Preparing " + Name); 18 | Dough = _ingredientFactory.CreateDough(); 19 | Sauce = _ingredientFactory.CreateSauce(); 20 | Cheese = _ingredientFactory.CreateCheese(); 21 | Clam = _ingredientFactory.CreateClam(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Pizzas/PepperoniPizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreAbstractFactory.AbstractFactories; 3 | 4 | namespace PizzaStoreAbstractFactory.Products.Pizzas 5 | { 6 | public class PepperoniPizza : Pizza 7 | { 8 | private readonly IPizzaIngredientFactory _ingredientFactory; 9 | 10 | public PepperoniPizza(IPizzaIngredientFactory ingredientFactory) 11 | { 12 | _ingredientFactory = ingredientFactory; 13 | } 14 | 15 | public override void Prepare() 16 | { 17 | Console.WriteLine("Preparing " + Name); 18 | Dough = _ingredientFactory.CreateDough(); 19 | Sauce = _ingredientFactory.CreateSauce(); 20 | Cheese = _ingredientFactory.CreateCheese(); 21 | Veggies = _ingredientFactory.CreateVeggies(); 22 | Pepperoni = _ingredientFactory.CreatePepperoni(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Products/Pizzas/VeggiePizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreAbstractFactory.AbstractFactories; 3 | 4 | namespace PizzaStoreAbstractFactory.Products.Pizzas 5 | { 6 | public class VeggiePizza : Pizza 7 | { 8 | private readonly IPizzaIngredientFactory _ingredientFactory; 9 | 10 | public VeggiePizza(IPizzaIngredientFactory ingredientFactory) 11 | { 12 | _ingredientFactory = ingredientFactory; 13 | } 14 | 15 | public override void Prepare() 16 | { 17 | Console.WriteLine("Preparing " + Name); 18 | Dough = _ingredientFactory.CreateDough(); 19 | Sauce = _ingredientFactory.CreateSauce(); 20 | Cheese = _ingredientFactory.CreateCheese(); 21 | Veggies = _ingredientFactory.CreateVeggies(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreAbstractFactory/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreAbstractFactory.FactoryMethods; 3 | using PizzaStoreAbstractFactory.Products.Pizzas; 4 | 5 | namespace PizzaStoreAbstractFactory 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | PizzaStore nyStore = new NYPizzaStore(); 12 | PizzaStore chicagoStore = new ChicagoPizzaStore(); 13 | 14 | Pizza pizza = nyStore.OrderPizza("cheese"); 15 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 16 | 17 | pizza = chicagoStore.OrderPizza("cheese"); 18 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 19 | 20 | pizza = nyStore.OrderPizza("clam"); 21 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 22 | 23 | pizza = chicagoStore.OrderPizza("clam"); 24 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 25 | 26 | pizza = nyStore.OrderPizza("pepperoni"); 27 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 28 | 29 | pizza = chicagoStore.OrderPizza("pepperoni"); 30 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 31 | 32 | pizza = nyStore.OrderPizza("veggie"); 33 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 34 | 35 | pizza = chicagoStore.OrderPizza("veggie"); 36 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/FactoryMethods/Abstractions/PizzaStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.FactoryMethods 5 | { 6 | public abstract class PizzaStore 7 | { 8 | protected abstract Pizza CreatePizza(string item); 9 | 10 | public Pizza OrderPizza(string type) 11 | { 12 | Pizza pizza = CreatePizza(type); 13 | Console.WriteLine("--- Making a " + pizza.Name + " ---"); 14 | pizza.Prepare(); 15 | pizza.Bake(); 16 | pizza.Cut(); 17 | pizza.Box(); 18 | return pizza; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/FactoryMethods/ChicagoPizzaStore.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreFactoryMethod.FactoryMethods; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.FactoryMethods 5 | { 6 | public class ChicagoPizzaStore : PizzaStore 7 | { 8 | protected override Pizza CreatePizza(string item) 9 | { 10 | Pizza pizza = null; 11 | 12 | switch (item) 13 | { 14 | case "cheese": 15 | pizza = new ChicagoStyleCheesePizza(); 16 | break; 17 | case "veggie": 18 | pizza = new ChicagoStyleVeggiePizza(); 19 | break; 20 | case "clam": 21 | pizza = new ChicagoStyleClamPizza(); 22 | break; 23 | case "pepperoni": 24 | pizza = new ChicagoStylePepperoniPizza(); 25 | break; 26 | } 27 | 28 | return pizza; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/FactoryMethods/NYPizzaStore.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreFactoryMethod.FactoryMethods; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.FactoryMethods 5 | { 6 | public class NYPizzaStore : PizzaStore 7 | { 8 | protected override Pizza CreatePizza(string item) 9 | { 10 | Pizza pizza = null; 11 | switch (item) 12 | { 13 | case "cheese": 14 | pizza = new NYStyleCheesePizza(); 15 | break; 16 | case "veggie": 17 | pizza = new NYStyleVeggiePizza(); 18 | break; 19 | case "clam": 20 | pizza = new NYStyleClamPizza(); 21 | break; 22 | case "pepperoni": 23 | pizza = new NYStylePepperoniPizza(); 24 | break; 25 | } 26 | 27 | return pizza; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/PizzaStoreFactoryMethod.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/Abstractions/Pizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace PizzaStoreFactoryMethod.Products.Pizzas 6 | { 7 | public abstract class Pizza 8 | { 9 | public string Name { get; protected set; } 10 | public string Dough { get; protected set; } 11 | public string Sauce { get; protected set; } 12 | public List Toppings { get; protected set; } = new List(); 13 | 14 | public virtual void Prepare() 15 | { 16 | Console.WriteLine("Preparing " + Name); 17 | Console.WriteLine("Tossing dough..."); 18 | Console.WriteLine("Adding sauce..."); 19 | Console.WriteLine("Adding toppings: "); 20 | foreach (var topping in Toppings) 21 | { 22 | Console.WriteLine(" " + topping); 23 | } 24 | } 25 | 26 | public virtual void Bake() 27 | { 28 | Console.WriteLine("Bake for 25 minutes at 350"); 29 | } 30 | 31 | public virtual void Cut() 32 | { 33 | Console.WriteLine("Cutting the pizza into diagonal slices"); 34 | } 35 | 36 | public virtual void Box() 37 | { 38 | Console.WriteLine("Place pizza in official PizzaStore box"); 39 | } 40 | 41 | public override string ToString() 42 | { 43 | var result = new StringBuilder(); 44 | 45 | result.AppendLine("---- " + Name + " ----"); 46 | result.AppendLine(Dough); 47 | result.AppendLine(Sauce); 48 | foreach (var topping in Toppings) 49 | { 50 | result.AppendLine(topping); 51 | } 52 | 53 | return result.ToString(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/ChicagoStyleCheesePizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.Products.Pizzas 5 | { 6 | public class ChicagoStyleCheesePizza : Pizza 7 | { 8 | public ChicagoStyleCheesePizza() 9 | { 10 | Name = "Chicago Style Deep Dish Cheese Pizza"; 11 | Dough = "Extra Thick Crust Dough"; 12 | Sauce = "Shredded Mozzarella Cheese"; 13 | 14 | Toppings.Add("Shredded Mozzarella Cheese"); 15 | } 16 | 17 | public override void Cut() 18 | { 19 | Console.WriteLine("Cutting the pizza into square slices"); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/ChicagoStyleClamPizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.Products.Pizzas 5 | { 6 | public class ChicagoStyleClamPizza : Pizza 7 | { 8 | public ChicagoStyleClamPizza() 9 | { 10 | Name = "Chicago Style Clam Pizza"; 11 | Dough = "Extra Thick Crust Dough"; 12 | Sauce = "Plum Tomato Sauce"; 13 | 14 | Toppings.Add("Shredded Mozzarella Cheese"); 15 | Toppings.Add("Frozen Clams from Chesapeake Bay"); 16 | } 17 | 18 | public override void Cut() 19 | { 20 | Console.WriteLine("Cutting the pizza into square slices"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/ChicagoStylePepperoniPizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.Products.Pizzas 5 | { 6 | public class ChicagoStylePepperoniPizza : Pizza 7 | { 8 | public ChicagoStylePepperoniPizza() 9 | { 10 | Name = "Chicago Style Pepperoni Pizza"; 11 | Dough = "Extra Thick Crust Dough"; 12 | Sauce = "Plum Tomato Sauce"; 13 | 14 | Toppings.Add("Shredded Mozzarella Cheese"); 15 | Toppings.Add("Black Olives"); 16 | Toppings.Add("Spinach"); 17 | Toppings.Add("Eggplant"); 18 | Toppings.Add("Sliced Pepperoni"); 19 | } 20 | 21 | public override void Cut() 22 | { 23 | Console.WriteLine("Cutting the pizza into square slices"); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/ChicagoStyleVeggiePizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.Products.Pizzas 5 | { 6 | public class ChicagoStyleVeggiePizza : Pizza 7 | { 8 | public ChicagoStyleVeggiePizza() 9 | { 10 | Name = "Chicago Deep Dish Veggie Pizza"; 11 | Dough = "Extra Thick Crust Dough"; 12 | Sauce = "Plum Tomato Sauce"; 13 | 14 | Toppings.Add("Shredded Mozzarella Cheese"); 15 | Toppings.Add("Black Olives"); 16 | Toppings.Add("Spinach"); 17 | Toppings.Add("Eggplant"); 18 | } 19 | 20 | public override void Cut() 21 | { 22 | Console.WriteLine("Cutting the pizza into square slices"); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/NYStyleCheesePizza.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreFactoryMethod.Products.Pizzas; 2 | 3 | namespace PizzaStoreFactoryMethod.Products.Pizzas 4 | { 5 | public class NYStyleCheesePizza : Pizza 6 | { 7 | public NYStyleCheesePizza() 8 | { 9 | Name = "NY Style Sauce and Cheese Pizza"; 10 | Dough = "Thin Crust Dough"; 11 | Sauce = "Marinara Sauce"; 12 | 13 | Toppings.Add("Grated Reggiano Cheese"); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/NYStyleClamPizza.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreFactoryMethod.Products.Pizzas; 2 | 3 | namespace PizzaStoreFactoryMethod.Products.Pizzas 4 | { 5 | public class NYStyleClamPizza : Pizza 6 | { 7 | public NYStyleClamPizza() 8 | { 9 | Name = "NY Style Clam Pizza"; 10 | Dough = "Thin Crust Dough"; 11 | Sauce = "Marinara Sauce"; 12 | 13 | Toppings.Add("Grated Reggiano Cheese"); 14 | Toppings.Add("Fresh Clams from Long Island Sound"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/NYStylePepperoniPizza.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreFactoryMethod.Products.Pizzas; 2 | 3 | namespace PizzaStoreFactoryMethod.Products.Pizzas 4 | { 5 | public class NYStylePepperoniPizza : Pizza 6 | { 7 | public NYStylePepperoniPizza() 8 | { 9 | Name = "NY Style Pepperoni Pizza"; 10 | Dough = "Thin Crust Dough"; 11 | Sauce = "Marinara Sauce"; 12 | 13 | Toppings.Add("Grated Reggiano Cheese"); 14 | Toppings.Add("Sliced Pepperoni"); 15 | Toppings.Add("Garlic"); 16 | Toppings.Add("Onion"); 17 | Toppings.Add("Mushrooms"); 18 | Toppings.Add("Red Pepper"); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Products/Pizzas/NYStyleVeggiePizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreFactoryMethod.Products.Pizzas; 3 | 4 | namespace PizzaStoreFactoryMethod.Products.Pizzas 5 | { 6 | public class NYStyleVeggiePizza : Pizza 7 | { 8 | public NYStyleVeggiePizza() 9 | { 10 | Name = "NY Style Veggie Pizza"; 11 | Dough = "Thin Crust Dough"; 12 | Sauce = "Marinara Sauce"; 13 | 14 | Toppings.Add("Grated Reggiano Cheese"); 15 | Toppings.Add("Garlic"); 16 | Toppings.Add("Onion"); 17 | Toppings.Add("Mushrooms"); 18 | Toppings.Add("Red Pepper"); 19 | } 20 | 21 | public override void Cut() 22 | { 23 | Console.WriteLine("Cutting the pizza into square slices"); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreFactoryMethod/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreFactoryMethod.FactoryMethods; 3 | using PizzaStoreFactoryMethod.Products.Pizzas; 4 | 5 | namespace PizzaStoreFactoryMethod 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | PizzaStore nyStore = new NYPizzaStore(); 12 | PizzaStore chicagoStore = new ChicagoPizzaStore(); 13 | 14 | Pizza pizza = nyStore.OrderPizza("cheese"); 15 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 16 | 17 | pizza = chicagoStore.OrderPizza("cheese"); 18 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 19 | 20 | pizza = nyStore.OrderPizza("clam"); 21 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 22 | 23 | pizza = chicagoStore.OrderPizza("clam"); 24 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 25 | 26 | pizza = nyStore.OrderPizza("pepperoni"); 27 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 28 | 29 | pizza = chicagoStore.OrderPizza("pepperoni"); 30 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 31 | 32 | pizza = nyStore.OrderPizza("veggie"); 33 | Console.WriteLine("Ethan ordered a " + pizza + "\n"); 34 | 35 | pizza = chicagoStore.OrderPizza("veggie"); 36 | Console.WriteLine("Joel ordered a " + pizza + "\n"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/PizzaStore.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreSimpleFactory.Pizzas; 2 | using PizzaStoreSimpleFactory.SimpleFactories; 3 | 4 | namespace PizzaStoreSimpleFactory 5 | { 6 | public class PizzaStore 7 | { 8 | private readonly SimplePizzaFactory _factory; 9 | 10 | public PizzaStore(SimplePizzaFactory factory) 11 | { 12 | _factory = factory; 13 | } 14 | 15 | public Pizza OrderPizza(string type) 16 | { 17 | Pizza pizza = _factory.CreatePizza(type); 18 | 19 | pizza.Prepare(); 20 | pizza.Bake(); 21 | pizza.Cut(); 22 | pizza.Box(); 23 | 24 | return pizza; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/PizzaStoreSimpleFactory.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/Pizzas/Abstractions/Pizza.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace PizzaStoreSimpleFactory.Pizzas 6 | { 7 | public abstract class Pizza 8 | { 9 | public string Name { get; protected set; } 10 | public string Dough { get; protected set; } 11 | public string Sauce { get; protected set; } 12 | public List Toppings { get; protected set; } = new List(); 13 | 14 | public virtual void Prepare() 15 | { 16 | Console.WriteLine("Preparing " + Name); 17 | } 18 | 19 | public virtual void Bake() 20 | { 21 | Console.WriteLine("Bake for 25 minutes at 350"); 22 | } 23 | 24 | public virtual void Cut() 25 | { 26 | Console.WriteLine("Cutting the pizza into diagonal slices"); 27 | } 28 | 29 | public virtual void Box() 30 | { 31 | Console.WriteLine("Place pizza in official PizzaStore box"); 32 | } 33 | 34 | public override string ToString() 35 | { 36 | var result = new StringBuilder(); 37 | 38 | result.AppendLine("---- " + Name + " ----"); 39 | result.AppendLine(Dough); 40 | result.AppendLine(Sauce); 41 | foreach (var topping in Toppings) 42 | { 43 | result.AppendLine(topping); 44 | } 45 | 46 | return result.ToString(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/Pizzas/CheesePizza.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreSimpleFactory.Pizzas; 2 | 3 | namespace PizzaStoreSimpleFactory.Pizzas 4 | { 5 | public class CheesePizza : Pizza 6 | { 7 | public CheesePizza() 8 | { 9 | Name = "Cheese Pizza"; 10 | Dough = "Regular Crust"; 11 | Sauce = "Marinara Pizza Sauce"; 12 | 13 | Toppings.Add("Fresh Mozzarella"); 14 | Toppings.Add("Parmesan"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/Pizzas/ClamPizza.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreSimpleFactory.Pizzas; 2 | 3 | namespace PizzaStoreSimpleFactory.Pizzas 4 | { 5 | public class ClamPizza : Pizza 6 | { 7 | public ClamPizza() 8 | { 9 | Name = "Clam Pizza"; 10 | Dough = "Thin crust"; 11 | Sauce = "White garlic sauce"; 12 | 13 | Toppings.Add("Clams"); 14 | Toppings.Add("Grated parmesan cheese"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/Pizzas/PepperoniPizza.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreSimpleFactory.Pizzas; 2 | 3 | namespace PizzaStoreSimpleFactory.Pizzas 4 | { 5 | public class PepperoniPizza : Pizza 6 | { 7 | public PepperoniPizza() 8 | { 9 | Name = "Pepperoni Pizza"; 10 | Dough = "Crust"; 11 | Sauce = "Marinara sauce"; 12 | 13 | Toppings.Add("Sliced Pepperoni"); 14 | Toppings.Add("Sliced Onion"); 15 | Toppings.Add("Grated parmesan cheese"); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/Pizzas/VeggiePizza.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreSimpleFactory.Pizzas; 2 | 3 | namespace PizzaStoreSimpleFactory.Pizzas 4 | { 5 | public class VeggiePizza : Pizza 6 | { 7 | public VeggiePizza() 8 | { 9 | Name = "Veggie Pizza"; 10 | Dough = "Crust"; 11 | Sauce = "Marinara sauce"; 12 | 13 | Toppings.Add("Shredded mozzarella"); 14 | Toppings.Add("Grated parmesan"); 15 | Toppings.Add("Diced onion"); 16 | Toppings.Add("Sliced mushrooms"); 17 | Toppings.Add("Sliced red pepper"); 18 | Toppings.Add("Sliced black olives"); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PizzaStoreSimpleFactory.Pizzas; 3 | using PizzaStoreSimpleFactory.SimpleFactories; 4 | 5 | namespace PizzaStoreSimpleFactory 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | SimplePizzaFactory factory = new SimplePizzaFactory(); 12 | PizzaStore store = new PizzaStore(factory); 13 | 14 | Pizza pizza = store.OrderPizza("cheese"); 15 | Console.WriteLine("We ordered a " + pizza.Name); 16 | 17 | pizza = store.OrderPizza("veggie"); 18 | Console.WriteLine("We ordered a " + pizza.Name); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/factory/PizzaStoreSimpleFactory/SimpleFactories/SimplePizzaFactory.cs: -------------------------------------------------------------------------------- 1 | using PizzaStoreSimpleFactory.Pizzas; 2 | 3 | namespace PizzaStoreSimpleFactory.SimpleFactories 4 | { 5 | public class SimplePizzaFactory 6 | { 7 | public Pizza CreatePizza(string item) 8 | { 9 | Pizza pizza = null; 10 | switch (item) 11 | { 12 | case "cheese": 13 | pizza = new CheesePizza(); 14 | break; 15 | case "veggie": 16 | pizza = new VeggiePizza(); 17 | break; 18 | case "clam": 19 | pizza = new ClamPizza(); 20 | break; 21 | case "pepperoni": 22 | pizza = new PepperoniPizza(); 23 | break; 24 | } 25 | 26 | return pizza; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/factory/README.md: -------------------------------------------------------------------------------- 1 | **The Factory Method Pattern** defines an interface for creating an object, but lets subclasses decide which class to instantiate. 2 | Factory Method lets a class defer instantiation to subclasses. 3 | 4 | 5 | **The Abstract Factory Pattern** provides an interface for creating families of related or dependent objects without 6 | specifying their concrete classes. -------------------------------------------------------------------------------- /src/iterator/DinerMerger/AlternatingDinerMenuIterator.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | 4 | namespace DinerMerger 5 | { 6 | public class AlternatingDinerMenuIterator : IIterator 7 | { 8 | private readonly MenuItem[] _items; 9 | private int _position; 10 | 11 | public AlternatingDinerMenuIterator(MenuItem[] items) 12 | { 13 | _items = items; 14 | _position = (int)DateTime.Now.DayOfWeek % 2; 15 | } 16 | 17 | public bool HasNext() => _position < _items.Length && _items[_position] != null; 18 | 19 | public MenuItem Next() => _items[_position+=2]; 20 | 21 | public override string ToString() 22 | { 23 | return "Alternating Diner Menu Iterator"; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/iterator/DinerMerger/DinerMenuIterator.cs: -------------------------------------------------------------------------------- 1 | namespace DinerMerger 2 | { 3 | public class DinerMenuIterator : IIterator 4 | { 5 | private readonly MenuItem[] _items; 6 | private int _position; 7 | 8 | public DinerMenuIterator(MenuItem[] items) 9 | { 10 | _items = items; 11 | } 12 | 13 | public bool HasNext() => _position < _items.Length && _items[_position] != null; 14 | 15 | public MenuItem Next() => _items[_position++]; 16 | } 17 | } -------------------------------------------------------------------------------- /src/iterator/DinerMerger/DinerMerger.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/iterator/DinerMerger/IIterator.cs: -------------------------------------------------------------------------------- 1 | namespace DinerMerger 2 | { 3 | public interface IIterator 4 | { 5 | bool HasNext(); 6 | MenuItem Next(); 7 | } 8 | } -------------------------------------------------------------------------------- /src/iterator/DinerMerger/IMenu.cs: -------------------------------------------------------------------------------- 1 | namespace DinerMerger 2 | { 3 | public interface IMenu 4 | { 5 | IIterator CreateIterator(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/iterator/DinerMerger/MenuItem.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | 3 | namespace DinerMerger 4 | { 5 | public class MenuItem 6 | { 7 | public MenuItem(string name, string description, bool vegetarian, decimal price) 8 | { 9 | Name = name; 10 | Description = description; 11 | IsVegetarian = vegetarian; 12 | Price = price; 13 | } 14 | 15 | public string Name { get; } 16 | public string Description { get; } 17 | public bool IsVegetarian { get; } 18 | public decimal Price { get; } 19 | 20 | public override string ToString() 21 | { 22 | return $"{Name}, ${Price.ToString(CultureInfo.InvariantCulture)} \r\n {Description}"; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/iterator/DinerMerger/PancakeHouseMenu.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DinerMerger 4 | { 5 | public class PancakeHouseMenu : IMenu 6 | { 7 | private readonly List _menuItems; 8 | 9 | public PancakeHouseMenu() 10 | { 11 | _menuItems = new List(); 12 | 13 | AddItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99m); 14 | AddItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99m); 15 | AddItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49m); 16 | AddItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59m); 17 | } 18 | 19 | public void AddItem(string name, string description, 20 | bool vegetarian, decimal price) 21 | { 22 | var menuItem = new MenuItem(name, description, vegetarian, price); 23 | _menuItems.Add(menuItem); 24 | } 25 | 26 | public List GetMenuItems() 27 | { 28 | return _menuItems; 29 | } 30 | 31 | public IIterator CreateIterator() 32 | { 33 | return new PancakeHouseMenuIterator(_menuItems); 34 | } 35 | 36 | public override string ToString() 37 | { 38 | return "Objectville Pancake House Menu"; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/iterator/DinerMerger/PancakeHouseMenuIterator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DinerMerger 4 | { 5 | public class PancakeHouseMenuIterator : IIterator 6 | { 7 | private readonly List _items; 8 | private int _position; 9 | 10 | public PancakeHouseMenuIterator(List items) 11 | { 12 | _items = items; 13 | } 14 | 15 | public bool HasNext() 16 | { 17 | return _position < _items.Count; 18 | } 19 | 20 | public MenuItem Next() 21 | { 22 | return _items[_position++]; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/iterator/DinerMerger/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DinerMerger 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); 13 | DinerMenu dinerMenu = new DinerMenu(); 14 | 15 | Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu); 16 | 17 | // Without iterators 18 | //printMenu(); 19 | 20 | // With iterators 21 | waitress.PrintMenu(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/CafeMenu.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DinerMergerCafe 4 | { 5 | public class CafeMenu : IMenu 6 | { 7 | private readonly Dictionary _menuItems = new Dictionary(); 8 | 9 | public CafeMenu() 10 | { 11 | AddItem("Veggie Burger and Air Fries", "Veggie burger on a whole wheat bun, lettuce, tomato, and fries", true, 3.99m); 12 | AddItem("Soup of the day", "A cup of the soup of the day, with a side salad", false, 3.69m); 13 | AddItem("Burrito", "A large burrito, with whole pinto beans, salsa, guacamole", true, 4.29m); 14 | } 15 | 16 | public void AddItem(string name, string description, 17 | bool vegetarian, decimal price) 18 | { 19 | var menuItem = new MenuItem(name, description, vegetarian, price); 20 | _menuItems.Add(menuItem.Name, menuItem); 21 | } 22 | 23 | public Dictionary GetItems() 24 | { 25 | return _menuItems; 26 | } 27 | 28 | public IEnumerator CreateIterator() 29 | { 30 | return _menuItems.Values.GetEnumerator(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/DinerMenu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace DinerMergerCafe 5 | { 6 | public class DinerMenu : IMenu 7 | { 8 | private const int MAX_ITEMS = 6; 9 | private int _numberOfItems; 10 | private readonly MenuItem[] _menuItems; 11 | 12 | public DinerMenu() 13 | { 14 | _menuItems = new MenuItem[MAX_ITEMS]; 15 | 16 | AddItem("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99m); 17 | AddItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99m); 18 | AddItem("Soup of the day", "Soup of the day, with a side of potato salad", false, 3.29m); 19 | AddItem("Hotdog", "A hot dog, with sauerkraut, relish, onions, topped with cheese", false, 3.05m); 20 | AddItem("Steamed Veggies and Brown Rice", "Steamed vegetables over brown rice", true, 3.99m); 21 | AddItem("Pasta", "Spaghetti with Marinara Sauce, and a slice of sourdough bread", true, 3.89m); 22 | } 23 | 24 | public void AddItem(string name, string description, 25 | bool vegetarian, decimal price) 26 | { 27 | var menuItem = new MenuItem(name, description, vegetarian, price); 28 | if (_numberOfItems >= MAX_ITEMS) 29 | { 30 | Console.WriteLine("Sorry, menu is full! Can't add item to menu"); 31 | } 32 | else 33 | { 34 | _menuItems[_numberOfItems++] = menuItem; 35 | } 36 | } 37 | 38 | public MenuItem[] GetMenuItems() 39 | { 40 | return _menuItems; 41 | } 42 | 43 | public IEnumerator CreateIterator() 44 | { 45 | return new DinerMenuIterator(_menuItems); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/DinerMenuIterator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace DinerMergerCafe 6 | { 7 | public class DinerMenuIterator : IEnumerator 8 | { 9 | private readonly IEnumerator _enumerator; 10 | 11 | public DinerMenuIterator(MenuItem[] menuItems) 12 | { 13 | _enumerator = menuItems.GetEnumerator(); 14 | } 15 | 16 | public void Dispose() 17 | { 18 | } 19 | 20 | public bool MoveNext() 21 | { 22 | return _enumerator.MoveNext(); 23 | } 24 | 25 | public void Reset() 26 | { 27 | _enumerator.Reset(); 28 | } 29 | 30 | public MenuItem Current => (MenuItem) _enumerator.Current; 31 | 32 | object IEnumerator.Current => Current; 33 | } 34 | } -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/DinerMergerCafe.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/IMenu.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DinerMergerCafe 4 | { 5 | public interface IMenu 6 | { 7 | IEnumerator CreateIterator(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/MenuItem.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | 3 | namespace DinerMergerCafe 4 | { 5 | public class MenuItem 6 | { 7 | public MenuItem(string name, string description, bool vegetarian, decimal price) 8 | { 9 | Name = name; 10 | Description = description; 11 | IsVegetarian = vegetarian; 12 | Price = price; 13 | } 14 | 15 | public string Name { get; } 16 | public string Description { get; } 17 | public bool IsVegetarian { get; } 18 | public decimal Price { get; } 19 | 20 | public override string ToString() 21 | { 22 | return $"{Name}, ${Price.ToString(CultureInfo.InvariantCulture)} \r\n {Description}"; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/PancakeHouseMenu.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace DinerMergerCafe 4 | { 5 | public class PancakeHouseMenu : IMenu 6 | { 7 | private readonly List _menuItems; 8 | 9 | public PancakeHouseMenu() 10 | { 11 | _menuItems = new List(); 12 | 13 | AddItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99m); 14 | AddItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99m); 15 | AddItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49m); 16 | AddItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59m); 17 | } 18 | 19 | public void AddItem(string name, string description, 20 | bool vegetarian, decimal price) 21 | { 22 | var menuItem = new MenuItem(name, description, vegetarian, price); 23 | _menuItems.Add(menuItem); 24 | } 25 | 26 | public List GetMenuItems() 27 | { 28 | return _menuItems; 29 | } 30 | 31 | public IEnumerator CreateIterator() 32 | { 33 | return _menuItems.GetEnumerator(); 34 | } 35 | 36 | public override string ToString() 37 | { 38 | return "Objectville Pancake House Menu"; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/iterator/DinerMergerCafe/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace DinerMergerCafe 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); 13 | DinerMenu dinerMenu = new DinerMenu(); 14 | CafeMenu cafeMenu = new CafeMenu(); 15 | 16 | Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu, cafeMenu); 17 | 18 | waitress.PrintMenu(); 19 | waitress.PrintVegetarianMenu(); 20 | 21 | Console.WriteLine("\nCustomer asks, is the Hotdog vegetarian?"); 22 | Console.Write("Waitress says: "); 23 | Console.WriteLine(waitress.IsItemVegetarian("Hotdog") ? "Yes" : "No"); 24 | Console.WriteLine("\nCustomer asks, are the Waffles vegetarian?"); 25 | Console.Write("Waitress says: "); 26 | Console.WriteLine(waitress.IsItemVegetarian("Waffles") ? "Yes" : "No"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/iterator/README.md: -------------------------------------------------------------------------------- 1 | **The Iterator Pattern** provides a way to access the elements of an aggregate object sequentially without exposing its underlying 2 | representation. -------------------------------------------------------------------------------- /src/observer/README.md: -------------------------------------------------------------------------------- 1 | **The Observer Pattern** defines a one-to-many dependency between objects so that when one object changes state, 2 | all of its dependents are notified and updated automatically. -------------------------------------------------------------------------------- /src/observer/WeatherStation.Observable/Observers/Abstractions/IDisplayElement.cs: -------------------------------------------------------------------------------- 1 | namespace WeatherStation.Observable.Observers 2 | { 3 | public interface IDisplayElement 4 | { 5 | void Display(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/observer/WeatherStation.Observable/Observers/CurrentConditionsDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Observable.Subjects; 3 | 4 | namespace WeatherStation.Observable.Observers 5 | { 6 | public class CurrentConditionsDisplay : IObserver, IDisplayElement 7 | { 8 | private double _temperature; 9 | private double _humidity; 10 | private readonly IDisposable _unsubscriber; 11 | 12 | public CurrentConditionsDisplay(IObservable weatherData) 13 | { 14 | if(weatherData != null) 15 | _unsubscriber = weatherData.Subscribe(this); 16 | } 17 | 18 | public void Display() 19 | { 20 | Console.WriteLine("Current conditions: " + _temperature + "F degrees and " + _humidity + "% humidity"); 21 | } 22 | 23 | public void OnCompleted() 24 | { 25 | Console.WriteLine("Weather station has completed transmitting data"); 26 | _unsubscriber.Dispose(); 27 | } 28 | 29 | public void OnError(Exception error) 30 | { 31 | Console.WriteLine("Error occured {0}", error); 32 | } 33 | 34 | public void OnNext(WeatherData value) 35 | { 36 | _temperature = value.Temperature; 37 | _humidity = value.Humidity; 38 | Display(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/observer/WeatherStation.Observable/Observers/ForecastDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Observable.Subjects; 3 | 4 | namespace WeatherStation.Observable.Observers 5 | { 6 | public class ForecastDisplay : IObserver, IDisplayElement 7 | { 8 | private double _currentPressure = 29.92d; 9 | private double _lastPressure; 10 | private readonly IDisposable _unsubscriber; 11 | 12 | public ForecastDisplay(IObservable weatherData) 13 | { 14 | if (weatherData != null) 15 | _unsubscriber = weatherData.Subscribe(this); 16 | } 17 | 18 | public void Display() 19 | { 20 | Console.Write("Forecast: "); 21 | if (_currentPressure > _lastPressure) 22 | { 23 | Console.WriteLine("Improving weather on the way!"); 24 | } 25 | else if (_currentPressure == _lastPressure) 26 | { 27 | Console.WriteLine("More of the same"); 28 | } 29 | else if (_currentPressure < _lastPressure) 30 | { 31 | Console.WriteLine("Watch out for cooler, rainy weather"); 32 | } 33 | } 34 | 35 | public void OnCompleted() 36 | { 37 | Console.WriteLine("Weather station has completed transmitting data"); 38 | _unsubscriber.Dispose(); 39 | } 40 | 41 | public void OnError(Exception error) 42 | { 43 | Console.WriteLine("Error occured {0}", error); 44 | } 45 | 46 | public void OnNext(WeatherData value) 47 | { 48 | _lastPressure = _currentPressure; 49 | _currentPressure = value.Pressure; 50 | 51 | Display(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/observer/WeatherStation.Observable/Observers/StatisticsDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Observable.Subjects; 3 | 4 | namespace WeatherStation.Observable.Observers 5 | { 6 | public class StatisticsDisplay : IObserver, IDisplayElement 7 | { 8 | private double _maxTemp; 9 | private double _minTemp = 200; 10 | private double _tempSum; 11 | private int _numReadings; 12 | private readonly IDisposable _unsubscriber; 13 | 14 | public StatisticsDisplay(IObservable weatherData) 15 | { 16 | if (weatherData != null) 17 | _unsubscriber = weatherData.Subscribe(this); 18 | } 19 | 20 | public void Display() 21 | { 22 | Console.WriteLine("Avg/Max/Min temperature = " + (_tempSum / _numReadings) 23 | + "/" + _maxTemp + "/" + _minTemp); 24 | } 25 | 26 | public void OnCompleted() 27 | { 28 | Console.WriteLine("Weather station has completed transmitting data"); 29 | _unsubscriber.Dispose(); 30 | } 31 | 32 | public void OnError(Exception error) 33 | { 34 | Console.WriteLine("Error occured {0}", error); 35 | } 36 | 37 | public void OnNext(WeatherData value) 38 | { 39 | _tempSum += value.Temperature; 40 | _numReadings++; 41 | 42 | if (value.Temperature > _maxTemp) 43 | { 44 | _maxTemp = value.Temperature; 45 | } 46 | 47 | if (value.Temperature < _minTemp) 48 | { 49 | _minTemp = value.Temperature; 50 | } 51 | 52 | Display(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/observer/WeatherStation.Observable/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Observable.Observers; 3 | using WeatherStation.Observable.Subjects; 4 | 5 | namespace WeatherStation.Observable 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | WeatherData weatherData = new WeatherData(); 12 | 13 | CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); 14 | StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); 15 | ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); 16 | HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData); 17 | 18 | weatherData.SetMeasurements(80, 65, 30.4d); 19 | weatherData.SetMeasurements(82, 70, 29.2d); 20 | weatherData.SetMeasurements(78, 90, 29.2d); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/observer/WeatherStation.Observable/WeatherStation.Observable.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Observers/Abstractions/IDisplayElement.cs: -------------------------------------------------------------------------------- 1 | namespace WeatherStation.Observers 2 | { 3 | public interface IDisplayElement 4 | { 5 | void Display(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Observers/Abstractions/IObserver.cs: -------------------------------------------------------------------------------- 1 | namespace WeatherStation.Observers 2 | { 3 | public interface IObserver 4 | { 5 | void Update(double temp, double humidity, double pressure); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Observers/CurrentConditionsDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Subjects; 3 | 4 | namespace WeatherStation.Observers 5 | { 6 | public class CurrentConditionsDisplay : IObserver, IDisplayElement 7 | { 8 | private double _temperature; 9 | private double _humidity; 10 | private readonly ISubject _weatherData; 11 | 12 | public CurrentConditionsDisplay(ISubject weatherData) 13 | { 14 | _weatherData = weatherData; 15 | _weatherData.RegisterObserver(this); 16 | } 17 | 18 | public void Display() 19 | { 20 | Console.WriteLine("Current conditions: " + _temperature + "F degrees and " + _humidity + "% humidity"); 21 | } 22 | 23 | public void Update(double temp, double humidity, double pressure) 24 | { 25 | _temperature = temp; 26 | _humidity = humidity; 27 | Display(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Observers/ForecastDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Subjects; 3 | 4 | namespace WeatherStation.Observers 5 | { 6 | public class ForecastDisplay : IObserver, IDisplayElement 7 | { 8 | private double _currentPressure = 29.92d; 9 | private double _lastPressure; 10 | private readonly ISubject _weatherData; 11 | 12 | public ForecastDisplay(ISubject weatherData) 13 | { 14 | _weatherData = weatherData; 15 | _weatherData.RegisterObserver(this); 16 | } 17 | 18 | public void Display() 19 | { 20 | Console.Write("Forecast: "); 21 | if (_currentPressure > _lastPressure) 22 | { 23 | Console.WriteLine("Improving weather on the way!"); 24 | } 25 | else if (_currentPressure == _lastPressure) 26 | { 27 | Console.WriteLine("More of the same"); 28 | } 29 | else if (_currentPressure < _lastPressure) 30 | { 31 | Console.WriteLine("Watch out for cooler, rainy weather"); 32 | } 33 | } 34 | 35 | public void Update(double temp, double humidity, double pressure) 36 | { 37 | _lastPressure = _currentPressure; 38 | _currentPressure = pressure; 39 | 40 | Display(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Observers/HeatIndexDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Subjects; 3 | 4 | namespace WeatherStation.Observers 5 | { 6 | public class HeatIndexDisplay : IObserver, IDisplayElement 7 | { 8 | private double _heatIndex; 9 | private readonly ISubject _weatherData; 10 | 11 | public HeatIndexDisplay(ISubject weatherData) 12 | { 13 | _weatherData = weatherData; 14 | _weatherData.RegisterObserver(this); 15 | } 16 | 17 | public void Display() 18 | { 19 | Console.WriteLine("Heat index is " + _heatIndex); 20 | } 21 | 22 | public void Update(double temp, double humidity, double pressure) 23 | { 24 | _heatIndex = ComputeHeatIndex(temp, humidity); 25 | Display(); 26 | } 27 | 28 | private double ComputeHeatIndex(double t, double rh) 29 | { 30 | double index = (16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh) 31 | + (0.00941695 * (t * t)) + (0.00728898 * (rh * rh)) 32 | + (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) + 33 | (0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 * 34 | (rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) + 35 | (0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) + 36 | 0.000000000843296 * (t * t * rh * rh * rh)) - 37 | (0.0000000000481975 * (t * t * t * rh * rh * rh)); 38 | return index; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Observers/StatisticsDisplay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Subjects; 3 | 4 | namespace WeatherStation.Observers 5 | { 6 | public class StatisticsDisplay : IObserver, IDisplayElement 7 | { 8 | private double _maxTemp; 9 | private double _minTemp = 200; 10 | private double _tempSum; 11 | private int _numReadings; 12 | private readonly ISubject _weatherData; 13 | 14 | public StatisticsDisplay(ISubject weatherData) 15 | { 16 | _weatherData = weatherData; 17 | _weatherData.RegisterObserver(this); 18 | } 19 | 20 | public void Display() 21 | { 22 | Console.WriteLine("Avg/Max/Min temperature = " + (_tempSum / _numReadings) 23 | + "/" + _maxTemp + "/" + _minTemp); 24 | } 25 | 26 | public void Update(double temp, double humidity, double pressure) 27 | { 28 | _tempSum += temp; 29 | _numReadings++; 30 | 31 | if (temp > _maxTemp) 32 | { 33 | _maxTemp = temp; 34 | } 35 | 36 | if (temp < _minTemp) 37 | { 38 | _minTemp = temp; 39 | } 40 | 41 | Display(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using WeatherStation.Observers; 3 | using WeatherStation.Subjects; 4 | 5 | namespace WeatherStation 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | WeatherData weatherData = new WeatherData(); 12 | 13 | CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); 14 | StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); 15 | ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); 16 | HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData); 17 | 18 | weatherData.SetMeasurements(80, 65, 30.4d); 19 | weatherData.SetMeasurements(82, 70, 29.2d); 20 | weatherData.SetMeasurements(78, 90, 29.2d); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Subjects/Abstractions/ISubject.cs: -------------------------------------------------------------------------------- 1 | using WeatherStation.Observers; 2 | 3 | namespace WeatherStation.Subjects 4 | { 5 | public interface ISubject 6 | { 7 | void RegisterObserver(IObserver o); 8 | void RemoveObserver(IObserver o); 9 | void NotifyObservers(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/Subjects/WeatherData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using WeatherStation.Observers; 3 | 4 | namespace WeatherStation.Subjects 5 | { 6 | public class WeatherData : ISubject 7 | { 8 | private readonly List _observers; 9 | private double _temperature; 10 | private double _humidity; 11 | private double _pressure; 12 | 13 | public WeatherData() 14 | { 15 | _observers = new List(); 16 | } 17 | 18 | public void MeasurementsChanged() 19 | { 20 | NotifyObservers(); 21 | } 22 | 23 | public void SetMeasurements(double temperature, double humidity, double pressure) 24 | { 25 | _temperature = temperature; 26 | _humidity = humidity; 27 | _pressure = pressure; 28 | MeasurementsChanged(); 29 | } 30 | 31 | public void NotifyObservers() 32 | { 33 | foreach (var observer in _observers) 34 | { 35 | observer.Update(_temperature, _humidity, _pressure); 36 | } 37 | } 38 | 39 | public void RegisterObserver(IObserver o) 40 | { 41 | _observers.Add(o); 42 | } 43 | 44 | public void RemoveObserver(IObserver o) 45 | { 46 | _observers.Remove(o); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/observer/WeatherStation/WeatherStation.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/proxy/README.md: -------------------------------------------------------------------------------- 1 | **The Proxy Pattern** provides a surrogate or placeholder for another object to control access to it. -------------------------------------------------------------------------------- /src/singleton/ChocolateBoiler/ChocolateBoiler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ChocolateBoiler 4 | { 5 | public class ChocolateBoiler 6 | { 7 | private static ChocolateBoiler _uniqueInstance; 8 | 9 | public static ChocolateBoiler Instance 10 | { 11 | get 12 | { 13 | if (_uniqueInstance == null) 14 | { 15 | Console.WriteLine("Creating unique instance of Chocolate Boiler"); 16 | _uniqueInstance = new ChocolateBoiler(); 17 | } 18 | 19 | Console.WriteLine("Returning instance of Chocolate Boiler"); 20 | return _uniqueInstance; 21 | } 22 | } 23 | 24 | public bool Empty { get; private set; } 25 | public bool Boiled { get; private set; } 26 | 27 | private ChocolateBoiler() 28 | { 29 | Empty = true; 30 | Boiled = false; 31 | } 32 | 33 | public void Fill() 34 | { 35 | if (Empty) 36 | { 37 | Empty = false; 38 | Boiled = false; 39 | // fill the boiler with a milk/chocolate mixture 40 | } 41 | } 42 | 43 | public void Drain() 44 | { 45 | if (!Empty && !Boiled) 46 | { 47 | // drain the boiled milk and chocolate 48 | Empty = true; 49 | } 50 | } 51 | 52 | public void Boil() 53 | { 54 | if (!Empty && !Boiled) 55 | { 56 | // bring the contents to a boil 57 | Boiled = true; 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/singleton/ChocolateBoiler/ChocolateBoiler.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/singleton/ChocolateBoiler/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ChocolateBoiler 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | ChocolateBoiler boiler = ChocolateBoiler.Instance; 10 | boiler.Fill(); 11 | boiler.Boil(); 12 | boiler.Drain(); 13 | 14 | // will return the existing instance 15 | ChocolateBoiler boiler2 = ChocolateBoiler.Instance; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/MultipleSingleton.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MultipleSingleton.Singletons.Subclasses; 3 | 4 | namespace MultipleSingleton 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | var foo = CoolerSingleton.Instance; 11 | var bar = HotterSingleton.Instance; 12 | 13 | Console.WriteLine(foo == bar); 14 | Console.WriteLine(foo); 15 | Console.WriteLine(bar); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Singletons/ClassicSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace MultipleSingleton.Singletons 2 | { 3 | // NOTE: This is not thread safe! 4 | public class ClassicSingleton 5 | { 6 | private static ClassicSingleton _uniqueInstance; 7 | 8 | public static ClassicSingleton Instance => _uniqueInstance ?? (_uniqueInstance = new ClassicSingleton()); 9 | 10 | private ClassicSingleton() { } 11 | } 12 | } -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Singletons/DclSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace MultipleSingleton.Singletons 2 | { 3 | public class DclSingleton 4 | { 5 | private static volatile DclSingleton _uniqueInstance; 6 | private static readonly object SyncLock = new object(); 7 | 8 | public static DclSingleton Instance 9 | { 10 | get 11 | { 12 | if (_uniqueInstance == null) 13 | { 14 | lock (SyncLock) 15 | { 16 | if (_uniqueInstance == null) 17 | { 18 | _uniqueInstance = new DclSingleton(); 19 | } 20 | } 21 | } 22 | return _uniqueInstance; 23 | } 24 | } 25 | 26 | private DclSingleton() { } 27 | } 28 | } -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Singletons/StaticSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace MultipleSingleton.Singletons 2 | { 3 | public class StaticSingleton 4 | { 5 | public static StaticSingleton Instance { get; } = new StaticSingleton(); 6 | 7 | private StaticSingleton() { } 8 | } 9 | } -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Singletons/Subclasses/BaseSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace MultipleSingleton.Singletons 2 | { 3 | public class BaseSingleton 4 | { 5 | protected static BaseSingleton UniqueInstance; 6 | private static readonly object SyncLock = new object(); 7 | 8 | public static BaseSingleton Instance 9 | { 10 | get 11 | { 12 | lock (SyncLock) 13 | { 14 | if (UniqueInstance == null) 15 | { 16 | UniqueInstance = new BaseSingleton(); 17 | } 18 | } 19 | 20 | return UniqueInstance; 21 | } 22 | } 23 | 24 | protected BaseSingleton() { } 25 | } 26 | } -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Singletons/Subclasses/CoolerSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace MultipleSingleton.Singletons.Subclasses 2 | { 3 | public class CoolerSingleton : BaseSingleton 4 | { 5 | protected new static BaseSingleton UniqueInstance; 6 | 7 | private CoolerSingleton() { } 8 | } 9 | } -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Singletons/Subclasses/HotterSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace MultipleSingleton.Singletons.Subclasses 2 | { 3 | public class HotterSingleton : BaseSingleton 4 | { 5 | private HotterSingleton(){} 6 | } 7 | } -------------------------------------------------------------------------------- /src/singleton/MultipleSingleton/Singletons/ThreadSafeSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace MultipleSingleton.Singletons 2 | { 3 | public class ThreadSafeSingleton 4 | { 5 | private static ThreadSafeSingleton _uniqueInstance; 6 | private static readonly object SyncLock = new object(); 7 | 8 | public static ThreadSafeSingleton Instance 9 | { 10 | get 11 | { 12 | lock (SyncLock) 13 | { 14 | if (_uniqueInstance == null) 15 | { 16 | _uniqueInstance = new ThreadSafeSingleton(); 17 | } 18 | } 19 | 20 | return _uniqueInstance; 21 | } 22 | } 23 | 24 | private ThreadSafeSingleton() { } 25 | } 26 | } -------------------------------------------------------------------------------- /src/singleton/README.md: -------------------------------------------------------------------------------- 1 | **The Singleton Pattern** ensures a class has only one instance, and provides a global point of access to it. -------------------------------------------------------------------------------- /src/state/Gumball/Gumball.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/state/Gumball/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace Gumball 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | GumballMachine gumballMachine = new GumballMachine(5); 13 | 14 | Console.WriteLine(gumballMachine); 15 | 16 | gumballMachine.InsertQuarter(); 17 | gumballMachine.TurnCrank(); 18 | 19 | Console.WriteLine(gumballMachine); 20 | 21 | gumballMachine.InsertQuarter(); 22 | gumballMachine.EjectQuarter(); 23 | gumballMachine.TurnCrank(); 24 | 25 | Console.WriteLine(gumballMachine); 26 | 27 | gumballMachine.InsertQuarter(); 28 | gumballMachine.TurnCrank(); 29 | gumballMachine.InsertQuarter(); 30 | gumballMachine.TurnCrank(); 31 | gumballMachine.EjectQuarter(); 32 | 33 | Console.WriteLine(gumballMachine); 34 | 35 | gumballMachine.InsertQuarter(); 36 | gumballMachine.InsertQuarter(); 37 | gumballMachine.TurnCrank(); 38 | gumballMachine.InsertQuarter(); 39 | gumballMachine.TurnCrank(); 40 | gumballMachine.InsertQuarter(); 41 | gumballMachine.TurnCrank(); 42 | 43 | Console.WriteLine(gumballMachine); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/state/GumballState/GumballState.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/state/GumballState/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace GumballState 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | GumballMachine gumballMachine = new GumballMachine(2); 13 | 14 | Console.WriteLine(gumballMachine); 15 | 16 | gumballMachine.InsertQuarter(); 17 | gumballMachine.TurnCrank(); 18 | 19 | Console.WriteLine(gumballMachine); 20 | 21 | gumballMachine.InsertQuarter(); 22 | gumballMachine.TurnCrank(); 23 | gumballMachine.InsertQuarter(); 24 | gumballMachine.TurnCrank(); 25 | 26 | gumballMachine.Refill(5); 27 | gumballMachine.InsertQuarter(); 28 | gumballMachine.TurnCrank(); 29 | 30 | Console.WriteLine(gumballMachine); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/state/GumballState/States/Abstractions/IState.cs: -------------------------------------------------------------------------------- 1 | namespace GumballState.States 2 | { 3 | public interface IState 4 | { 5 | void InsertQuarter(); 6 | void EjectQuarter(); 7 | void TurnCrank(); 8 | void Dispense(); 9 | 10 | void Refill(); 11 | } 12 | } -------------------------------------------------------------------------------- /src/state/GumballState/States/HasQuarterState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballState.States 4 | { 5 | public class HasQuarterState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | 9 | public HasQuarterState(GumballMachine gumballMachine) 10 | { 11 | _gumballMachine = gumballMachine; 12 | } 13 | 14 | public void InsertQuarter() 15 | { 16 | Console.WriteLine("You can't insert another quarter"); 17 | } 18 | 19 | public void EjectQuarter() 20 | { 21 | Console.WriteLine("Quarter returned"); 22 | _gumballMachine.SetState(_gumballMachine.NoQuarterState); 23 | } 24 | 25 | public void TurnCrank() 26 | { 27 | Console.WriteLine("You turned..."); 28 | _gumballMachine.SetState(_gumballMachine.SoldState); 29 | } 30 | 31 | public void Dispense() 32 | { 33 | Console.WriteLine("No gumball dispensed"); 34 | } 35 | 36 | public void Refill() { } 37 | 38 | public override string ToString() 39 | { 40 | return "waiting for turn of crank"; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/state/GumballState/States/NoQuarterState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballState.States 4 | { 5 | public class NoQuarterState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | 9 | public NoQuarterState(GumballMachine gumballMachine) 10 | { 11 | _gumballMachine = gumballMachine; 12 | } 13 | 14 | public void InsertQuarter() 15 | { 16 | Console.WriteLine("You inserted a quarter"); 17 | _gumballMachine.SetState(_gumballMachine.HasQuarterState); 18 | } 19 | 20 | public void EjectQuarter() 21 | { 22 | Console.WriteLine("You haven't inserted a quarter"); 23 | } 24 | 25 | public void TurnCrank() 26 | { 27 | Console.WriteLine("You turned, but there's no quarter"); 28 | } 29 | 30 | public void Dispense() 31 | { 32 | Console.WriteLine("You need to pay first"); 33 | } 34 | 35 | public void Refill() { } 36 | 37 | public override string ToString() 38 | { 39 | return "waiting for quarter"; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/state/GumballState/States/SoldOutState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballState.States 4 | { 5 | public class SoldOutState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | 9 | public SoldOutState(GumballMachine gumballMachine) 10 | { 11 | _gumballMachine = gumballMachine; 12 | } 13 | 14 | public void InsertQuarter() 15 | { 16 | Console.WriteLine("You can't insert a quarter, the machine is sold out"); 17 | } 18 | 19 | public void EjectQuarter() 20 | { 21 | Console.WriteLine("You can't eject, you haven't inserted a quarter yet"); 22 | } 23 | 24 | public void TurnCrank() 25 | { 26 | Console.WriteLine("You turned, but there are no gumballs"); 27 | } 28 | 29 | public void Dispense() 30 | { 31 | Console.WriteLine("No gumball dispensed"); 32 | } 33 | 34 | public void Refill() 35 | { 36 | _gumballMachine.SetState(_gumballMachine.NoQuarterState); 37 | } 38 | 39 | public override string ToString() 40 | { 41 | return "sold out"; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/state/GumballState/States/SoldState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballState.States 4 | { 5 | public class SoldState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | 9 | public SoldState(GumballMachine gumballMachine) 10 | { 11 | _gumballMachine = gumballMachine; 12 | } 13 | 14 | public void InsertQuarter() 15 | { 16 | Console.WriteLine("Please wait, we're already giving you a gumball"); 17 | } 18 | 19 | public void EjectQuarter() 20 | { 21 | Console.WriteLine("Sorry, you already turned the crank"); 22 | } 23 | 24 | public void TurnCrank() 25 | { 26 | Console.WriteLine("Turning twice doesn't get you another gumball!"); 27 | } 28 | 29 | public void Dispense() 30 | { 31 | _gumballMachine.ReleaseBall(); 32 | if (_gumballMachine.Count > 0) 33 | { 34 | _gumballMachine.SetState(_gumballMachine.NoQuarterState); 35 | } 36 | else 37 | { 38 | Console.WriteLine("Oops, out of gumballs!"); 39 | _gumballMachine.SetState(_gumballMachine.SoldOutState); 40 | } 41 | } 42 | 43 | public void Refill() { } 44 | 45 | public override string ToString() 46 | { 47 | return "dispensing a gumball"; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/state/GumballStateWinner/GumballStateWinner.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/state/GumballStateWinner/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace GumballStateWinner 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | GumballMachine gumballMachine = new GumballMachine(10); 13 | 14 | Console.WriteLine(gumballMachine); 15 | 16 | gumballMachine.InsertQuarter(); 17 | gumballMachine.TurnCrank(); 18 | gumballMachine.InsertQuarter(); 19 | gumballMachine.TurnCrank(); 20 | 21 | Console.WriteLine(gumballMachine); 22 | 23 | gumballMachine.InsertQuarter(); 24 | gumballMachine.TurnCrank(); 25 | gumballMachine.InsertQuarter(); 26 | gumballMachine.TurnCrank(); 27 | 28 | Console.WriteLine(gumballMachine); 29 | 30 | gumballMachine.InsertQuarter(); 31 | gumballMachine.TurnCrank(); 32 | gumballMachine.InsertQuarter(); 33 | gumballMachine.TurnCrank(); 34 | 35 | Console.WriteLine(gumballMachine); 36 | 37 | gumballMachine.InsertQuarter(); 38 | gumballMachine.TurnCrank(); 39 | gumballMachine.InsertQuarter(); 40 | gumballMachine.TurnCrank(); 41 | 42 | Console.WriteLine(gumballMachine); 43 | 44 | gumballMachine.InsertQuarter(); 45 | gumballMachine.TurnCrank(); 46 | gumballMachine.InsertQuarter(); 47 | gumballMachine.TurnCrank(); 48 | 49 | Console.WriteLine(gumballMachine); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/state/GumballStateWinner/States/Abstractions/IState.cs: -------------------------------------------------------------------------------- 1 | namespace GumballStateWinner.States 2 | { 3 | public interface IState 4 | { 5 | void InsertQuarter(); 6 | void EjectQuarter(); 7 | void TurnCrank(); 8 | void Dispense(); 9 | 10 | void Refill(); 11 | } 12 | } -------------------------------------------------------------------------------- /src/state/GumballStateWinner/States/HasQuarterState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballStateWinner.States 4 | { 5 | public class HasQuarterState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | private readonly Random _random = new Random(); 9 | 10 | public HasQuarterState(GumballMachine gumballMachine) 11 | { 12 | _gumballMachine = gumballMachine; 13 | } 14 | 15 | public void InsertQuarter() 16 | { 17 | Console.WriteLine("You can't insert another quarter"); 18 | } 19 | 20 | public void EjectQuarter() 21 | { 22 | Console.WriteLine("Quarter returned"); 23 | _gumballMachine.SetState(_gumballMachine.NoQuarterState); 24 | } 25 | 26 | public void TurnCrank() 27 | { 28 | Console.WriteLine("You turned..."); 29 | int winner = _random.Next(10); 30 | if (winner == 0 && _gumballMachine.Count > 1) 31 | { 32 | _gumballMachine.SetState(_gumballMachine.WinnerState); 33 | } 34 | else 35 | { 36 | _gumballMachine.SetState(_gumballMachine.SoldState); 37 | } 38 | } 39 | 40 | public void Dispense() 41 | { 42 | Console.WriteLine("No gumball dispensed"); 43 | } 44 | 45 | public void Refill() { } 46 | 47 | public override string ToString() 48 | { 49 | return "waiting for turn of crank"; 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/state/GumballStateWinner/States/NoQuarterState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballStateWinner.States 4 | { 5 | public class NoQuarterState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | 9 | public NoQuarterState(GumballMachine gumballMachine) 10 | { 11 | _gumballMachine = gumballMachine; 12 | } 13 | 14 | public void InsertQuarter() 15 | { 16 | Console.WriteLine("You inserted a quarter"); 17 | _gumballMachine.SetState(_gumballMachine.HasQuarterState); 18 | } 19 | 20 | public void EjectQuarter() 21 | { 22 | Console.WriteLine("You haven't inserted a quarter"); 23 | } 24 | 25 | public void TurnCrank() 26 | { 27 | Console.WriteLine("You turned, but there's no quarter"); 28 | } 29 | 30 | public void Dispense() 31 | { 32 | Console.WriteLine("You need to pay first"); 33 | } 34 | 35 | public void Refill() { } 36 | 37 | public override string ToString() 38 | { 39 | return "waiting for quarter"; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/state/GumballStateWinner/States/SoldOutState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballStateWinner.States 4 | { 5 | public class SoldOutState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | 9 | public SoldOutState(GumballMachine gumballMachine) 10 | { 11 | _gumballMachine = gumballMachine; 12 | } 13 | 14 | public void InsertQuarter() 15 | { 16 | Console.WriteLine("You can't insert a quarter, the machine is sold out"); 17 | } 18 | 19 | public void EjectQuarter() 20 | { 21 | Console.WriteLine("You can't eject, you haven't inserted a quarter yet"); 22 | } 23 | 24 | public void TurnCrank() 25 | { 26 | Console.WriteLine("You turned, but there are no gumballs"); 27 | } 28 | 29 | public void Dispense() 30 | { 31 | Console.WriteLine("No gumball dispensed"); 32 | } 33 | 34 | public void Refill() 35 | { 36 | _gumballMachine.SetState(_gumballMachine.NoQuarterState); 37 | } 38 | 39 | public override string ToString() 40 | { 41 | return "sold out"; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/state/GumballStateWinner/States/SoldState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GumballStateWinner.States 4 | { 5 | public class SoldState : IState 6 | { 7 | private readonly GumballMachine _gumballMachine; 8 | 9 | public SoldState(GumballMachine gumballMachine) 10 | { 11 | _gumballMachine = gumballMachine; 12 | } 13 | 14 | public void InsertQuarter() 15 | { 16 | Console.WriteLine("Please wait, we're already giving you a gumball"); 17 | } 18 | 19 | public void EjectQuarter() 20 | { 21 | Console.WriteLine("Sorry, you already turned the crank"); 22 | } 23 | 24 | public void TurnCrank() 25 | { 26 | Console.WriteLine("Turning twice doesn't get you another gumball!"); 27 | } 28 | 29 | public void Dispense() 30 | { 31 | _gumballMachine.ReleaseBall(); 32 | if (_gumballMachine.Count > 0) 33 | { 34 | _gumballMachine.SetState(_gumballMachine.NoQuarterState); 35 | } 36 | else 37 | { 38 | Console.WriteLine("Oops, out of gumballs!"); 39 | _gumballMachine.SetState(_gumballMachine.SoldOutState); 40 | } 41 | } 42 | 43 | public void Refill() { } 44 | 45 | public override string ToString() 46 | { 47 | return "dispensing a gumball"; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/state/README.md: -------------------------------------------------------------------------------- 1 | **The State Pattern** allows an object to alter its behavior when its internal state changes. 2 | The object will appear to change its class. -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/Abstractions/IFlyBehavior.cs: -------------------------------------------------------------------------------- 1 | namespace MiniDuckSimulator.Behaviors 2 | { 3 | public interface IFlyBehavior 4 | { 5 | void Fly(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/Abstractions/IQuackBehavior.cs: -------------------------------------------------------------------------------- 1 | namespace MiniDuckSimulator.Behaviors 2 | { 3 | public interface IQuackBehavior 4 | { 5 | void Quack(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/FlyNoWay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MiniDuckSimulator.Behaviors 4 | { 5 | public class FlyNoWay : IFlyBehavior 6 | { 7 | public void Fly() 8 | { 9 | Console.WriteLine("I can't fly"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/FlyRocketPowered.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MiniDuckSimulator.Behaviors 4 | { 5 | public class FlyRocketPowered : IFlyBehavior 6 | { 7 | public void Fly() 8 | { 9 | Console.WriteLine("I'm flying with a rocket!"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/FlyWithWings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MiniDuckSimulator.Behaviors 4 | { 5 | public class FlyWithWings : IFlyBehavior 6 | { 7 | public void Fly() 8 | { 9 | Console.WriteLine("I'm flying!!"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/MuteQuack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MiniDuckSimulator.Behaviors 4 | { 5 | public class MuteQuack : IQuackBehavior 6 | { 7 | public void Quack() 8 | { 9 | Console.WriteLine("<< Silence >>"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/Quack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MiniDuckSimulator.Behaviors 4 | { 5 | public class Quack : IQuackBehavior 6 | { 7 | void IQuackBehavior.Quack() 8 | { 9 | Console.WriteLine("Quack"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Behaviors/Squeak.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MiniDuckSimulator.Behaviors 4 | { 5 | public class Squeak : IQuackBehavior 6 | { 7 | public void Quack() 8 | { 9 | Console.WriteLine("Squeak"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Ducks/Abstractions/Duck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MiniDuckSimulator.Behaviors; 3 | 4 | namespace MiniDuckSimulator.Ducks 5 | { 6 | public abstract class Duck 7 | { 8 | public IFlyBehavior FlyBehavior { get; set; } 9 | public IQuackBehavior QuackBehavior { get; set; } 10 | 11 | protected Duck() 12 | { 13 | } 14 | 15 | public abstract void Display(); 16 | 17 | public void PerformFly() 18 | { 19 | FlyBehavior.Fly(); 20 | } 21 | 22 | public void PerformQuack() 23 | { 24 | QuackBehavior.Quack(); 25 | } 26 | 27 | public void Swim() 28 | { 29 | Console.WriteLine("All ducks float, even decoys!"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Ducks/DecoyDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MiniDuckSimulator.Behaviors; 3 | 4 | namespace MiniDuckSimulator.Ducks 5 | { 6 | public class DecoyDuck : Duck 7 | { 8 | public DecoyDuck() 9 | { 10 | QuackBehavior = new MuteQuack(); 11 | FlyBehavior = new FlyNoWay(); 12 | } 13 | 14 | public override void Display() 15 | { 16 | Console.WriteLine("I'm a duck Decoy"); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Ducks/MallardDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MiniDuckSimulator.Behaviors; 3 | 4 | namespace MiniDuckSimulator.Ducks 5 | { 6 | public class MallardDuck : Duck 7 | { 8 | public MallardDuck() 9 | { 10 | QuackBehavior = new Quack(); 11 | FlyBehavior = new FlyWithWings(); 12 | } 13 | 14 | public override void Display() 15 | { 16 | Console.WriteLine("I'm a real Mallard duck"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Ducks/ModelDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MiniDuckSimulator.Behaviors; 3 | 4 | namespace MiniDuckSimulator.Ducks 5 | { 6 | public class ModelDuck : Duck 7 | { 8 | public ModelDuck() 9 | { 10 | FlyBehavior = new FlyNoWay(); 11 | QuackBehavior = new Quack(); 12 | } 13 | 14 | public override void Display() 15 | { 16 | Console.WriteLine("I'm a model duck"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Ducks/RedHeadDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MiniDuckSimulator.Behaviors; 3 | 4 | namespace MiniDuckSimulator.Ducks 5 | { 6 | public class RedHeadDuck : Duck 7 | { 8 | public RedHeadDuck() 9 | { 10 | QuackBehavior = new Quack(); 11 | FlyBehavior = new FlyWithWings(); 12 | } 13 | 14 | public override void Display() 15 | { 16 | Console.WriteLine("I'm a real Red Headed duck"); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Ducks/RubberDuck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MiniDuckSimulator.Behaviors; 3 | 4 | namespace MiniDuckSimulator.Ducks 5 | { 6 | public class RubberDuck : Duck 7 | { 8 | public RubberDuck() 9 | { 10 | QuackBehavior = new Squeak(); 11 | FlyBehavior = new FlyNoWay(); 12 | } 13 | 14 | public override void Display() 15 | { 16 | Console.WriteLine("I'm a rubber duckie"); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/MiniDuckSimulator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/strategy/MiniDuckSimulator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MiniDuckSimulator.Behaviors; 3 | using MiniDuckSimulator.Ducks; 4 | 5 | namespace MiniDuckSimulator 6 | { 7 | public class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | MallardDuck mallard = new MallardDuck(); 12 | RubberDuck rubberDuckie = new RubberDuck(); 13 | DecoyDuck decoy = new DecoyDuck(); 14 | 15 | ModelDuck model = new ModelDuck(); 16 | 17 | mallard.PerformQuack(); 18 | rubberDuckie.PerformQuack(); 19 | decoy.PerformQuack(); 20 | 21 | model.PerformFly(); 22 | model.FlyBehavior = new FlyRocketPowered(); 23 | model.PerformFly(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/strategy/README.md: -------------------------------------------------------------------------------- 1 | **The Strategy Pattern** defines a family of algorithms, encapsulates each one, and makes them interchangeable. 2 | Strategy lets the algorithm vary independently from clients that use it. -------------------------------------------------------------------------------- /src/templatemethod/Barista/Barista.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | Exe 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/templatemethod/Barista/CaffeineBeverage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Barista 4 | { 5 | public abstract class CaffeineBeverage 6 | { 7 | public void PrepareRecipe() 8 | { 9 | BoilWater(); 10 | Brew(); 11 | PourInCup(); 12 | AddCondiments(); 13 | } 14 | 15 | public abstract void Brew(); 16 | public abstract void AddCondiments(); 17 | 18 | public virtual void BoilWater() 19 | { 20 | Console.WriteLine("Boiling water"); 21 | } 22 | 23 | public virtual void PourInCup() 24 | { 25 | Console.WriteLine("Pouring into cup"); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/templatemethod/Barista/CaffeineBeverageWithHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Barista 4 | { 5 | public abstract class CaffeineBeverageWithHook 6 | { 7 | public void PrepareRecipe() 8 | { 9 | BoilWater(); 10 | Brew(); 11 | PourInCup(); 12 | if (CustomerWantsCondiments) 13 | { 14 | AddCondiments(); 15 | } 16 | } 17 | 18 | public abstract void Brew(); 19 | public abstract void AddCondiments(); 20 | 21 | public virtual void BoilWater() 22 | { 23 | Console.WriteLine("Boiling water"); 24 | } 25 | 26 | public virtual void PourInCup() 27 | { 28 | Console.WriteLine("Pouring into cup"); 29 | } 30 | 31 | public virtual bool CustomerWantsCondiments => true; 32 | } 33 | } -------------------------------------------------------------------------------- /src/templatemethod/Barista/Coffee.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Barista 4 | { 5 | public class Coffee : CaffeineBeverage 6 | { 7 | public override void Brew() 8 | { 9 | Console.WriteLine("Dripping Coffee through filter"); 10 | } 11 | 12 | public override void AddCondiments() 13 | { 14 | Console.WriteLine("Adding Sugar and Milk"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/templatemethod/Barista/CoffeeWithHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Barista 4 | { 5 | public class CoffeeWithHook : CaffeineBeverageWithHook 6 | { 7 | public override void Brew() 8 | { 9 | Console.WriteLine("Dripping Coffee through filter"); 10 | } 11 | 12 | public override void AddCondiments() 13 | { 14 | Console.WriteLine("Adding Sugar and Milk"); 15 | } 16 | 17 | public override bool CustomerWantsCondiments => GetUserInput().ToUpper().StartsWith("Y"); 18 | 19 | private string GetUserInput() 20 | { 21 | Console.WriteLine("Would you like milk and sugar with your coffee (y/n)? "); 22 | 23 | string answer = Console.ReadLine(); 24 | 25 | return answer ?? "no"; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/templatemethod/Barista/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Barista 4 | { 5 | public class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | Tea tea = new Tea(); 10 | Coffee coffee = new Coffee(); 11 | 12 | Console.WriteLine("Making tea..."); 13 | tea.PrepareRecipe(); 14 | 15 | Console.WriteLine("\nMaking coffee..."); 16 | coffee.PrepareRecipe(); 17 | 18 | 19 | TeaWithHook teaHook = new TeaWithHook(); 20 | CoffeeWithHook coffeeHook = new CoffeeWithHook(); 21 | 22 | Console.WriteLine("\nMaking tea..."); 23 | teaHook.PrepareRecipe(); 24 | 25 | Console.WriteLine("\nMaking coffee..."); 26 | coffeeHook.PrepareRecipe(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/templatemethod/Barista/Tea.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Barista 4 | { 5 | public class Tea : CaffeineBeverage 6 | { 7 | public override void Brew() 8 | { 9 | Console.WriteLine("Steeping the tea"); 10 | } 11 | 12 | public override void AddCondiments() 13 | { 14 | Console.WriteLine("Adding Lemon"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/templatemethod/Barista/TeaWithHook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Barista 4 | { 5 | public class TeaWithHook : CaffeineBeverageWithHook 6 | { 7 | public override void Brew() 8 | { 9 | Console.WriteLine("Steeping the tea"); 10 | } 11 | 12 | public override void AddCondiments() 13 | { 14 | Console.WriteLine("Adding Lemon"); 15 | } 16 | 17 | public override bool CustomerWantsCondiments => GetUserInput().ToUpper().StartsWith("Y"); 18 | 19 | private string GetUserInput() 20 | { 21 | Console.WriteLine("Would you like lemon with your tea (y/n)? "); 22 | 23 | string answer = Console.ReadLine(); 24 | 25 | return answer ?? "no"; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/templatemethod/DuckSort/Duck.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace DuckSort 4 | { 5 | public class Duck : IComparable 6 | { 7 | public Duck(string name, int weight) 8 | { 9 | Name = name; 10 | Weight = weight; 11 | } 12 | 13 | public string Name { get; } 14 | public int Weight { get; } 15 | 16 | public int CompareTo(Duck other) 17 | { 18 | if (Weight < other.Weight) 19 | { 20 | return -1; 21 | } 22 | 23 | return Weight == other.Weight ? 0 : 1; //Weight > other.Weight; 24 | } 25 | 26 | public override string ToString() => $"{Name} weighs {Weight.ToString()}"; 27 | } 28 | } -------------------------------------------------------------------------------- /src/templatemethod/DuckSort/DuckSort.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/templatemethod/DuckSort/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace DuckSort 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | Duck[] ducks = 11 | { 12 | new Duck("Daffy", 8), 13 | new Duck("Dewey", 2), 14 | new Duck("Howard", 7), 15 | new Duck("Louie", 2), 16 | new Duck("Donald", 10), 17 | new Duck("Huey", 2) 18 | }; 19 | 20 | Console.WriteLine("Before sorting:"); 21 | Display(ducks); 22 | 23 | Array.Sort(ducks); 24 | 25 | Console.WriteLine("\nAfter sorting:"); 26 | Display(ducks); 27 | } 28 | 29 | public static void Display(IEnumerable ducks) 30 | { 31 | foreach (var duck in ducks) 32 | { 33 | Console.WriteLine(duck); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/templatemethod/README.md: -------------------------------------------------------------------------------- 1 | **The Template Method Pattern** defines the skeleton of an algorithm in a method, deferring some steps to subclasses. 2 | Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. --------------------------------------------------------------------------------