This project demonstrates the implementation of the Strategy Design Pattern in C#. The Strategy Pattern is used to define a family of algorithms, encapsulate each one, and make them interchangeable. This pattern lets the algorithm vary independently from the clients that use it.
Order: Represents an order with properties such asOrderId,Amount, andOrderType.OrderType: Enum representing different payment types (e.g.,CreditCard,Paypal,Bitcoin, andCash).
-
Without Strategy:
Bad_OrderService: Processes payments using aswitchstatement, violating the Open/Closed Principle. Adding new payment types requires modifying the existing code.- Endpoints:
/api/withoutStrategyshowcases the complexity of this approach.
-
With Strategy:
- Strategy Interface:
IPaymentStrategy: Defines the interface for all payment strategies.
- Concrete Strategies:
CreditCardPayment,PayPalPayment,BitcoinPayment, andCashPayment: Implementations of different payment strategies.
- Factory:
PaymenyStrategyFactory: Returns the appropriate payment strategy based on theOrderType.
- Context:
PaymentContext: Encapsulates a payment strategy and delegates payment execution.
- Dynamic Registration:
PaymentStrategyRegistery: Allows dynamic registration of new payment types.
- Endpoints:
/api/Strategy: Demonstrates payment processing with the Strategy Pattern./api/Strategy/Better: Illustrates the enhanced approach with dynamic strategy registration.
- Strategy Interface:
- Payment processing is handled using a
switchstatement inBad_OrderService. - Adding new payment types requires modifying the service, increasing the risk of errors and maintenance challenges.
- Payment processing logic is encapsulated in separate strategy classes.
- Adheres to the Open/Closed Principle:
- Adding new payment types is as simple as creating a new class and registering it.
- Dynamic strategy registration allows runtime flexibility.
- Decoupling: Separates the algorithm (payment processing) from the client (order service).
- Extensibility: New payment types can be added without modifying existing code.
- Testability: Each strategy can be independently tested.
- Flexibility: Strategies can be registered dynamically at runtime.
- GET /api/withoutStrategy:
Fetches payment results processed usingBad_OrderService.
-
GET /api/Strategy:
Fetches payment results processed using the Strategy Pattern. -
GET /api/Strategy/Better:
Fetches payment results processed using dynamically registered strategies.
GET /api/withoutStrategy
Response:
[
{
"orderId": 1,
"amount": 100.0,
"orderType": "CreditCard",
"result": "Paid 100.0 using Credit Card for Order 1 ."
}
]GET /api/Strategy
Response:
[
{
"orderId": 1,
"amount": 100.0,
"orderType": "CreditCard",
"result": "Paid 100.0 using Credit Card for Order 1 ."
},
{
"orderId": 4,
"amount": 400.0,
"orderType": "Cash",
"result": "Paid 400.0 using cash for Order 4"
}
]GET /api/Strategy/Better
Response:
[
{
"orderId": 1,
"amount": 100.0,
"orderType": "CreditCard",
"result": "Paid 100.0 using Bitcoin for Order 1 ." // Dynamically registered strategy.
}
]- .NET 8.0 or higher.
- Visual Studio or any C# IDE.
- Clone the repository:
git clone <repository-url>
- Navigate to the project directory.
- Run the application:
dotnet run
- Use Swagger UI to test the endpoints:
- Access Swagger at:
https://localhost:<port>/swagger.
- Access Swagger at:
- C#
- ASP.NET Core Minimal API
- Swagger for API documentation
Develop By AliCharper
Refactor by Mohammad.
Feel free to reach out for feedback or collaboration!