Skip to content

Commit e5d68b8

Browse files
committed
Add Bridge Design Pattern implementation
Implemented the Bridge Design Pattern with new classes (`Tv`, `Radio`, `RemoteControl`, `AdvancedRemote`) and the `IDevice` interface in the `DesignPatterns.Bridge` namespace. This decouples abstraction (`RemoteControl`) from implementation (`Tv`, `Radio`). Updated `Program.cs` to include a demo of the Bridge pattern, showcasing device control features like toggling power, adjusting volume, muting, and setting channels. Updated `README.md` to document the Bridge pattern, including its purpose, usage example, and test coverage. Added `BridgeTests.cs` with unit tests for `RemoteControl` and `AdvancedRemote` to verify functionality with `Tv` and `Radio`. Introduced `AdvancedRemote` with a `Mute` method, `IDevice` interface for device abstraction, and `Tv` and `Radio` classes as device implementations.
1 parent 595dcaf commit e5d68b8

File tree

8 files changed

+136
-1
lines changed

8 files changed

+136
-1
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace DesignPatterns.Bridge;
2+
3+
public class AdvancedRemote : RemoteControl
4+
{
5+
public AdvancedRemote(IDevice device) : base(device) { }
6+
7+
public void Mute() => Device.SetVolume(0);
8+
}

DesignPatterns/Bridge/IDevice.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace DesignPatterns.Bridge;
2+
3+
public interface IDevice
4+
{
5+
bool IsEnabled { get; }
6+
int Volume { get; }
7+
int Channel { get; }
8+
9+
void Enable();
10+
void Disable();
11+
void SetVolume(int percent); // 0 - 100
12+
void SetChannel(int channel);
13+
}

