Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions AdapterPattern/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Adapter Pattern

This folder demonstrates the Adapter design pattern in C# using a turkey-to-duck adapter example.

## Pattern overview

Adapter lets incompatible interfaces work together. It wraps one object with another adapter so it can be used as if it implemented a target interface.

In this example:

- `IDuck` is the target interface used by client code.
- `ITurkey` is the adaptee interface that has a different API.
- `TurkeyAdapter` converts `ITurkey` callbacks (`Gobble`, `Fly`) into `IDuck` actions (`Quack`, `Fly`).

## Project structure

- `IDuck.cs`: duck contract with `Quack()` and `Fly()`.
- `ITurkey.cs`: turkey contract with `Gobble()` and `Fly()`.
- `WildTurkey.cs`: concrete turkey implementation.
- `TurkeyAdapter.cs`: adapter implementing `IDuck` by delegating to `ITurkey`.
- `Program.cs`: test harness that uses `TurkeyAdapter` where an `IDuck` is expected.

## Behavior details

- `TurkeyAdapter.Quack()` calls `ITurkey.Gobble()`.
- `TurkeyAdapter.Fly()` calls `ITurkey.Fly()` multiple times to compensate for turkey’s short flight capability (adaptation logic in code).

## Usage

```csharp
var turkey = new WildTurkey();
var adapter = new TurkeyAdapter(turkey);
Tester(adapter);

static void Tester(IDuck duck)
{
duck.Fly();
duck.Quack();
}
```

## Why this pattern is useful

- Provides compatibility between otherwise incompatible components.
- Supports reuse of existing implementations without modifying them.
- Decouples client code from concrete adaptee classes.
50 changes: 50 additions & 0 deletions BridgePattern/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Bridge Pattern

This folder implements the Bridge design pattern in C# illustrating how weapons and enchantments are decoupled.

## Pattern overview

Bridge separates an abstraction from its implementation so they can vary independently. In this example, weapons are the abstractions and enchantments are the implementations.

- `IWeapon` is the abstraction interface.
- `IEnchantment` is the implementation interface.
- `Sword` and `Hammer` are concrete abstractions.
- `FlyingEnchantment` and `SoulEatingEnchantment` are concrete implementations.

## How it works

Each `IWeapon` holds an `IEnchantment`. Weapon methods delegate behavior to the enchantment, allowing any weapon to be combined with any enchantment:

- `Wield()` calls `IEnchantment.OnActivate()`
- `Swing()` calls `IEnchantment.Apply()`
- `Unwield()` calls `IEnchantment.OnDeactivate()`

This keeps weapon and enchantment hierarchies independent and reusable.

## Project files

- `IWeapon.cs`: abstraction interface.
- `IEnchantment.cs`: implementor interface.
- `Sword.cs`, `Hammer.cs`: concrete abstractions.
- `FlyingEnchantment.cs`, `SoulEatingEnchantment.cs`: concrete implementors.
- `Program.cs`: sample usage.

## Example usage

```csharp
IWeapon sword = new Sword(new FlyingEnchantment());
sword.Wield();
sword.Swing();
sword.Unwield();

IWeapon hammer = new Hammer(new SoulEatingEnchantment());
hammer.Wield();
hammer.Swing();
hammer.Unwield();
```

## Why this pattern is useful

- Adds flexibility by enabling combinations (weapon + enchantment) without class explosion.
- Reduces coupling and improves maintainability.
- Makes it easy to add new weapons or enchantments independently.
50 changes: 50 additions & 0 deletions BuilderPattern/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Builder Pattern

This folder implements the Builder design pattern in C# using hamburger construction examples.

## Pattern overview

Builder decouples the construction of a complex object from its representation, allowing the same construction process to create different representations.

- `IBuilder` defines steps for building a product.
- `Hamburger` is the product being created.
- `MyHamburgerBuilder` and `WifesHamburgerBuilder` are concrete builders with different configurations.
- `Cook` acts as the director and executes build steps in a fixed order.

## How it works

1. `Cook` is initialized with an `IBuilder`.
2. `Cook.Build()` calls:
- `AddIngredients()`
- `AddShape()`
- `AddSize()`
3. After steps complete, `Cook` returns `builder.Build()`.
4. `Cook.ChangeBuilder()` switches builder implementations at runtime.

