1

我有一堂有很多方法的课:

public class MyClass {
    public bool checkConditions() {
        return checkCondition1() &&
               checkCondition2() &&
               checkCondition3();
    }

...conditions methods

    public void DoProcess() {
        FirstPartOfProcess();
        SecondPartOfProcess();
        ThirdPartOfProcess();
    }

...process methods
}

我确定了两个“重要”工作领域,并决定将这些方法提取到自己的类中:

public class MyClass {
    private readonly MyClassConditions _conditions = new ...;
    private readonly MyClassProcessExecution = new ...;

    public bool checkConditions() {
        return _conditions.checkConditions();
    }

    public void DoProcess() {
        _process.DoProcess();
    }
}

在 Java 中,我将MyClassConditionsand定义MyClassProcessExecutionpackage protected,但在 C# 中我不能这样做。


您将如何在 C# 中执行此操作?

将这两个类都设置为 MyClass 的内部类?

我有 2 个选项:我要么在内部定义它们MyClass,将所有内容都放在同一个文件中,这看起来令人困惑和丑陋,要么我可以定义MyClass为 a partial class,一个文件用于MyClass,另一个用于MyClassConditions,另一个用于MyClassProcessExecution

将它们定义为内部?

我不太喜欢内部修饰符,因为我发现这些类根本没有为我的程序/程序集的其余部分增加任何价值,如果可能的话,我想隐藏它们。它们在程序的任何其他部分都不会有用/可重用。

让他们公开?

我不明白为什么,但我让这个选项在这里。

任何其他?

命名吧!

谢谢

4

5 回答 5

2

对于不会在当前程序集之外使用的“Helper”类型的类,Internal如果方法将被多个类使用,这是一种方法。

对于仅由单个类使用的方法,我只需将它们设为该类的私有,或者如果它实际上是一个在其他任何地方都没有使用的类,则使用内部类。如果代码不依赖类的任何(非静态)成员,您也可以将代码分解为静态方法。

于 2010-05-13T19:00:45.137 回答
2

您最好的选择可能是使用部分类并将三组代码放在单独的文件中,添加到同一个类中。然后,您可以将条件和过程代码设为私有,以便只有类本身可以访问它们。

于 2010-05-13T19:05:03.813 回答
1

我可以将 MyClass 定义为部分类,其中一个文件用于 MyClass,另一个用于 MyClassConditions,另一个用于 MyClassProcessExecution。

也许这是我的 C++ 背景,但这是我的标准方法,尽管我将小型辅助类捆绑到一个文件中。

因此,在我目前的一个项目中,课程Product分为Product.csProductPrivate.cs

于 2010-05-13T19:17:53.397 回答
1

我要去做别的事情了——公共/受保护/私有的问题可能无法通过这个来专门解决,但我认为它比很多嵌套的内部类更适合维护。

因为听起来您在顺序算法中有一组步骤,其中一个步骤的执行可能取决于也可能不取决于前一步的执行。这种类型的顺序步骤处理有时可以使用责任链模式,尽管它与最初的意图有所不同。仅关注您的“处理方法”,例如,从以下内容开始:

class LargeClass
{
public void DoProcess()
{
  if (DoProcess1())
  {
    if (DoProcess2())
    {
      DoProcess3();
    }
  }
}

protected bool DoProcess1()
{
...
}

protected bool DoProcess2()
{
...
}

protected bool DoProcess3()
{
...
}

}

使用责任链,这可以分解为每个步骤的一组具体类,这些类继承自一些抽象步骤类。如果满足必要的先决条件,抽象步骤类更负责确保调用下一步。

public class AbstractStep
{
    public AbstractStep NextStep { get; set; }

    public virtual bool ExecuteStep
    {
       if (NextStep != null)
       {
         return NextStep.ExecuteStep();
       }
    }  
}

public class ConcreteStep1 : AbstractStep
{
    public bool ExecuteStep
    {
       // execute DoProcess1 stuff
       // call base
       return base.ExecuteStep();
    }
}

...

public class ConcreteStep3 : AbstractStep
{
     public bool ExecuteStep
     { 
        // Execute DoProcess3 stuff
        // call base
        return true; // or false?
      }
}

要进行此设置,您将在代码的某些部分中执行以下操作:

var stepOne = new ConcreteStep1();
var stepTwo = new ConcreteStep2();
var stepThree = new ConcreteStep3();
stepOne.NextStep = stepTwo;
stepTwo.NextStep = stepThree;

bool success = stepOne.ExecuteStep();

这可能有助于清理您在单个类中遇到的代码膨胀——我过去曾将它用于一些顺序类型算法,它有助于很好地隔离每个步骤。您显然可以将相同的想法应用于您的条件检查(或将它们构建到每个步骤中,如果适用的话)。您还可以通过让 ExecuteStep 方法采用带有某种状态对象的参数来在步骤之间传递状态方面对此进行一些变化。

当然,如果您在这篇文章中真正关心的只是隐藏各个步骤,那么是的,您可以将每个子步骤设置为创建步骤的类中的受保护类。但是,除非您以某种形式或方式向客户公开您的库,并且您不希望他们对您的执行步骤有任何类型的可见性,否则与使代码可维护相比,这似乎是一个较小的问题。

于 2010-05-13T19:38:54.720 回答
0

使用与您重构的方法相同的访问修饰符创建类。仅当您有多个人或自动代码生成工具经常修改相同的类时,部分类才真正有用。他们只是真正避免了源代码合并地狱,因为它不能将多个编辑合并到同一个文件中,因为它不能将多个编辑合并到同一个文件中。

于 2010-05-13T19:06:27.577 回答