Skip to content

Commit

Permalink
feat: Flyweight
Browse files Browse the repository at this point in the history
  • Loading branch information
treveshan committed Oct 2, 2024
1 parent 1dab361 commit 8712a51
Show file tree
Hide file tree
Showing 15 changed files with 280 additions and 205 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This project demonstrates various design patterns implemented in C#. Design patt
- [ ] Composite
- [ ] Decorator
- [ ] Facade
- [ ] Flyweight
- [X] Flyweight
- [ ] Proxy

3. **Behavioral Patterns**
Expand Down
1 change: 1 addition & 0 deletions src/Creational/AbstractFactory/AbstractFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using DesignPatterns.Creational.AbstractFactory.PolicyTypes.Car;
using DesignPatterns.Creational.AbstractFactory.PolicyTypes.Health;
using DesignPatterns.Creational.AbstractFactory.PolicyTypes.Home;
using DesignPatterns.Creational.FactoryMethod;
using DesignPatterns.Utils.Display;

namespace DesignPatterns.Creational.AbstractFactory;
Expand Down
5 changes: 3 additions & 2 deletions src/Creational/Builder/Builder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DesignPatterns.Utils.Display;
using DesignPatterns.Creational.FactoryMethod;
using DesignPatterns.Utils.Display;

namespace DesignPatterns.Creational.Builder;

Expand Down Expand Up @@ -51,7 +52,7 @@ public void Run(string policyType)
//5. **Learning Curve**:
// - For developers unfamiliar with design patterns, understanding and implementing the Builder pattern might require a learning curve, adding to the initial development time.

//### When to Use the Builder Pattern
//### When to Use the Builder IPattern

//- **Complex Construction Logic**: When the construction of an object involves many steps, and the object has many configurations.
//- **Immutability**: When you need to create immutable objects and want to provide a clear and concise way to construct them.
Expand Down
2 changes: 1 addition & 1 deletion src/Creational/FactoryMethod/FactoryMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace DesignPatterns.Creational.FactoryMethod;

