Skip to main content

Posts

Showing posts with the label csharp

Design Patterns: Prototype

In software development, there are scenarios where creating multiple objects with similar attributes and configurations is necessary. Instead of constructing each object from scratch, a more efficient approach is to duplicate an existing instance. This is precisely what the Prototype Design Pattern facilitates. What is the Prototype Pattern? The Prototype pattern is a creational design pattern that focuses on cloning objects. Rather than instantiating new objects directly, this pattern allows for the creation of copies of existing instances. This can be particularly beneficial when object creation is expensive or complex. Benefits of Using the Prototype Pattern Improved Performance – If object creation involves expensive operations such as database queries or intensive computations, cloning can optimize performance. Simplified Object Initialization – When an object requires extensive setup, cloning eliminates redundant initialization steps. Dynamic Object Modifications – Prototypes...

TDD and Mocking

In the  last post  we have discussed core principles of unit testing and TDD. In this post, we’ll walk through a simple example of how to use Moq  as mocking framework and Dependency Injection with NUnit in the context of Test-Driven Development (TDD) in C#. This combination allows for clean, maintainable tests by mocking dependencies and focusing on the behavior of the system under test. Imagine we have an application where we process payments through a PaymentService . This service depends on an external IPaymentGateway interface to make the actual payment.  Let’s break this down step by step. Step 1: Write the Test First (Before Code) We want to test the PaymentService , which depends on the IPaymentGateway . Our first test will focus on making sure the PaymentService behaves correctly when making a valid payment. Here's the test code: using Moq; using NUnit.Framework; [TestFixture] public class PaymentServiceTests { private Mock<IPaymentGateway>...

Unit Testing and Test-Driven Development (TDD) in C#

Writing code without unit tests can be risky—you might not realize issues until it’s too late. Unit testing helps make sure your code actually does what it's supposed to. In this post, we’ll break down unit testing in C# using NUnit and explore how Test-Driven Development (TDD) can make your life easier. What’s Unit Testing Anyway? Unit testing is all about testing small, isolated chunks of your code to make sure they work correctly. Instead of waiting until the whole application is built and then scrambling to fix bugs, unit tests let you catch issues early. In C#, we typically use frameworks like NUnit , xUnit , or MSTest to write and run these tests. Why Should You Care About Unit Testing? Find Bugs Early: Fixing issues sooner rather than later saves time (and headaches). Make Your Code More Maintainable: Well-tested code is easier to update and improve. Write Better Code: Writing testable code forces you to structure it well. Acts as Documentation: Your tests describe what...

Design Patterns: Decorator

The Decorator Pattern is a structural design pattern that allows behavior to be dynamically added to individual objects, without modifying their code. It is often used to extend the functionalities of classes in a flexible and reusable way. When To Use It? You Need to Add Behavior Dynamically at Runtime.  Example: A coffee shop app where users can customize their drinks with add-ons like Milk, Sugar, Whipped Cream, etc. You Want to Avoid a Large Inheritance Tree.  If you use inheritance, each combination of behaviors would require a new subclass (e.g., CoffeeWithMilk , CoffeeWithSugar , CoffeeWithMilkAndSugar , etc.). You Want More Flexible and Reusable Code.  Different decorators can be reused independently . Example: A LoggingDecorator , CompressionDecorator , and EncryptionDecorator can be used separately or in different orders. You Follow the Open-Closed Principle.  Instead of modifying an existing class, you can extend behavior using decorators . This mak...

Testable WinForms Applications (MVP pattern)

Today, WinForms apps mainly belong to legacy code because of increasing popularity of WPF. And when one team decides about the development stack for the brand new desktop application, they mainly vote for WPF. On the other hand, there are demands for WinForms applications when it is needed to upgrade existing software which is tightly coupled with WinForms, demands for higher performance, etc. Different Approaches There are many opinions on the subject about testable WinForms apps. Some claim that it's not possible to test WinForms apps because there is a lot of dependency between user events and business logic. Standard Windows Form contains Designer.cs partial class and a partial class which contains event handlers for user actions. So, if we follow this same principle and try to implement app logic in event handlers, we can conclude that it would be very hard to write tests for this kind of application. But, if we look at this problem from some distance, we can conclude that eve...

Dependency Injection In .NET Core With Strategy Pattern

In the previous post, we gave an introduction and explained the basic concept of the  Strategy Pattern . Now, we want to go a bit further and demonstrate how it works in practice alongside a dependency injection in .NET Core. Instead of manually instantiating strategies, we let the ASP.NET Core DI container inject the correct implementation at runtime. Example For the showing purposes, let us asume that we are implementing some payment service, and we want to use one service at the time, depending on user input. For our strategy pattern, we would need following components: Interface public interface IPaymentStrategy { void Pay ( decimal amount ) ; } Concrete Strategies public class CreditCardPayment : IPaymentStrategy { public void Pay(decimal amount) { Console.WriteLine($"Paid ${amount} using Credit Card."); } } public class PayPalPayment : IPaymentStrategy { public void Pay(decimal amount) { Console.WriteLine($"Paid ${amoun...

Design Patterns: Strategy

The Strategy Pattern is a behavioral design pattern that defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern allows the algorithm to be selected at runtime, providing flexibility in designing software. It’s particularly useful when you have multiple ways of performing a task, and you want to choose the implementation dynamically without altering the client code. When To Use It? You Have Multiple Algorithms or Behaviors. Use it when you have a need for muplitple ways of performing a task, and you want to make these implementations interchangeable. Examples: Different sorting algorithms, payment methods, discount calculations... You Want to Eliminate Conditional Logic.  If you find yourself writing large if-else or switch statements to decide which algorithm to use, this pattern can simplify and clean up your code. Examples: A game character with different attack styles  You Need Runtime Flexibility.  Use this pattern if the ...

Composition Over Inheritence

Inheritence is often misused or overused or even forced for several reasons, and they are mostly due to education, misunderstanding or habit. Many developers who studied OOP are introduced with inheritence in early stage and then it stays with them as a default way how to build relationships between objects. Escaping this matrix can be quite challenging, as lacking alternative perspectives often leads to the trap of believing that inheritance is the solution to everything. Here, we will try to find the reasoning behind this way of thinking. Historical Influence Early OOP examples often revolved around "is-a" relationships like Car -> Vehicle, Dog -> Animal , reinforcing inheritance as the primary method of code reuse. We can see this in early OOP literature, such as the influential "Gang of Four Design Patterns",  where inheritance is prominently discussed. And then, as a result, developers internalized it as the default design approach. Inheritance = Code Reu...