Reputation: 1419
My Workmate believes that the following code is an example of the Open Closed Principle in C#:
public class MyClass
{
public int Id { get; private set; }
public int Count{ get; private set; }
public int Maximum{ get; private set; }
public MyClass(int id, int count, int maximum)
{
Id = id;
Count = count;
Maximum = maximum;
}
public PrintValueWithText()
{
Conlose.Writeline($"The value of the Id property is: {Id.ToString()}");
}
}
The reason that he gives is that: "The Id property's value is closed for modification once the class is constructed".
I believe this is an incorrect interpretation.
It is my understanding that the open closed principle has nothing to do with the value of a property being closed for modification.
I believe that the Open Closed principle only relates to designing the class so that extending the behavior of the class is possible without modifying the existing code.
i.e. if i was to go in and edit the PrintIdWithText
method to also print the value of Count
on a new line I would be violating the principle. Because I'm modifying the existing class.
In order to satisfy the principle, I must design the class so that its extendable so that I can for example, inject in the print functionality by composition.
Which would allow me to a later date, add functionality to print the print the value of Maximum
on a new line.
Is my interpretation of the principle correct?
Is his interpretation incorrect?
Upvotes: 2
Views: 381
Reputation: 4887
You are correct. The Open-Closed principle has nothing to do with mutability or property values at runtime.
The Open-closed principle is about architecting the code so that we can add new behaviour without modifying existing working code.
I have rewritten your code to follow the OCP. In this case, MyClass
was open for extension to print the Maximum
property by introducing a new IClassPrinter
, in this case the FancyClassPrinter
.
Bear in mind that it is impossible to make a class fully closed, there will always be modifications that we cannot foresee, so the the OCP is a guide not a target.
For you code, this is a bit of a contrived example, and might be overkill for such simple program. Also note that the Single Responsibility Principle required us to move the printing responsibility to another class, even if were not following OCP.
using System;
using System.Collections.Generic;
public interface IClassPrinter{
void PrintValue(MyClass myClass);
}
public class NormalClassPrinter: IClassPrinter{
public void PrintValue(MyClass myClass)
{
Console.WriteLine($"The value of the Id property is: {myClass.Id.ToString()}");
}
}
public class FancyClassPrinter: IClassPrinter{
public void PrintValue(MyClass myClass)
{
Console.WriteLine($"The value of the Id property is: {myClass.Id.ToString()}");
Console.WriteLine($"The value of the Maximum property is: {myClass.Maximum.ToString()}");
}
}
public class MyClass
{
public int Id { get; private set; }
public int Count{ get; private set; }
public int Maximum{ get; private set; }
public MyClass(int id, int count, int maximum)
{
Id = id;
Count = count;
Maximum = maximum;
}
public void PrintValueWithText(IClassPrinter classPrinter)
{
classPrinter.PrintValue(this);
}
}
class MainClass
{
static public void Main(string[] args)
{
MyClass myClass = new MyClass(0,0,0);
myClass.PrintValueWithText(new NormalClassPrinter());
myClass.PrintValueWithText(new FancyClassPrinter());
}
}
Upvotes: 1