public class FactoryMethod
public class FactoryMethod
{
private readonly IOutput _output;

Expand Down
8 changes: 3 additions & 5 deletions src/Creational/Prototype/Prototype.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@

using DesignPatterns.Creational.Builder;
using DesignPatterns.Utils.Display;
using DesignPatterns.Utils.Display;

namespace DesignPatterns.Creational.Prototype;

public class Prototype
public class Prototype
{
private readonly IOutput _output;

Expand All @@ -13,7 +11,7 @@ public Prototype(IOutput output)
_output = output;
}

public void Run()
public void Run(string policyType)
{

var originalPolicy = new InsurancePolicy()
Expand Down
5 changes: 3 additions & 2 deletions src/Creational/Singleton/Singleton.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DesignPatterns.Utils.Display;
using DesignPatterns.Creational.FactoryMethod;
using DesignPatterns.Utils.Display;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -16,7 +17,7 @@ public Singleton(IOutput output)
_output = output;
}

public void Run()
public void Run(string policyType)
{
// Access the singleton instance
InsurancePolicySingleton policy1 = InsurancePolicySingleton.Instance;
Expand Down
2 changes: 1 addition & 1 deletion src/DesignPatterns.Adapter/Adapter/Adapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace DesignPatterns.Structural.Adapter
{
public class Adapter
public class Adapter
{
private readonly IOutput _output;

Expand Down
2 changes: 1 addition & 1 deletion src/DesignPatterns.Adapter/Bridge/Bridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace DesignPatterns.Structural.Bridge
{
public class Bridge
public class Bridge
{
private readonly IOutput _output;

Expand Down
35 changes: 35 additions & 0 deletions src/DesignPatterns.Adapter/Flyweight/Flyweight.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using DesignPatterns.Utils.Display;

namespace DesignPatterns.Structural.Flyweight
{
public class Flyweight
{
private readonly IOutput _output;

public Flyweight(IOutput output)
{
_output = output;
}

public void Run()
{
var factory = new InsuranceTypeFactory();

// Shared insurance types
var healthType = factory.GetInsuranceType("Health", "Full Coverage");
var carType = factory.GetInsuranceType("Car", "Collision Coverage");

// Policies that share insurance types
var policy1 = new InsurancePolicy(healthType, "Mdu Doe", "P123456");
var policy2 = new InsurancePolicy(healthType, "Trev Doe", "P123457");
var policy3 = new InsurancePolicy(carType, "Dane", "P123458");
var policy4 = new InsurancePolicy(carType, "Menzi", "P123459");

// Display policy details
_output.Display(policy1.GetPolicyDetails());
_output.Display(policy2.GetPolicyDetails());
_output.Display(policy3.GetPolicyDetails());
_output.Display(policy4.GetPolicyDetails());
}
}
}
21 changes: 21 additions & 0 deletions src/DesignPatterns.Adapter/Flyweight/InsurancePolicy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace DesignPatterns.Structural.Flyweight;

//Extrinsic State: This represents the unique state
public class InsurancePolicy
{
private readonly InsuranceType _insuranceType;
public string CustomerName { get; }
public string PolicyNumber { get; }

public InsurancePolicy(InsuranceType insuranceType, string customerName, string policyNumber)
{
_insuranceType = insuranceType;
CustomerName = customerName;
PolicyNumber = policyNumber;
}

public string GetPolicyDetails()
{
return $"Policy No: {PolicyNumber}, Customer: {CustomerName}, {_insuranceType.GetPolicyTypeDetails()}";
}
}
19 changes: 19 additions & 0 deletions src/DesignPatterns.Adapter/Flyweight/InsuranceType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace DesignPatterns.Structural.Flyweight;

//Intrinsic State: This represents the shared state
public class InsuranceType
{
public string Type { get; }
public string Coverage { get; }

public InsuranceType(string type, string coverage)
{
Type = type;
Coverage = coverage;
}

public string GetPolicyTypeDetails()
{
return $"Type: {Type}, Coverage: {Coverage}";
}
}
18 changes: 18 additions & 0 deletions src/DesignPatterns.Adapter/Flyweight/InsuranceTypeFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace DesignPatterns.Structural.Flyweight;

public class InsuranceTypeFactory
{
private readonly Dictionary<string, InsuranceType> _insuranceTypes = new Dictionary<string, InsuranceType>();

public InsuranceType GetInsuranceType(string type, string coverage)
{
var key = $"{type}_{coverage}";

if (!_insuranceTypes.ContainsKey(key))
{
_insuranceTypes[key] = new InsuranceType(type, coverage);
}

return _insuranceTypes[key];
}
}
60 changes: 60 additions & 0 deletions src/DesignPatterns.Structural.Tests/FlyweightPatternTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using DesignPatterns.Structural.Flyweight;
using FluentAssertions;

namespace DesignPatterns.Structural.Tests;

public class FlyweightPatternTests
{
public class InsuranceTypeFactoryTests
{
[Test]
public void ShouldReuseInsuranceTypeForSamePolicyType()
{
// Arrange
var factory = new InsuranceTypeFactory();

// Act
var type1 = factory.GetInsuranceType("Health", "Full Coverage");
var type2 = factory.GetInsuranceType("Health", "Full Coverage");

// Assert
type1.Should().BeSameAs(type2, "Factory should return the same instance for the same insurance type");
}

[Test]
public void ShouldCreateDifferentInsuranceTypesForDifferentPolicyTypes()
{
// Arrange
var factory = new InsuranceTypeFactory();

// Act
var healthType = factory.GetInsuranceType("Health", "Full Coverage");
var carType = factory.GetInsuranceType("Car", "Collision Coverage");

// Assert
healthType.Should().NotBeSameAs(carType, "Factory should return different instances for different insurance types");
}
}

public class InsurancePolicyTests
{
[Test]
public void ShouldStoreCustomerSpecificPolicyDetails()
{
// Arrange
var factory = new InsuranceTypeFactory();
var healthType = factory.GetInsuranceType("Health", "Full Coverage");

var policy1 = new InsurancePolicy(healthType, "Mdu Doe", "P123456");
var policy2 = new InsurancePolicy(healthType, "Trev Doe", "P123457");

// Act
var details1 = policy1.GetPolicyDetails();
var details2 = policy2.GetPolicyDetails();

// Assert
details1.Should().Be("Policy No: P123456, Customer: Mdu Doe, Type: Health, Coverage: Full Coverage");
details2.Should().Be("Policy No: P123457, Customer: Trev Doe, Type: Health, Coverage: Full Coverage");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace DesignPatterns.Structural.Tests;

public class InsurancePolicyTests
public class InsurancePolicyBridgeTests
{
[Test]
public void ShouldIssueHealthPolicyWithProviderA()
Expand Down
Loading

0 comments on commit 8712a51

Please sign in to comment.