Meta Descripation:
Learn how to refactor C# code step-by-step, transitioning from static functions to a flexible, object-oriented design. Discover practical examples that showcase the benefits of applying OOP principles for better code flexibility, maintainability, and extensibility.
Introduction
This article aims to explain how to make C# code more object-oriented by starting with simple examples and gradually moving to more complex ones. We’ll start by writing basic code and refactoring it step by step to make it flexible and maintainable.
Step 1: The Basic Example – Summing All Numbers
Let’s start with a basic function that sums up all numbers in an array.
Example 1: Summing All Numbers
int Sum(int[] numbers)
{
int total = 0;
foreach (var number in numbers)
{
total += number;
}
return total;
}
Explanation: This function simply loops through the array and adds all the numbers together. It's basic but lacks flexibility.
Problem:
What if we only want to sum up odd numbers? Modifying this function to include conditions will make the code messy.
Step 2: Adding a Simple Condition – Summing Odd Numbers
We add a basic condition to sum only odd numbers.
Example 2: Summing Odd Numbers
int SumOddNumbers(int[] numbers)
{
int total = 0;
foreach (var number in numbers)
{
if (number % 2 != 0)
{
total += number;
}
}
return total;
}
Explanation: Here, we only sum numbers that are odd. However, if requirements change again (e.g., sum even numbers), we have to modify the function each time, making it inflexible.
Step 3: Introducing a More Flexible Solution – Using a Function Delegate
Let’s make our code more flexible by allowing the user to pass a selection criterion.
Example 3: Using a Delegate for Selection
int Sum(int[] numbers, Func<int, bool> selector)
{
int total = 0;
foreach (var number in numbers)
{
if (selector(number))
{
total += number;
}
}
return total;
}
Example Usage:
int[] numbers = { 1, 2, 3, 4, 5 };
int sumOfOdds = Sum(numbers, n => n % 2 != 0); // Sum only odd numbers
int sumOfEvens = Sum(numbers, n => n % 2 == 0); // Sum only even numbers
Explanation: The function now uses a delegate (Func<int, bool>
) to decide which numbers to include in the sum. This makes the code flexible—you can easily change the selection criteria without modifying the core logic.
Step 4: Refactoring to an Object-Oriented Approach
To fully embrace OOP, we need to encapsulate the logic into classes.
Example 4: Creating a Selector
Class
public class Selector
{
private readonly Func<int, bool> _criteria;
public Selector(Func<int, bool> criteria)
{
_criteria = criteria;
}
public bool IsSelected(int number)
{
return _criteria(number);
}
}
Example 5: Refactoring to a NumberArray
Class
public class NumberArray
{
private readonly int[] _numbers;
public NumberArray(int[] numbers)
{
_numbers = numbers;
}
public int Sum(Selector selector)
{
int total = 0;
foreach (var number in _numbers)
{
if (selector.IsSelected(number))
{
total += number;
}
}
return total;
}
}
Example Usage:
var numbers = new NumberArray(new[] { 1, 2, 3, 4, 5 });
var oddSelector = new Selector(n => n % 2 != 0);
var sumOfOdds = numbers.Sum(oddSelector); // Output: 9
var evenSelector = new Selector(n => n % 2 == 0);
var sumOfEvens = numbers.Sum(evenSelector); // Output: 6
Explanation:
-
NumberArray
encapsulates the summing logic. -
Selector
encapsulates the selection criteria. - The solution is now more flexible, maintainable, and aligned with OOP principles.
Step 5: Making It Extensible
The OOP approach allows you to easily extend the code. For example, you can add new selectors without modifying existing classes.
Example 6: Adding a New Selector
var everyOtherSelector = new Selector((n, index) => index % 2 == 0);
var sumOfEveryOther = numbers.Sum(everyOtherSelector); // Output: 6
Conclusion
By refactoring code step by step, we’ve moved from a simple, rigid function to a flexible, object-oriented solution. Using classes and delegates makes the code easier to extend, test, and maintain.
This approach should help you understand how OOP adds value to your code and makes it adaptable to changing requirements.
Top comments (0)