## Project files

- `IBuilder.cs`: builder interface.
- `Hamburger.cs`: product class.
- `Cook.cs`: director.
- `MyHamburgerBuilder.cs` / `WifesHamburgerBuilder.cs`: concrete builders.
- `Program.cs`: sample usage.

## Usage

```csharp
var builder = new MyHamburgerBuilder();
var cook = new Cook(builder);
var myHamburger = cook.Build();

cook.ChangeBuilder(new WifesHamburgerBuilder());
var wifesHamburger = cook.Build();

Console.WriteLine($"My Hamburger: {myHamburger}");
Console.WriteLine($"My Wife's Hamburger: {wifesHamburger}");
```

## Benefits

- Builds different product variants with shared construction logic.
- Improves code reuse and maintainability.
- Changes to builder steps do not affect director logic.
51 changes: 51 additions & 0 deletions ChainOfResponsibilityPattern/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Chain of Responsibility Pattern

This folder implements the Chain of Responsibility design pattern in C# using mathematical operation handlers.

## Pattern overview

Chain of Responsibility allows passing requests along a chain of handlers. Each handler decides whether to process the request or pass it to the next handler in the chain.

In this example:

- Handlers process mathematical operations ("Add", "Minus", "Multiply").
- Each handler checks if it can handle the operation; if not, it delegates to the next.
- If no handler can process the request, it returns null.

## Project structure

- `IHandler.cs`: interface with `AddChain()` and `Handle()`.
- `BaseHandler.cs`: abstract base implementing `AddChain()` and holding `_nextInLine`.
- `AdditionHandler.cs`: handles "add" by summing values.
- `SubtractionHandler.cs`: handles "minus" by subtracting values.
- `MultiplicationHandler.cs`: handles "multiply" by multiplying values.
- `Program.cs`: sets up the chain and tests operations.

## How it works

1. Handlers are chained: Addition → Subtraction → Multiplication.
2. `Handle()` is called on the first handler.
3. Each handler checks the `action` string.
4. If it matches, performs the operation; else, calls `_nextInLine.Handle()`.
5. Unhandled requests return null.

## Usage

```csharp
var additionHandler = new AdditionHandler();
var subtractionHandler = new SubtractionHandler();
var multiplicationHandler = new MultiplicationHandler();

subtractionHandler.AddChain(multiplicationHandler);
additionHandler.AddChain(subtractionHandler);

double[] numbers = { 2, 3, 4, 5 };
var result = additionHandler.Handle(numbers, "Add"); // 14.0
```

## Why this pattern is useful

- Decouples sender from receiver.
- Allows dynamic handler chains.
- Promotes loose coupling and extensibility.
- Easy to add new handlers without changing existing code.
54 changes: 54 additions & 0 deletions CommandPattern/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Command Pattern

This folder implements the Command design pattern in C# using a remote control example with garage doors and lights.

## Pattern overview

Command encapsulates a request as an object, allowing parameterization of clients with queues, requests, and operations. It also supports undoable operations.

In this example:

- `ICommand` defines `Execute()` and `Undo()`.
- Concrete commands (e.g., `GarageDoorOpenCommand`) encapsulate receivers and actions.
- `RemoteControl` acts as the invoker, storing and executing commands.
- `MacroCommand` composes multiple commands for batch operations.

## Project structure

- `ICommand.cs`: command interface.
- `RemoteControl.cs`: invoker with slots for on/off commands and undo.
- `GarageDoorOpenCommand.cs`, `GarageDoorCloseCommand.cs`: concrete commands for garage.
- `LightOnCommand.cs`, `LightOffCommand.cs`: concrete commands for light.
- `MacroCommand.cs`: composite command for multiple actions.
- `NoCommand.cs`: null object for empty slots.
- `OnOffStruct.cs`: struct for on/off command pairs.
- `Garage.cs`, `Light.cs`: receivers.
- `Program.cs`: demo usage.

## How it works

