我的同事认为以下代码是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()}");
}
}
他给出的原因是:“一旦构造了类,就将Id属性的值关闭以进行修改”。
我相信这是一个错误的解释。
据我了解,开放式封闭原则与为修改而封闭的属性的值无关。
我相信开放封闭原则仅与设计类有关,因此可以扩展类的behavior而无需修改现有代码。
即如果我要去编辑PrintIdWithText
方法以在新行上打印Count
的值,那将违反该原理。因为我正在修改现有的类。
为了满足该原理,我必须将类设计为使其可扩展,以便例如可以通过合成来注入打印功能。
这会让我晚些时候,添加功能以在新行上打印Maximum
的值。
我对原理的解释正确吗?
他的解释不正确吗?
您是正确的。打开-关闭原则与运行时的可变性或属性值无关。
Open-closed原则是关于代码的架构,以便我们可以添加新行为without修改现有的工作代码。
我已重写您的代码以遵循OCP。在这种情况下,将MyClass
扩展为open以通过引入新的Maximum
(在本例中为IClassPrinter
)来打印FancyClassPrinter
属性。
请记住,不可能完全关闭一个类,总会有一些我们无法预见的修改,因此OCP是一个指南,而不是目标。
对于您的代码,这是一个人为的示例,对于这样简单的程序,可能有些过分。还请注意,即使不遵循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());
}
}