Add code examples, and documentation
This commit is contained in:
13
patterns/bridge/Bridge Example/AlertNotification.cs
Normal file
13
patterns/bridge/Bridge Example/AlertNotification.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Bridge_Example;
|
||||
|
||||
//This is one of the refined abstraction classes. Note that it can make use of _sender since it inherits it from its superclass. Note also that since EmailSender and SmsSender implement IMessageSender, their specific SendMessage() method will be called, depending on what's passed into the constructor (see the main method)
|
||||
public class AlertNotification : Notification
|
||||
{
|
||||
public AlertNotification(IMessageSender sender)
|
||||
: base(sender) { }
|
||||
|
||||
public override void Notify(string message)
|
||||
{
|
||||
_sender.SendMessage($"ALERT: {message}");
|
||||
}
|
||||
}
|
||||
7
patterns/bridge/Bridge Example/Bridge Example.csproj
Normal file
7
patterns/bridge/Bridge Example/Bridge Example.csproj
Normal file
@@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>Bridge_Example</RootNamespace>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
16
patterns/bridge/Bridge Example/EmailSender.cs
Normal file
16
patterns/bridge/Bridge Example/EmailSender.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Bridge_Example;
|
||||
|
||||
//This is one of the concrete implementors, which implements the implementor interface IMessageSender
|
||||
public class EmailSender : IMessageSender
|
||||
{
|
||||
public void SendMessage(string message)
|
||||
{
|
||||
Console.WriteLine($"Email sent: {message}");
|
||||
}
|
||||
}
|
||||
7
patterns/bridge/Bridge Example/IMessageSender.cs
Normal file
7
patterns/bridge/Bridge Example/IMessageSender.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Bridge_Example;
|
||||
|
||||
//This class is the implementor. It gets implemented by concrete classes.
|
||||
public interface IMessageSender
|
||||
{
|
||||
void SendMessage(string message);
|
||||
}
|
||||
14
patterns/bridge/Bridge Example/Notification.cs
Normal file
14
patterns/bridge/Bridge Example/Notification.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Bridge_Example;
|
||||
|
||||
//This is the abstraction
|
||||
public abstract class Notification
|
||||
{
|
||||
protected readonly IMessageSender _sender;
|
||||
|
||||
protected Notification(IMessageSender sender)
|
||||
{
|
||||
_sender = sender;
|
||||
}
|
||||
|
||||
public abstract void Notify(string message);
|
||||
}
|
||||
17
patterns/bridge/Bridge Example/Program.cs
Normal file
17
patterns/bridge/Bridge Example/Program.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Bridge_Example;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Notification n1 = new AlertNotification(new EmailSender());
|
||||
Notification n2 = new AlertNotification(new SmsSender());
|
||||
Notification n3 = new ReminderNotification(new EmailSender());
|
||||
Notification n4 = new ReminderNotification(new SmsSender());
|
||||
|
||||
n1.Notify("Server is down");
|
||||
n2.Notify("Server is down");
|
||||
n3.Notify("Meeting at 3pm");
|
||||
n4.Notify("Meeting at 3pm");
|
||||
}
|
||||
}
|
||||
13
patterns/bridge/Bridge Example/ReminderNotification.cs
Normal file
13
patterns/bridge/Bridge Example/ReminderNotification.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Bridge_Example;
|
||||
|
||||
//This is one of the refined abstraction classes. Note that it can make use of _sender since it inherits it from its superclass. Note also that since EmailSender and SmsSender implement IMessageSender, their specific SendMessage() method will be called, depending on what's passed into the constructor (see the main method)
|
||||
public class ReminderNotification : Notification
|
||||
{
|
||||
public ReminderNotification(IMessageSender sender)
|
||||
: base(sender) { }
|
||||
|
||||
public override void Notify(string message)
|
||||
{
|
||||
_sender.SendMessage($"Reminder: {message}");
|
||||
}
|
||||
}
|
||||
16
patterns/bridge/Bridge Example/SmsSender.cs
Normal file
16
patterns/bridge/Bridge Example/SmsSender.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Bridge_Example;
|
||||
|
||||
//This is another concrete implementor class, which implements the implementor interface IMessageSender
|
||||
public class SmsSender : IMessageSender
|
||||
{
|
||||
public void SendMessage(string message)
|
||||
{
|
||||
Console.WriteLine($"SMS sent: {message}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
102
patterns/decorator/IceCreamDecorations/Program.cs
Normal file
102
patterns/decorator/IceCreamDecorations/Program.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
public interface IIceCream
|
||||
{
|
||||
void Prepare();
|
||||
decimal GetPrice();
|
||||
}
|
||||
|
||||
public class ChocolateIceCream : IIceCream
|
||||
{
|
||||
public void Prepare()
|
||||
{
|
||||
Console.WriteLine("Preparing a chocolate ice cream.");
|
||||
}
|
||||
|
||||
public decimal GetPrice()
|
||||
{
|
||||
return 2.50m; // base price for chocolate ice cream
|
||||
}
|
||||
}
|
||||
|
||||
public class VanillaIceCream : IIceCream
|
||||
{
|
||||
public void Prepare()
|
||||
{
|
||||
Console.WriteLine("Preparing a vanilla ice cream.");
|
||||
}
|
||||
|
||||
public decimal GetPrice()
|
||||
{
|
||||
return 2.00m; // base price for vanilla ice cream
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class IceCreamDecorator(IIceCream decorated) : IIceCream
|
||||
{
|
||||
protected IIceCream _decorated = decorated;
|
||||
public abstract void Prepare();
|
||||
public abstract decimal GetPrice();
|
||||
}
|
||||
|
||||
public class SprinkleDecorator(IIceCream decorated)
|
||||
: IceCreamDecorator(decorated)
|
||||
{
|
||||
public override void Prepare()
|
||||
{
|
||||
// call the base first
|
||||
_decorated.Prepare();
|
||||
Console.WriteLine("Adding sprinkles!");
|
||||
}
|
||||
|
||||
public override decimal GetPrice()
|
||||
{
|
||||
return _decorated.GetPrice() + 0.50m; // add price for sprinkles
|
||||
}
|
||||
}
|
||||
|
||||
public class ChocolateSyrupDecorator(IIceCream decorated)
|
||||
: IceCreamDecorator(decorated)
|
||||
{
|
||||
public override void Prepare()
|
||||
{
|
||||
// call the base prepare first
|
||||
_decorated.Prepare();
|
||||
Console.WriteLine("Adding chocolate syrup!");
|
||||
}
|
||||
|
||||
public override decimal GetPrice()
|
||||
{
|
||||
return _decorated.GetPrice() + 0.75m; // add price for chocolate syrup
|
||||
}
|
||||
}
|
||||
|
||||
public class CaramelSyrupDecorator(IIceCream decorated)
|
||||
: IceCreamDecorator(decorated)
|
||||
{
|
||||
public override void Prepare()
|
||||
{
|
||||
// call the base prepare first
|
||||
_decorated.Prepare();
|
||||
Console.WriteLine("Adding caramel syrup!");
|
||||
}
|
||||
|
||||
public override decimal GetPrice()
|
||||
{
|
||||
return _decorated.GetPrice() + 0.75m; // add price for caramel syrup
|
||||
}
|
||||
}
|
||||
|
||||
internal class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
decimal price = new CaramelSyrupDecorator(
|
||||
new ChocolateSyrupDecorator(
|
||||
new SprinkleDecorator(
|
||||
new ChocolateIceCream()
|
||||
)
|
||||
)
|
||||
).GetPrice();
|
||||
|
||||
Console.WriteLine($"Total price: {price:C}");
|
||||
}
|
||||
}
|
||||
66
patterns/decorator/ShapeDecorations/Program.cs
Normal file
66
patterns/decorator/ShapeDecorations/Program.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
using ShapeDecorations.Shapes;
|
||||
using ShapeDecorations.Shapes.Decorators;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ShapeDecorations;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
// scoped to allow for re-use of variable names
|
||||
{
|
||||
// First create a concrete shape, since we need one to be able to decorate anything
|
||||
var circle = new Circle();
|
||||
circle.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
// Now we decorate the shape with a red color
|
||||
var red = new RedColor(circle);
|
||||
red.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
// Since the decorator itself is an IShape, we can further decorate it
|
||||
var blueBorder = new BlueBorder(red);
|
||||
blueBorder.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
// And can continue to decorate each ShapeDecorator with as many decorator classes as we like
|
||||
var huge = new HugeSize(blueBorder);
|
||||
huge.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
{
|
||||
// Always must start with a concrete IShape implementation
|
||||
var rect = new Rectangle();
|
||||
rect.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
// Note that the order in which we decorate doesn't matter
|
||||
var blueBorder = new BlueBorder(rect);
|
||||
blueBorder.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
var huge = new HugeSize(blueBorder);
|
||||
huge.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
var red = new RedColor(huge);
|
||||
red.Draw();
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>ShapeDecorations</RootNamespace>
|
||||
<AssemblyName>ShapeDecorations</AssemblyName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
15
patterns/decorator/ShapeDecorations/Shapes/Circle.cs
Normal file
15
patterns/decorator/ShapeDecorations/Shapes/Circle.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ShapeDecorations.Shapes;
|
||||
|
||||
public class Circle : IShape
|
||||
{
|
||||
public void Draw()
|
||||
{
|
||||
Console.WriteLine("Drawing a circle");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ShapeDecorations.Shapes.Decorators;
|
||||
|
||||
/// <summary>
|
||||
/// See the RedColor class for details on the implementation
|
||||
/// </summary>
|
||||
public class BlueBorder : ShapeDecorator
|
||||
{
|
||||
/// <summary>
|
||||
/// See the RedColor class for details on the implementation
|
||||
/// </summary>
|
||||
public BlueBorder(IShape decorated)
|
||||
: base(decorated) { }
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
_decorated.Draw();
|
||||
Console.WriteLine("\tWith a blue border");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ShapeDecorations.Shapes.Decorators;
|
||||
|
||||
public class HugeSize : ShapeDecorator
|
||||
{
|
||||
/// <summary>
|
||||
/// See the RedColor class for details on the implementation
|
||||
/// </summary>
|
||||
/// <param name="decorated">
|
||||
/// The IShape (whtether concrete IShape or concrete
|
||||
/// ShapeDecorator) to be decorated
|
||||
/// </param>
|
||||
public HugeSize(IShape decorated)
|
||||
: base(decorated) { }
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
_decorated.Draw();
|
||||
Console.WriteLine("\tThat is enourmous in size");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ShapeDecorations.Shapes.Decorators;
|
||||
|
||||
public class RedColor : ShapeDecorator
|
||||
{
|
||||
/// <summary>
|
||||
/// Public ctor. Calls the base class with the passed IShape, thus decorating
|
||||
/// it.
|
||||
/// Implementation is left empty, as the base class does all the work needed.
|
||||
/// </summary>
|
||||
/// <param name="decorated"></param>
|
||||
public RedColor(IShape decorated)
|
||||
: base(decorated) { }
|
||||
|
||||
/// <summary>
|
||||
/// Performs the actual drawing logic, but first calls the decorated member,
|
||||
/// adding its own logic afterwards.
|
||||
/// </summary>
|
||||
public override void Draw()
|
||||
{
|
||||
// First calls decorated member
|
||||
_decorated.Draw();
|
||||
|
||||
// Then adds additional drawing logic
|
||||
Console.WriteLine("\tWhich is red in color");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace ShapeDecorations.Shapes.Decorators;
|
||||
|
||||
public abstract class ShapeDecorator : IShape
|
||||
{
|
||||
/// <summary>
|
||||
/// Maintains a reference to the shape which it decorates
|
||||
/// this allows implementors to add additional steps to the "drawing" process.
|
||||
/// Marked "protected" so that inheriting classes have access to it.
|
||||
/// </summary
|
||||
protected IShape _decorated;
|
||||
|
||||
/// <summary>
|
||||
/// Acceps a reference to any IShape.
|
||||
/// Since the ShapeDecorator itself IS an IShape, this
|
||||
/// decorator can also decorate other decorators
|
||||
/// However, since a ShapeDecorator has to be instantiated with an existing
|
||||
/// IShape,
|
||||
/// at some point in the chain of decoration, there must be a concrete shape
|
||||
/// (specifically, a concrete IShape that was createad without having another
|
||||
/// IShape passed to it)
|
||||
/// </summary>
|
||||
/// <param name="decorated"></param>
|
||||
public ShapeDecorator(IShape decorated)
|
||||
{
|
||||
_decorated = decorated;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marking this abstract satisfies the implementation of IShape,
|
||||
/// but forces inheriting classes to implement their own drawing logic
|
||||
/// </summary>
|
||||
public abstract void Draw();
|
||||
}
|
||||
6
patterns/decorator/ShapeDecorations/Shapes/IShape.cs
Normal file
6
patterns/decorator/ShapeDecorations/Shapes/IShape.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace ShapeDecorations.Shapes;
|
||||
|
||||
public interface IShape
|
||||
{
|
||||
void Draw();
|
||||
}
|
||||
15
patterns/decorator/ShapeDecorations/Shapes/Rectangle.cs
Normal file
15
patterns/decorator/ShapeDecorations/Shapes/Rectangle.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ShapeDecorations.Shapes;
|
||||
|
||||
public class Rectangle : IShape
|
||||
{
|
||||
public void Draw()
|
||||
{
|
||||
Console.WriteLine("Drawing a Rectangle");
|
||||
}
|
||||
}
|
||||
14
patterns/facade/CarEngineFacade/AirFlowController.cs
Normal file
14
patterns/facade/CarEngineFacade/AirFlowController.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace CarEngineFacade;
|
||||
|
||||
public class AirFlowController
|
||||
{
|
||||
public void TakeAir()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Off()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
8
patterns/facade/CarEngineFacade/CarEngineFacade.csproj
Normal file
8
patterns/facade/CarEngineFacade/CarEngineFacade.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>CarEngineFacade</RootNamespace>
|
||||
<AssemblyName>CarEngineFacade</AssemblyName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
14
patterns/facade/CarEngineFacade/CatalyticConverter.cs
Normal file
14
patterns/facade/CarEngineFacade/CatalyticConverter.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace CarEngineFacade;
|
||||
|
||||
public class CatalyticConverter
|
||||
{
|
||||
public void On()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Off()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
19
patterns/facade/CarEngineFacade/CoolingController.cs
Normal file
19
patterns/facade/CarEngineFacade/CoolingController.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace CarEngineFacade;
|
||||
|
||||
public class CoolingController
|
||||
{
|
||||
public void Run()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Cool()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
29
patterns/facade/CarEngineFacade/Facade.cs
Normal file
29
patterns/facade/CarEngineFacade/Facade.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace CarEngineFacade;
|
||||
|
||||
public class Facade
|
||||
{
|
||||
private readonly AirFlowController _air = new();
|
||||
private readonly CatalyticConverter _cat = new();
|
||||
private readonly CoolingController _cool = new();
|
||||
private readonly FuelInjector _fuel = new();
|
||||
private readonly Starter _start = new();
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_air.TakeAir();
|
||||
_fuel.On();
|
||||
_fuel.Inject();
|
||||
_start.Start();
|
||||
_cool.Run();
|
||||
_cat.On();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_fuel.Off();
|
||||
_cat.Off();
|
||||
_cool.Cool();
|
||||
_cool.Stop();
|
||||
_air.Off();
|
||||
}
|
||||
}
|
||||
19
patterns/facade/CarEngineFacade/FuelInjector.cs
Normal file
19
patterns/facade/CarEngineFacade/FuelInjector.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace CarEngineFacade;
|
||||
|
||||
public class FuelInjector
|
||||
{
|
||||
public void On()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Inject()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Off()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
38
patterns/facade/CarEngineFacade/Program.cs
Normal file
38
patterns/facade/CarEngineFacade/Program.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
namespace CarEngineFacade;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
//// without the facade, starting the engine involves creating all the objects
|
||||
//var airflow = new AirFlowController();
|
||||
//var fuel = new FuelInjector();
|
||||
//var start = new Starter();
|
||||
//var cool = new CoolingController();
|
||||
//var cat = new CatalyticConverter();
|
||||
|
||||
//// then performing all the steps in the correct order
|
||||
//airflow.TakeAir();
|
||||
//fuel.On();
|
||||
//fuel.Inject();
|
||||
//start.Start();
|
||||
//cool.Run();
|
||||
//cat.On();
|
||||
|
||||
//// and shut down also requires steps in the correct order
|
||||
//fuel.Off();
|
||||
//cat.Off();
|
||||
//cool.Cool();
|
||||
//cool.Stop();
|
||||
//airflow.Off();
|
||||
|
||||
// with the Facade, all creation is handled internally
|
||||
var facade = new Facade();
|
||||
|
||||
// as is starting
|
||||
facade.Start();
|
||||
|
||||
// and stopping
|
||||
facade.Stop();
|
||||
}
|
||||
}
|
||||
9
patterns/facade/CarEngineFacade/Starter.cs
Normal file
9
patterns/facade/CarEngineFacade/Starter.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace CarEngineFacade;
|
||||
|
||||
public class Starter
|
||||
{
|
||||
public void Start()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace CarEngineFacadeRecording;
|
||||
|
||||
public class AirFlowController
|
||||
{
|
||||
public void TakeAir()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Off()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace CarEngineFacadeRecording;
|
||||
|
||||
public class CatalyticConverter
|
||||
{
|
||||
public void On()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Off()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace CarEngineFacadeRecording;
|
||||
|
||||
public class CoolingController
|
||||
{
|
||||
public void Run()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Cool()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
29
patterns/facade/CarEngineFacadeRecording/Facade.cs
Normal file
29
patterns/facade/CarEngineFacadeRecording/Facade.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace CarEngineFacadeRecording;
|
||||
|
||||
public class Facade
|
||||
{
|
||||
private readonly AirFlowController _air = new();
|
||||
private readonly CatalyticConverter _cat = new();
|
||||
private readonly CoolingController _cool = new();
|
||||
private readonly FuelInjector _fuel = new();
|
||||
private readonly Starter _start = new();
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_air.TakeAir();
|
||||
_fuel.On();
|
||||
_fuel.Inject();
|
||||
_start.Start();
|
||||
_cool.Run();
|
||||
_cat.On();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_fuel.Off();
|
||||
_cat.Off();
|
||||
_cool.Cool();
|
||||
_cool.Stop();
|
||||
_air.Off();
|
||||
}
|
||||
}
|
||||
19
patterns/facade/CarEngineFacadeRecording/FuelInjector.cs
Normal file
19
patterns/facade/CarEngineFacadeRecording/FuelInjector.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace CarEngineFacadeRecording;
|
||||
|
||||
public class FuelInjector
|
||||
{
|
||||
public void On()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Inject()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
public void Off()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
36
patterns/facade/CarEngineFacadeRecording/Program.cs
Normal file
36
patterns/facade/CarEngineFacadeRecording/Program.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
#region
|
||||
|
||||
using CarEngineFacadeRecording;
|
||||
|
||||
#endregion
|
||||
|
||||
//// without the facade, starting the engine involves creating all the objects
|
||||
//var airflow = new AirFlowController();
|
||||
//var fuel = new FuelInjector();
|
||||
//var start = new Starter();
|
||||
//var cool = new CoolingController();
|
||||
//var cat = new CatalyticConverter();
|
||||
|
||||
//// then performing all the steps in the correct order
|
||||
//airflow.TakeAir();
|
||||
//fuel.On();
|
||||
//fuel.Inject();
|
||||
//start.Start();
|
||||
//cool.Run();
|
||||
//cat.On();
|
||||
|
||||
//// and shut down also requires steps in the correct order
|
||||
//fuel.Off();
|
||||
//cat.Off();
|
||||
//cool.Cool();
|
||||
//cool.Stop();
|
||||
//airflow.Off();
|
||||
|
||||
// with the Facade, all creation is handled internally
|
||||
var facade = new Facade();
|
||||
|
||||
// as is starting
|
||||
facade.Start();
|
||||
|
||||
// and stopping
|
||||
facade.Stop();
|
||||
9
patterns/facade/CarEngineFacadeRecording/Starter.cs
Normal file
9
patterns/facade/CarEngineFacadeRecording/Starter.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace CarEngineFacadeRecording;
|
||||
|
||||
public class Starter
|
||||
{
|
||||
public void Start()
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>AirTrafficControl</RootNamespace>
|
||||
<AssemblyName>AirTrafficControl</AssemblyName>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
363
patterns/mediator/AirTrafficControl/Program.cs
Normal file
363
patterns/mediator/AirTrafficControl/Program.cs
Normal file
@@ -0,0 +1,363 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace AirTrafficControl;
|
||||
|
||||
public enum AirTrafficRequest
|
||||
{
|
||||
LandingRequest,
|
||||
TakeoffRequest,
|
||||
RunwayCrossingRequest,
|
||||
LandingRequestDone,
|
||||
TakeoffRequestDone,
|
||||
RunwayCrossingRequestDone,
|
||||
}
|
||||
|
||||
public interface IColleague
|
||||
{
|
||||
void ReceiveMessage(string instruction, bool accepted);
|
||||
}
|
||||
|
||||
public interface IMediator
|
||||
{
|
||||
void Notify(IColleague sender, AirTrafficRequest request);
|
||||
}
|
||||
|
||||
public class Flight : IColleague
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
public string FlightNumber { get; }
|
||||
|
||||
public Flight(string flightNumber, IMediator mediator)
|
||||
{
|
||||
FlightNumber = flightNumber;
|
||||
_mediator = mediator;
|
||||
}
|
||||
|
||||
public void RequestLanding()
|
||||
{
|
||||
Console.WriteLine($"Flight {FlightNumber} requesting landing.");
|
||||
_mediator.Notify(this, AirTrafficRequest.LandingRequest);
|
||||
}
|
||||
|
||||
public void RequestTakeoff()
|
||||
{
|
||||
Console.WriteLine($"Flight {FlightNumber} requesting takeoff.");
|
||||
_mediator.Notify(this, AirTrafficRequest.TakeoffRequest);
|
||||
}
|
||||
|
||||
public void LandingCompleted()
|
||||
{
|
||||
Console.WriteLine($"Flight {FlightNumber} has completed landing.");
|
||||
_mediator.Notify(this, AirTrafficRequest.LandingRequestDone);
|
||||
}
|
||||
|
||||
public void TakeoffCompleted()
|
||||
{
|
||||
Console.WriteLine($"Flight {FlightNumber} has completed takeoff.");
|
||||
_mediator.Notify(this, AirTrafficRequest.TakeoffRequestDone);
|
||||
}
|
||||
|
||||
public void ReceiveMessage(string instruction, bool accepted)
|
||||
{
|
||||
if (accepted)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Flight {FlightNumber} received instruction: {instruction}"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Flight {FlightNumber} received rejection for instruction: {instruction}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GroundVehicle : IColleague
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
public string VehicleId { get; }
|
||||
|
||||
public GroundVehicle(string vehicleId, IMediator mediator)
|
||||
{
|
||||
VehicleId = vehicleId;
|
||||
_mediator = mediator;
|
||||
}
|
||||
|
||||
public void RequestRunwayCrossing()
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Ground vehicle {VehicleId} requesting runway crossing."
|
||||
);
|
||||
_mediator.Notify(this, AirTrafficRequest.RunwayCrossingRequest);
|
||||
}
|
||||
|
||||
public void RunwayCrossingCompleted()
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Ground vehicle {VehicleId} has completed runway crossing."
|
||||
);
|
||||
_mediator.Notify(this, AirTrafficRequest.RunwayCrossingRequestDone);
|
||||
}
|
||||
|
||||
public void ReceiveMessage(string instruction, bool accepted)
|
||||
{
|
||||
if (accepted)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Ground vehicle {VehicleId} received instruction: {instruction}"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Ground vehicle {VehicleId} received rejection for instruction: {instruction}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AirTrafficControlTower : IMediator
|
||||
{
|
||||
private class Runway
|
||||
{
|
||||
public string Name { get; init; } = "";
|
||||
public IColleague? OccupiedBy { get; set; }
|
||||
|
||||
public Runway(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Runway[] _runways = new Runway[30];
|
||||
|
||||
public AirTrafficControlTower()
|
||||
{
|
||||
// create runways
|
||||
for (int i = 0; i < _runways.Length; i++)
|
||||
{
|
||||
_runways[i] = new Runway($"Runway R{i + 1}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Notify(IColleague sender, AirTrafficRequest request)
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case AirTrafficRequest.LandingRequest:
|
||||
HandleLandingRequest(sender);
|
||||
break;
|
||||
case AirTrafficRequest.TakeoffRequest:
|
||||
HandleTakeoffRequest(sender);
|
||||
break;
|
||||
case AirTrafficRequest.RunwayCrossingRequest:
|
||||
HandleRunwayCrossingRequest(sender);
|
||||
break;
|
||||
case AirTrafficRequest.LandingRequestDone:
|
||||
HandleLandingRequestDone(sender);
|
||||
break;
|
||||
case AirTrafficRequest.TakeoffRequestDone:
|
||||
HandleTakeoffRequestDone(sender);
|
||||
break;
|
||||
case AirTrafficRequest.RunwayCrossingRequestDone:
|
||||
HandleRunwayCrossingRequestDone(sender);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleLandingRequest(IColleague sender)
|
||||
{
|
||||
Runway? val = _runways.FirstOrDefault(r => r.OccupiedBy is null);
|
||||
if (val is not null)
|
||||
{
|
||||
val.OccupiedBy = sender;
|
||||
sender.ReceiveMessage(
|
||||
$"Landing approved on {val.Name}.",
|
||||
accepted: true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.ReceiveMessage(
|
||||
"No available runways for landing.",
|
||||
accepted: false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleTakeoffRequest(IColleague sender)
|
||||
{
|
||||
Runway? val = _runways.FirstOrDefault(r => r.OccupiedBy is null);
|
||||
if (val is not null)
|
||||
{
|
||||
val.OccupiedBy = sender;
|
||||
sender.ReceiveMessage(
|
||||
$"Takeoff approved on {val.Name}.",
|
||||
accepted: true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.ReceiveMessage(
|
||||
"No available runways for takeoff.",
|
||||
accepted: false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleLandingRequestDone(IColleague sender)
|
||||
{
|
||||
Runway? val = _runways.FirstOrDefault(r => r.OccupiedBy == sender);
|
||||
if (val is not null)
|
||||
{
|
||||
val.OccupiedBy = null;
|
||||
sender.ReceiveMessage(
|
||||
$"You have cleared {val.Name} after landing.",
|
||||
accepted: true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.ReceiveMessage(
|
||||
"You were not occupying any runway.",
|
||||
accepted: false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleTakeoffRequestDone(IColleague sender)
|
||||
{
|
||||
Runway? val = _runways.FirstOrDefault(r => r.OccupiedBy == sender);
|
||||
if (val is not null)
|
||||
{
|
||||
val.OccupiedBy = null;
|
||||
sender.ReceiveMessage(
|
||||
$"You have cleared {val.Name} after takeoff.",
|
||||
accepted: true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.ReceiveMessage(
|
||||
"You were not occupying any runway.",
|
||||
accepted: false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRunwayCrossingRequestDone(IColleague sender)
|
||||
{
|
||||
Runway? val = _runways.FirstOrDefault(r => r.OccupiedBy == sender);
|
||||
|
||||
if (val is not null)
|
||||
{
|
||||
val.OccupiedBy = null;
|
||||
sender.ReceiveMessage(
|
||||
$"You have cleared {val.Name} after crossing.",
|
||||
accepted: true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.ReceiveMessage(
|
||||
"You were not occupying any runway.",
|
||||
accepted: false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRunwayCrossingRequest(IColleague sender)
|
||||
{
|
||||
Runway? val = _runways.FirstOrDefault(r => r.OccupiedBy is null);
|
||||
|
||||
if (val is not null)
|
||||
{
|
||||
val.OccupiedBy = sender;
|
||||
sender.ReceiveMessage(
|
||||
$"Crossing approved on {val.Name}.",
|
||||
accepted: true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.ReceiveMessage(
|
||||
"No available runways for crossing.",
|
||||
accepted: false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var tower = new AirTrafficControlTower();
|
||||
|
||||
Flight[] flights = new Flight[1000];
|
||||
|
||||
for (int i = 0; i < flights.Length; i++)
|
||||
{
|
||||
flights[i] = new Flight($"F{i + 1:D4}", tower);
|
||||
}
|
||||
|
||||
GroundVehicle[] vehicles = new GroundVehicle[10];
|
||||
|
||||
for (int i = 0; i < vehicles.Length; i++)
|
||||
{
|
||||
vehicles[i] = new GroundVehicle($"V{i + 1:D3}", tower);
|
||||
}
|
||||
|
||||
// create simulation with random events
|
||||
Random rand = new Random();
|
||||
|
||||
ulong tick = 0;
|
||||
|
||||
while (tick < 100_000)
|
||||
{
|
||||
tick++;
|
||||
|
||||
// randomly select a flight or vehicle to make a request
|
||||
int index = rand.Next(0, flights.Length + vehicles.Length);
|
||||
if (index < flights.Length)
|
||||
{
|
||||
Flight flight = flights[index];
|
||||
int action = rand.Next(0, 4);
|
||||
switch (action)
|
||||
{
|
||||
case 0:
|
||||
flight.RequestLanding();
|
||||
break;
|
||||
case 1:
|
||||
flight.RequestTakeoff();
|
||||
break;
|
||||
case 2:
|
||||
flight.LandingCompleted();
|
||||
break;
|
||||
case 3:
|
||||
flight.TakeoffCompleted();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GroundVehicle vehicle = vehicles[index - flights.Length];
|
||||
int action = rand.Next(0, 2);
|
||||
switch (action)
|
||||
{
|
||||
case 0:
|
||||
vehicle.RequestRunwayCrossing();
|
||||
break;
|
||||
case 1:
|
||||
vehicle.RunwayCrossingCompleted();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
patterns/memento/MementoPattern/Caretaker.cs
Normal file
24
patterns/memento/MementoPattern/Caretaker.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace MementoPattern;
|
||||
|
||||
public class Caretaker
|
||||
{
|
||||
//container that could hold memento of Originator
|
||||
//object
|
||||
private readonly Stack<IMemento> _mementos = new();
|
||||
private readonly IOriginator _originator;
|
||||
|
||||
public Caretaker(IOriginator originator)
|
||||
{
|
||||
_originator = originator;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
_mementos.Push(_originator.GetMemento());
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
_originator.SetMemento(_mementos.Pop());
|
||||
}
|
||||
}
|
||||
3
patterns/memento/MementoPattern/IMemento.cs
Normal file
3
patterns/memento/MementoPattern/IMemento.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace MementoPattern;
|
||||
|
||||
public interface IMemento { }
|
||||
7
patterns/memento/MementoPattern/IOriginator.cs
Normal file
7
patterns/memento/MementoPattern/IOriginator.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace MementoPattern;
|
||||
|
||||
public interface IOriginator
|
||||
{
|
||||
IMemento GetMemento();
|
||||
void SetMemento(IMemento memento);
|
||||
}
|
||||
8
patterns/memento/MementoPattern/MementoPattern.csproj
Normal file
8
patterns/memento/MementoPattern/MementoPattern.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
46
patterns/memento/MementoPattern/Originator.cs
Normal file
46
patterns/memento/MementoPattern/Originator.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
namespace MementoPattern;
|
||||
|
||||
public class Originator : IOriginator
|
||||
{
|
||||
private Guid _id;
|
||||
|
||||
public Originator()
|
||||
{
|
||||
_id = Guid.NewGuid();
|
||||
Console.WriteLine($"Starting ID: {_id}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public IMemento GetMemento()
|
||||
{
|
||||
Memento memento = new Memento();
|
||||
memento.Id = _id;
|
||||
Console.WriteLine("Creating Memento...");
|
||||
Console.WriteLine();
|
||||
return memento;
|
||||
}
|
||||
|
||||
public void SetMemento(IMemento memento)
|
||||
{
|
||||
if (!(memento is Memento))
|
||||
return;
|
||||
Console.WriteLine("Restting ID...");
|
||||
_id = (memento as Memento).Id;
|
||||
|
||||
Console.WriteLine($"ID is reset to {_id}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public void UpdateId()
|
||||
{
|
||||
Console.WriteLine("Updating Id...");
|
||||
_id = Guid.NewGuid();
|
||||
Console.WriteLine($"Updated ID is now {_id}");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
private class Memento : IMemento
|
||||
{
|
||||
public Guid Id;
|
||||
}
|
||||
}
|
||||
45
patterns/memento/MementoPattern/Program.cs
Normal file
45
patterns/memento/MementoPattern/Program.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace MementoPattern;
|
||||
|
||||
public class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Originator originator = new Originator();
|
||||
Caretaker caretaker = new Caretaker(originator);
|
||||
|
||||
caretaker.Save();
|
||||
Console.WriteLine(
|
||||
"After the first save, the originator's first ID is saved as a memento and pushed on the caretaker's stack. Enter any input to continue."
|
||||
);
|
||||
Console.ReadLine();
|
||||
|
||||
originator.UpdateId();
|
||||
originator.UpdateId();
|
||||
|
||||
caretaker.Save();
|
||||
Console.WriteLine(
|
||||
"After two updates and a save, only the second update is saved as a memento and pushed on the caretaker's stack. Enter any input to continue."
|
||||
);
|
||||
Console.ReadLine();
|
||||
|
||||
originator.UpdateId();
|
||||
caretaker.Undo();
|
||||
|
||||
Console.WriteLine(
|
||||
"After this latest update, since we called Undo() the ID will be changed from the latest updated ID to the prior one (i.e. the latest one that was actually saved to the stack). This is the main point of memento. Enter any input to continue."
|
||||
);
|
||||
Console.ReadLine();
|
||||
|
||||
originator.UpdateId();
|
||||
caretaker.Save();
|
||||
|
||||
Console.WriteLine(
|
||||
"A new ID is updated and pushed onto the stack. Enter any input to continue."
|
||||
);
|
||||
Console.ReadLine();
|
||||
|
||||
originator.UpdateId();
|
||||
caretaker.Undo();
|
||||
caretaker.Undo();
|
||||
}
|
||||
}
|
||||
94
patterns/observer/ObserverPattern/Program.cs
Normal file
94
patterns/observer/ObserverPattern/Program.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
namespace UpdatedOne;
|
||||
|
||||
public interface IObserver<TSubject>
|
||||
{
|
||||
void Update(TSubject subject);
|
||||
}
|
||||
|
||||
public abstract class Subject<TSubject>
|
||||
{
|
||||
private readonly List<IObserver<TSubject>> _observers = new();
|
||||
|
||||
public void Subscribe(IObserver<TSubject> observer)
|
||||
{
|
||||
if (!_observers.Contains(observer))
|
||||
_observers.Add(observer);
|
||||
}
|
||||
|
||||
public void Unsubscribe(IObserver<TSubject> observer)
|
||||
{
|
||||
_observers.Remove(observer);
|
||||
}
|
||||
|
||||
protected void Notify(TSubject subject)
|
||||
{
|
||||
foreach (IObserver<TSubject> observer in _observers.ToArray())
|
||||
observer.Update(subject);
|
||||
}
|
||||
}
|
||||
|
||||
public class Data : Subject<Data>
|
||||
{
|
||||
private int _value;
|
||||
|
||||
public Data(int value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public void SetData(int value)
|
||||
{
|
||||
if (_value == value)
|
||||
return;
|
||||
|
||||
_value = value;
|
||||
|
||||
Console.WriteLine($"Data changed to {_value}");
|
||||
|
||||
Notify(this);
|
||||
}
|
||||
|
||||
public int GetData()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
public class BarGraph : IObserver<Data>
|
||||
{
|
||||
public void Update(Data subject)
|
||||
{
|
||||
int value = subject.GetData();
|
||||
|
||||
Console.WriteLine($"Bar Graph updated: {value}");
|
||||
}
|
||||
}
|
||||
|
||||
public class PieChart : IObserver<Data>
|
||||
{
|
||||
public void Update(Data subject)
|
||||
{
|
||||
int value = subject.GetData();
|
||||
|
||||
Console.WriteLine($"Pie Chart updated: {value}");
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static void Main()
|
||||
{
|
||||
Data data = new Data(2);
|
||||
|
||||
BarGraph barGraph = new BarGraph();
|
||||
PieChart pieChart = new PieChart();
|
||||
|
||||
data.Subscribe(barGraph);
|
||||
data.Subscribe(pieChart);
|
||||
|
||||
data.SetData(3);
|
||||
|
||||
data.Unsubscribe(barGraph);
|
||||
data.Unsubscribe(pieChart);
|
||||
}
|
||||
}
|
||||
8
patterns/observer/ObserverPattern/UpdatedOne.csproj
Normal file
8
patterns/observer/ObserverPattern/UpdatedOne.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
6
patterns/state/BadCarState/BadCarState.csproj
Normal file
6
patterns/state/BadCarState/BadCarState.csproj
Normal file
@@ -0,0 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
81
patterns/state/BadCarState/Car.cs
Normal file
81
patterns/state/BadCarState/Car.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace BadCarState;
|
||||
|
||||
public class Car
|
||||
{
|
||||
private State _state = State.Off;
|
||||
|
||||
public bool HandleInput(string input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case "turn-clockwise":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Off:
|
||||
Console.WriteLine("The engine has started");
|
||||
Console.WriteLine();
|
||||
_state = State.Stopped;
|
||||
break;
|
||||
case State.Stopped:
|
||||
case State.Driving:
|
||||
Console.WriteLine("You hear a grinding noise...");
|
||||
Console.WriteLine();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "turn-counter":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Stopped:
|
||||
Console.WriteLine("The engine has stopped");
|
||||
Console.WriteLine();
|
||||
_state = State.Off;
|
||||
break;
|
||||
case State.Driving:
|
||||
Console.WriteLine(
|
||||
"The engine turns off, and the car stops suddenly"
|
||||
);
|
||||
Console.WriteLine();
|
||||
_state = State.Off;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "gas":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Stopped:
|
||||
Console.WriteLine("The car begins to drive");
|
||||
Console.WriteLine();
|
||||
_state = State.Driving;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "brake":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Driving:
|
||||
Console.WriteLine("The car slows to a stop");
|
||||
Console.WriteLine();
|
||||
_state = State.Stopped;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "exit":
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private enum State
|
||||
{
|
||||
Off,
|
||||
Stopped,
|
||||
Driving,
|
||||
}
|
||||
}
|
||||
41
patterns/state/BadCarState/Program.cs
Normal file
41
patterns/state/BadCarState/Program.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace BadCarState;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var car = new Car();
|
||||
|
||||
string input;
|
||||
bool keepRunning = true;
|
||||
|
||||
Console.WriteLine("Welcome to the Driving Simulater");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(" turn-clockwise -Turns the car's key clockwise");
|
||||
Console.WriteLine(
|
||||
" turn-counter -Turns the car's key counter clockwise"
|
||||
);
|
||||
Console.WriteLine(" gas -Presses the gas pedal");
|
||||
Console.WriteLine(" brake -Presses the brake pedal");
|
||||
Console.WriteLine(" exit -Exits the simulator");
|
||||
Console.WriteLine();
|
||||
|
||||
do
|
||||
{
|
||||
Console.Write("> ");
|
||||
input = Console.ReadLine();
|
||||
Console.WriteLine();
|
||||
keepRunning = car.HandleInput(input);
|
||||
} while (keepRunning);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("goodbye");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
44
patterns/state/CarState/Car.cs
Normal file
44
patterns/state/CarState/Car.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
#region
|
||||
|
||||
using CarState.States;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CarState;
|
||||
|
||||
public class Car
|
||||
{
|
||||
private State _state;
|
||||
|
||||
public Car()
|
||||
{
|
||||
ChangeState(new Off(this));
|
||||
}
|
||||
|
||||
public bool HandleInput(string input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case "turn-clockwise":
|
||||
_state.TurnKeyClockwise();
|
||||
break;
|
||||
case "turn-counter":
|
||||
_state.TurnKeyCounterClockwise();
|
||||
break;
|
||||
case "gas":
|
||||
_state.PressGas();
|
||||
break;
|
||||
case "brake":
|
||||
_state.PressBrake();
|
||||
break;
|
||||
case "exit":
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ChangeState(State state)
|
||||
{
|
||||
_state = state;
|
||||
}
|
||||
}
|
||||
6
patterns/state/CarState/CarState.csproj
Normal file
6
patterns/state/CarState/CarState.csproj
Normal file
@@ -0,0 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
41
patterns/state/CarState/Program.cs
Normal file
41
patterns/state/CarState/Program.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CarState;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var car = new Car();
|
||||
|
||||
string input;
|
||||
bool keepRunning = true;
|
||||
|
||||
Console.WriteLine("Welcome to the Driving Simulater");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(" turn-clockwise -Turns the car's key clockwise");
|
||||
Console.WriteLine(
|
||||
" turn-counter -Turns the car's key counter clockwise"
|
||||
);
|
||||
Console.WriteLine(" gas -Presses the gas pedal");
|
||||
Console.WriteLine(" brake -Presses the brake pedal");
|
||||
Console.WriteLine(" exit -Exits the simulator");
|
||||
Console.WriteLine();
|
||||
|
||||
do
|
||||
{
|
||||
Console.Write("> ");
|
||||
input = Console.ReadLine();
|
||||
Console.WriteLine();
|
||||
keepRunning = car.HandleInput(input);
|
||||
} while (keepRunning);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("goodbye");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
33
patterns/state/CarState/States/Driving.cs
Normal file
33
patterns/state/CarState/States/Driving.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CarState.States;
|
||||
|
||||
public class Driving : State
|
||||
{
|
||||
public Driving(Car car)
|
||||
: base(car) { }
|
||||
|
||||
public override void TurnKeyClockwise()
|
||||
{
|
||||
Console.WriteLine("You hear a grinding noise...");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public override void TurnKeyCounterClockwise()
|
||||
{
|
||||
Console.WriteLine("The engine turns off, and the car stops suddenly");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Off(_car));
|
||||
}
|
||||
|
||||
public override void PressBrake()
|
||||
{
|
||||
Console.WriteLine("The car slows to a stop");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Stopped(_car));
|
||||
}
|
||||
}
|
||||
20
patterns/state/CarState/States/Off.cs
Normal file
20
patterns/state/CarState/States/Off.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CarState.States;
|
||||
|
||||
public class Off : State
|
||||
{
|
||||
public Off(Car car)
|
||||
: base(car) { }
|
||||
|
||||
public override void TurnKeyClockwise()
|
||||
{
|
||||
Console.WriteLine("The engine has started");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Stopped(_car));
|
||||
}
|
||||
}
|
||||
19
patterns/state/CarState/States/State.cs
Normal file
19
patterns/state/CarState/States/State.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace CarState.States;
|
||||
|
||||
public class State
|
||||
{
|
||||
protected Car _car;
|
||||
|
||||
public State(Car car)
|
||||
{
|
||||
_car = car;
|
||||
}
|
||||
|
||||
public virtual void TurnKeyClockwise() { }
|
||||
|
||||
public virtual void TurnKeyCounterClockwise() { }
|
||||
|
||||
public virtual void PressGas() { }
|
||||
|
||||
public virtual void PressBrake() { }
|
||||
}
|
||||
33
patterns/state/CarState/States/Stopped.cs
Normal file
33
patterns/state/CarState/States/Stopped.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#region
|
||||
|
||||
using System;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CarState.States;
|
||||
|
||||
public class Stopped : State
|
||||
{
|
||||
public Stopped(Car car)
|
||||
: base(car) { }
|
||||
|
||||
public override void PressGas()
|
||||
{
|
||||
Console.WriteLine("The car begins to drive");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Driving(_car));
|
||||
}
|
||||
|
||||
public override void TurnKeyClockwise()
|
||||
{
|
||||
Console.WriteLine("You hear a grinding noise...");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public override void TurnKeyCounterClockwise()
|
||||
{
|
||||
Console.WriteLine("The engine has stopped");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Off(_car));
|
||||
}
|
||||
}
|
||||
44
patterns/state/WithStatePattern/Car.cs
Normal file
44
patterns/state/WithStatePattern/Car.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
#region
|
||||
|
||||
using WithStatePattern.States;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace WithStatePattern;
|
||||
|
||||
public class Car
|
||||
{
|
||||
private State _state;
|
||||
|
||||
public Car()
|
||||
{
|
||||
ChangeState(new Off(this));
|
||||
}
|
||||
|
||||
public bool HandleInput(string input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case "turn-clockwise":
|
||||
_state.TurnKeyClockwise();
|
||||
break;
|
||||
case "turn-counter":
|
||||
_state.TurnKeyCounterClockwise();
|
||||
break;
|
||||
case "gas":
|
||||
_state.PressGas();
|
||||
break;
|
||||
case "brake":
|
||||
_state.PressBrake();
|
||||
break;
|
||||
case "exit":
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ChangeState(State state)
|
||||
{
|
||||
_state = state;
|
||||
}
|
||||
}
|
||||
35
patterns/state/WithStatePattern/Program.cs
Normal file
35
patterns/state/WithStatePattern/Program.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace WithStatePattern;
|
||||
|
||||
public class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var car = new Car();
|
||||
|
||||
string input;
|
||||
bool keepRunning = true;
|
||||
|
||||
Console.WriteLine("Welcome to the Driving Simulater");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(" turn-clockwise -Turns the car's key clockwise");
|
||||
Console.WriteLine(
|
||||
" turn-counter -Turns the car's key counter clockwise"
|
||||
);
|
||||
Console.WriteLine(" gas -Presses the gas pedal");
|
||||
Console.WriteLine(" brake -Presses the brake pedal");
|
||||
Console.WriteLine(" exit -Exits the simulator");
|
||||
Console.WriteLine();
|
||||
|
||||
do
|
||||
{
|
||||
Console.Write("> ");
|
||||
input = Console.ReadLine();
|
||||
Console.WriteLine();
|
||||
keepRunning = car.HandleInput(input);
|
||||
} while (keepRunning);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("goodbye");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
27
patterns/state/WithStatePattern/States/Driving.cs
Normal file
27
patterns/state/WithStatePattern/States/Driving.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace WithStatePattern.States;
|
||||
|
||||
public class Driving : State
|
||||
{
|
||||
public Driving(Car car)
|
||||
: base(car) { }
|
||||
|
||||
public override void TurnKeyClockwise()
|
||||
{
|
||||
Console.WriteLine("You hear a grinding noise...");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public override void TurnKeyCounterClockwise()
|
||||
{
|
||||
Console.WriteLine("The engine turns off, and the car stops suddenly");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Off(_car));
|
||||
}
|
||||
|
||||
public override void PressBrake()
|
||||
{
|
||||
Console.WriteLine("The car slows to a stop");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Stopped(_car));
|
||||
}
|
||||
}
|
||||
14
patterns/state/WithStatePattern/States/Off.cs
Normal file
14
patterns/state/WithStatePattern/States/Off.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace WithStatePattern.States;
|
||||
|
||||
public class Off : State
|
||||
{
|
||||
public Off(Car car)
|
||||
: base(car) { }
|
||||
|
||||
public override void TurnKeyClockwise()
|
||||
{
|
||||
Console.WriteLine("The engine has started");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Stopped(_car));
|
||||
}
|
||||
}
|
||||
19
patterns/state/WithStatePattern/States/State.cs
Normal file
19
patterns/state/WithStatePattern/States/State.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace WithStatePattern.States;
|
||||
|
||||
public class State
|
||||
{
|
||||
protected Car _car;
|
||||
|
||||
public State(Car car)
|
||||
{
|
||||
_car = car;
|
||||
}
|
||||
|
||||
public virtual void TurnKeyClockwise() { }
|
||||
|
||||
public virtual void TurnKeyCounterClockwise() { }
|
||||
|
||||
public virtual void PressGas() { }
|
||||
|
||||
public virtual void PressBrake() { }
|
||||
}
|
||||
27
patterns/state/WithStatePattern/States/Stopped.cs
Normal file
27
patterns/state/WithStatePattern/States/Stopped.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace WithStatePattern.States;
|
||||
|
||||
public class Stopped : State
|
||||
{
|
||||
public Stopped(Car car)
|
||||
: base(car) { }
|
||||
|
||||
public override void PressGas()
|
||||
{
|
||||
Console.WriteLine("The car begins to drive");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Driving(_car));
|
||||
}
|
||||
|
||||
public override void TurnKeyClockwise()
|
||||
{
|
||||
Console.WriteLine("You hear a grinding noise...");
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
public override void TurnKeyCounterClockwise()
|
||||
{
|
||||
Console.WriteLine("The engine has stopped");
|
||||
Console.WriteLine();
|
||||
_car.ChangeState(new Off(_car));
|
||||
}
|
||||
}
|
||||
8
patterns/state/WithStatePattern/WithStatePattern.csproj
Normal file
8
patterns/state/WithStatePattern/WithStatePattern.csproj
Normal file
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
75
patterns/state/WithoutStatePattern/Car.cs
Normal file
75
patterns/state/WithoutStatePattern/Car.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
namespace WithoutStatePattern;
|
||||
|
||||
public class Car
|
||||
{
|
||||
private State _state = State.Off;
|
||||
|
||||
public bool HandleInput(string input)
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case "turn-clockwise":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Off:
|
||||
Console.WriteLine("The engine has started");
|
||||
Console.WriteLine();
|
||||
_state = State.Stopped;
|
||||
break;
|
||||
case State.Stopped:
|
||||
case State.Driving:
|
||||
Console.WriteLine("You hear a grinding noise...");
|
||||
Console.WriteLine();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "turn-counter":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Stopped:
|
||||
Console.WriteLine("The engine has stopped");
|
||||
Console.WriteLine();
|
||||
_state = State.Off;
|
||||
break;
|
||||
case State.Driving:
|
||||
Console.WriteLine(
|
||||
"The engine turns off, and the car stops suddenly"
|
||||
);
|
||||
Console.WriteLine();
|
||||
_state = State.Off;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "gas":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Stopped:
|
||||
Console.WriteLine("The car begins to drive");
|
||||
Console.WriteLine();
|
||||
_state = State.Driving;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "brake":
|
||||
switch (_state)
|
||||
{
|
||||
case State.Driving:
|
||||
Console.WriteLine("The car slows to a stop");
|
||||
Console.WriteLine();
|
||||
_state = State.Stopped;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "exit":
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private enum State
|
||||
{
|
||||
Off,
|
||||
Stopped,
|
||||
Driving,
|
||||
}
|
||||
}
|
||||
35
patterns/state/WithoutStatePattern/Program.cs
Normal file
35
patterns/state/WithoutStatePattern/Program.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace WithoutStatePattern;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var car = new Car();
|
||||
|
||||
string input;
|
||||
bool keepRunning = true;
|
||||
|
||||
Console.WriteLine("Welcome to the Driving Simulater");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(" turn-clockwise -Turns the car's key clockwise");
|
||||
Console.WriteLine(
|
||||
" turn-counter -Turns the car's key counter clockwise"
|
||||
);
|
||||
Console.WriteLine(" gas -Presses the gas pedal");
|
||||
Console.WriteLine(" brake -Presses the brake pedal");
|
||||
Console.WriteLine(" exit -Exits the simulator");
|
||||
Console.WriteLine();
|
||||
|
||||
do
|
||||
{
|
||||
Console.Write("> ");
|
||||
input = Console.ReadLine();
|
||||
Console.WriteLine();
|
||||
keepRunning = car.HandleInput(input);
|
||||
} while (keepRunning);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("goodbye");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user