1. Commands are assigned to remote slots (on/off pairs).
2. `PushOn(slot)` executes the on command and sets undo to off.
3. `PushOff(slot)` executes the off command and sets undo to on.
4. `PushUndo()` executes the last command's opposite.
5. Macro commands execute multiple commands in sequence.

## Usage

```csharp
var remote = new RemoteControl(3);
var garage = new Garage("Bike");
var openCmd = new GarageDoorOpenCommand(garage);
var closeCmd = new GarageDoorCloseCommand(garage);

remote[0] = new OnOffStruct { On = openCmd, Off = closeCmd };
remote.PushOn(0); // Opens garage
remote.PushUndo(); // Closes garage
```

## Why this pattern is useful

- Decouples invoker from receiver.
- Supports undo, redo, and macro operations.
- Enables queuing and logging of requests.
- Promotes extensibility by adding new commands without changing existing code.
47 changes: 47 additions & 0 deletions CompositePattern/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Composite Pattern

This folder implements the Composite design pattern in C# using a restaurant menu example.

## Pattern overview

Composite lets clients treat individual objects and compositions of objects uniformly. It composes objects into tree structures to represent part-whole hierarchies.

In this example:

- `MenuComponent` is the component interface.
- `Menu` is the composite, containing child components.
- `MenuItem` is the leaf, with no children.
- Clients call `Print()` on the root menu, which recursively prints the hierarchy.

## Project structure

- `MenuComponent.cs`: abstract component with common interface.
- `Menu.cs`: composite that holds and manages child components.
- `MenuItem.cs`: leaf component representing individual items.
- `Program.cs`: demo building a menu hierarchy and printing it.

## How it works

1. `Menu` implements `Add()`, `Remove()`, `GetChild()` to manage children.
2. `MenuItem` implements leaf-specific properties (name, price, etc.).
3. `Print()` is implemented in both:
- `Menu`: prints its name, then calls `Print()` on each child.
- `MenuItem`: prints item details.
4. Clients treat menus and items uniformly via `MenuComponent`.

## Usage

```csharp
var menu = new Menu("All", "McDonalds");
var breakfast = new Menu("Breakfast", "Pancake House");
menu.Add(breakfast);
breakfast.Add(new MenuItem("Waffles", "Butterscotch waffles", 140, false));
menu.Print(); // Prints entire hierarchy
```

## Why this pattern is useful

- Simplifies client code by treating composites and leaves uniformly.
- Makes it easy to add new component types.
- Supports complex tree structures with recursive operations.
- Promotes code reuse and consistency.
45 changes: 45 additions & 0 deletions DecoratorPattern/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Decorator Pattern

This folder implements the Decorator design pattern in C# using a coffee shop beverage example.

## Pattern overview

Decorator attaches additional responsibilities to an object dynamically. It provides a flexible alternative to subclassing for extending functionality.

In this example:

- `Beverage` is the component interface.
- `CondimentDecorator` is the decorator base.
- `Espresso`, `DarkRoast`, `HouseBlend` are concrete components.
- `MochaCondiment`, `WhipCondiment` are concrete decorators that wrap beverages.

## Project structure

- `Beverage.cs`: abstract component with `Description` and `Cost()`.
- `CondimentDecorator.cs`: abstract decorator extending `Beverage`.
- `Espresso.cs`, `DarkRoast.cs`, `HouseBlend.cs`: concrete beverages.
- `MochaCondiment.cs`, `WhipCondiment.cs`: concrete decorators adding condiments.
- `Program.cs`: demo wrapping beverages with multiple condiments.

## How it works

1. Decorators wrap components, delegating calls to the wrapped object.
2. Each decorator adds its own behavior (e.g., cost, description).
3. Multiple decorators can be stacked dynamically.
4. Clients treat decorated objects uniformly via the component interface.

## Usage

```csharp
Beverage beverage = new DarkRoast();
beverage = new MochaCondiment(beverage);
beverage = new WhipCondiment(beverage);
Console.WriteLine(beverage.Description + " $" + beverage.Cost());
```

## Why this pattern is useful

- Adds responsibilities without subclassing.
- Combines behaviors at runtime.
- Avoids class explosion from all possible combinations.
- Follows open-closed principle for extension.
Loading