Open Closed Principle C#:私有集+构造函数初始化的一个例子吗?

问题描述 投票:2回答:1

我的同事认为以下代码是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的值。

我对原理的解释正确吗?

他的解释不正确吗?

c# oop solid-principles open-closed-principle
1个回答
0
投票

您是正确的。打开-关闭原则与运行时的可变性或属性值无关。

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());

   }
}
© www.soinside.com 2019 - 2024. All rights reserved.