开闭原则C#:Private Set + Constructor Init 是它的一个例子吗?

Open Closed Principle C#: Is Private Set + Constructor Init an Example of it?

我的同事认为下面的代码是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 Id property's value is closed for modification once the class is constructed".

我认为这是一个错误的解释。

据我了解,开闭原则与属性的值被修改关闭无关。

我认为开闭原则只与设计 class 相关,因此可以在不修改现有的情况下扩展 class 的 行为 代码。

即如果我要进入并编辑 PrintIdWithText 方法以在新行上也打印 Count 的值,我将违反原则。因为我正在修改现有的class。

为了满足原则,我必须设计 class 使其可扩展,例如,我可以通过组合注入打印功能。

这将允许我在以后的日期添加功能以在新行上打印 Maximum 的值。

我对原理的理解正确吗?

他的解释有误吗?

你是对的。 开闭原则与运行时的可变性或 属性 值无关。

开闭原则是关于构建代码的,这样我们就可以添加新行为而无需修改现有的工作代码。

我已重写您的代码以遵循 OCP。在这种情况下,MyClassopen 用于通过引入新的 IClassPrinter 来扩展打印 Maximum 属性,在这种情况下FancyClassPrinter

请记住,class 完全关闭是不可能的,总会有我们无法预见的修改,因此 OCP 是指南而不是目标。

对于您的代码,这是一个有点人为的例子,对于这样简单的程序来说可能有点过分了。另请注意,单一职责原则要求我们将打印职责转移到另一个 class,即使我们不遵循 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());

   }
}