DesignPatterns/Bridge/Radio.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace DesignPatterns.Bridge;
2+
3+
public class Radio : IDevice
4+
{
5+
public bool IsEnabled { get; private set; }
6+
public int Volume { get; private set; }
7+
public int Channel { get; private set; }
8+
9+
public void Enable() => IsEnabled = true;
10+
public void Disable() => IsEnabled = false;
11+
public void SetVolume(int percent) => Volume = Math.Clamp(percent, 0, 100);
12+
public void SetChannel(int channel) => Channel = channel;
13+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace DesignPatterns.Bridge;
2+
3+
public class RemoteControl
4+
{
5+
protected IDevice Device;
6+
7+
public RemoteControl(IDevice device)
8+
{
9+
Device = device;
10+
}
11+
12+
public virtual void TogglePower()
13+
{
14+
if (Device.IsEnabled) Device.Disable(); else Device.Enable();
15+
}
16+
17+
public virtual void VolumeUp() => Device.SetVolume(Device.Volume + 10);
18+
public virtual void VolumeDown() => Device.SetVolume(Device.Volume - 10);
19+
public virtual void SetChannel(int channel) => Device.SetChannel(channel);
20+
}

DesignPatterns/Bridge/Tv.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace DesignPatterns.Bridge;
2+
3+
public class Tv : IDevice
4+
{
5+
public bool IsEnabled { get; private set; }
6+
public int Volume { get; private set; }
7+
public int Channel { get; private set; }
8+
9+
public void Enable() => IsEnabled = true;
10+
public void Disable() => IsEnabled = false;
11+
public void SetVolume(int percent) => Volume = Math.Clamp(percent, 0, 100);
12+
public void SetChannel(int channel) => Channel = channel;
13+
}

DesignPatterns/Program.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using DesignPatterns.Prototype;
55
using DesignPatterns.AbstractFactory;
66
using DesignPatterns.Adapter;
7+
using DesignPatterns.Bridge;
78

89
Console.WriteLine("Factory pattern demo:");
910

@@ -59,6 +60,22 @@
5960
ITextProvider provider = new LegacyTextAdapter(legacy);
6061
Console.WriteLine(provider.GetText());
6162

63+
// Bridge demo
64+
Console.WriteLine();
65+
Console.WriteLine("Bridge pattern demo:");
66+
var tv = new Tv();
67+
var remote = new RemoteControl(tv);
68+
remote.TogglePower();
69+
remote.VolumeUp();
70+
remote.SetChannel(10);
71+
Console.WriteLine($"TV - Enabled: {tv.IsEnabled}, Volume: {tv.Volume}, Channel: {tv.Channel}");
72+
73+
var radio = new Radio();
74+
var adv = new AdvancedRemote(radio);
75+
adv.VolumeUp();
76+
adv.Mute();
77+
Console.WriteLine($"Radio - Enabled: {radio.IsEnabled}, Volume: {radio.Volume}, Channel: {radio.Channel}");
78+
6279
// Singleton demo
6380
Logger.Instance.Clear();
6481
Logger.Instance.Log("Singleton started");

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ Design Patterns Examples
33
This solution demonstrates simple design pattern examples in C# targeting .NET 10 (C# 14).
44

55
Projects
6-
- `DesignPatterns` - Console demo showing Factory, Singleton, Builder, Prototype, Abstract Factory, and Adapter patterns.
6+
- `DesignPatterns` - Console demo showing Factory, Singleton, Builder, Prototype, Abstract Factory, Adapter, and Bridge patterns.
77
- Factory implementation: `DesignPatterns/Factories`
88
- Singleton implementation: `DesignPatterns/Singleton/Logger.cs`
99
- Builder implementation: `DesignPatterns/Builder/HouseBuilder.cs` and `DesignPatterns/Builder/House.cs`
1010
- Prototype implementation: `DesignPatterns/Prototype/Person.cs` and `DesignPatterns/Prototype/Address.cs`
1111
- Abstract Factory implementation: `DesignPatterns/AbstractFactory/*`
1212
- Adapter implementation: `DesignPatterns/Adapter/*`
13+
- Bridge implementation: `DesignPatterns/Bridge/*`
1314
- `Tests` - xUnit tests covering the examples.
1415

1516
Included patterns and brief docs
@@ -79,6 +80,19 @@ Included patterns and brief docs
7980
Console.WriteLine(provider.GetText());
8081
```
8182
83+
- Bridge Pattern
84+
- Purpose: Decouple an abstraction from its implementation so the two can vary independently.
85+
- Example: `DesignPatterns/Bridge/*` provides `IDevice` implementations (`Tv`, `Radio`) and abstractions (`RemoteControl`, `AdvancedRemote`).
86+
- Usage snippet:
87+
88+
```csharp
89+
var tv = new Tv();
90+
var remote = new RemoteControl(tv);
91+
remote.TogglePower();
92+
remote.VolumeUp();
93+
remote.SetChannel(10);
94+
```
95+
8296
Tests
8397
- Tests are written with xUnit in the `Tests` project.
8498
- Factory tests: `Tests/ShapeFactoryTests.cs`
@@ -87,6 +101,7 @@ Tests
87101
- Prototype tests: `Tests/PrototypeTests.cs`
88102
- Abstract Factory tests: `Tests/AbstractFactoryTests.cs`
89103
- Adapter tests: `Tests/AdapterTests.cs`
104+
- Bridge tests: `Tests/BridgeTests.cs`
90105
91106
Requirements
92107
- .NET 10 SDK

Tests/BridgeTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using DesignPatterns.Bridge;
2+
3+
namespace Tests;
4+
5+
public class BridgeTests
6+
{
7+
[Fact]
8+
public void RemoteControl_CanToggleDeviceAndChangeVolume()
9+
{
10+
var tv = new Tv();
11+
var remote = new RemoteControl(tv);
12+
13+
Assert.False(tv.IsEnabled);
14+
remote.TogglePower();
15+
Assert.True(tv.IsEnabled);
16+
17+
remote.VolumeUp();
18+
Assert.Equal(10, tv.Volume);
19+
20+
remote.SetChannel(5);
21+
Assert.Equal(5, tv.Channel);
22+
}
23+
24+
[Fact]
25+
public void AdvancedRemote_Mute_SetsVolumeToZero()
26+
{
27+
var radio = new Radio();
28+
var remote = new AdvancedRemote(radio);
29+
30+
remote.VolumeUp(); // 10
31+
Assert.Equal(10, radio.Volume);
32+
33+
remote.Mute();
34+
Assert.Equal(0, radio.Volume);
35+
}
36+
}

0 commit comments

Comments
 (0)