如何在不造成混乱的情况下引用多个类?

时间:2012-02-23 20:23:04

标签: c#

我有一个情况,我有8个步骤(将其视为向导)。每个步骤都包含不同的内容,因此我创建了8个类。每个类都需要前面步骤(类)中的一些信息。所有类都从一个主类调用。我发现处理这种情况的最简单的方法是:

public void Main()
{
   var step1 = new Step1();
   step1.Process();
   var step2 = new Step2(step1);
   step2.Process();
   var step3 = new Step3(step1, step2);
   //...
   var step8 = new Step8(step1, step2, step3, step4, step5, step6, step7);
   step8.Process();
}
显然,这是一团糟。我不想发送那么多参数,我不想使用静态类(可能不是一个好习惯)。

你会如何处理这种情况?

8 个答案:

答案 0 :(得分:8)

这听起来像是你可以通过Chain of Responsibility Pattern完成的事情。这是我至少要研究的方向。

如果你沿着这条路走下去,那么你将在未来更加清晰地实施添加/删除步骤。

而且,就多个数据集而言,John Koerner的正确之处在于您应该拥有一个在每个步骤中更新的数据模型。这将使您能够实现一个干净的责任链。

答案 1 :(得分:3)

拥有一个可以在整个过程中使用的数据模型类。这些步骤更新了它们的数据模型,这是传递给每个后续步骤的唯一对象。

答案 2 :(得分:1)

只创建一个类,并使用不同的方法作为步骤

class Wizard
{
    int someIntInfo;
    string some StringInfo;
    ...

    public void ProcessStep1();
    public void ProcessStep2();
    public void ProcessStep3();
    public void ProcessStep4();
}

或创建一个步骤和一个信息界面,并通过将相同的信息传递给所有步骤来声明这样的向导

interface IWizardInfo
{
    int someIntInfo { get set; }
    string someStringInfo { get set; }
    ...
}

interface IStep
{
    void Process(IWizardInfo info);
}

class Wizard
{
     IWizardInfo _info = ....;
     IStep[] _steps = new IStep[] { new Step1(), new Step2(), ... };
     int _currentStep;

     void ProcessCurrentStep()
     {
         _steps[_currentStep++].Process(_info);
     }
}

编辑:

创建一个可以包含所有先前步骤的复合类

class Step1 { public Step1(AllSteps steps) { steps.Step1 = this; } ... }
class Step2 { public Step2(AllSteps steps) { steps.Step2 = this; } ... }
class Step3 { public Step3(AllSteps steps) { steps.Step3 = this; } ... }

class AllSteps
{
     public Step1 Step1 { get; set; }
     public Step2 Step2 { get; set; }
     public Step3 Step3 { get; set; }
}

将相同的信息传递给所有步骤。这些步骤负责将自己添加到信息

AllSteps allSteps = new AllSteps();
var stepX = new StepX(allSteps);

答案 3 :(得分:1)

似乎Java的内部类比C#更适合这一点。但是,C#在许多其他方面都要好得多,我们将让这一个通过。

您应该创建一个包含所有数据的类。如果您的步骤很简单,那么每个步骤中应该有一个方法。如果您的步骤很复杂,请将它们分成几类,但要让每个人都能访问数据类。

答案 4 :(得分:1)

您可以使用方法Run(Wizard)和属性Name的接口IProcess,多个进程以及每个人继承IProcess,以及包含要在列表中运行的进程的类向导。所以:

class Wizard
{
    private IList<IProcess> processes = new List<IProcess();

    public T GetProcess<T>(string name) 
           where T : IProcess
    {
        return (T)processes.Single(x => x.Name == name);
    }

    public void Run()
    {
       foreach (var proc in processes) 
              proc.Run(this);
    }
}

每个进程都可以使用Run方法的参数访问向导,或者只是在构造函数中使用它。通过调用wizard.GetProcess<Process1>("some name"),您可以拥有先前执行的流程(您可以添加支票)。

其他选项是在Wizard类中包含结果。

这只是众多变种中的一种。你可以看看责任链模式,就像Justin建议的那样

答案 5 :(得分:1)

我想说一个Chain-Of-Responsibility的变体的经典例子。

以下是一个例子:

class Request
{
    private List<string> _data;

    public IEnumerable<string> GetData()
    {
        return _data.AsReadOnly();
    }

    public string AddData(string value)
    {
        _data.Add(value);
    }
}

abstract class Step
{
    protected Step _nextStep;

    public void SetSuccessor(Step step)
    {
        _nextStep = step;
    }

    public abstract void Process(Request request);
}

sealed class Step1 : Step
{
    public override void Process(Request request)
    {
        var data = request.GetData();

        Console.Write("Request processed by");
        foreach (var datum in data)
        {
            Console.Write(" {0} ", datum);
        }

        Console.WriteLine("Now is my turn!");

        request.AddData("step1");

        _nextStep.Process(request);
    }
}

// Other steps omitted.
sealed class Step8 : Step
{
    public override void Process(Request request)
    {
        var data = request.GetData();

        Console.Write("Request processed by");
        foreach (var datum in data)
        {
            Console.Write(" {0} ", datum);
        }

        Console.WriteLine("Guess we're through, huh?");
    }
}

void Main()
{
     var step1 = new Step1();
     // ...
     var step8 = new Step8();
     step8.SetSuccessor(step1);

     var req = new Request();
     step1.Process(req);
}

答案 6 :(得分:0)

为什么不为所有步骤创建一个单独的类并在该类中实现状态管理? e.g。

private class Steps
{
   private int _stepIndex = 0;
   public void Process()
   {
       switch(_stepIndex)
       {
          case 0: // First Step
             ...  // Perform business logic for step 1.
             break;
          case 1: // Second Step
             ...  // Perform business logic for step 2.
             break;
       }
       _stepIndex++;
   }
}

答案 7 :(得分:0)

我会有两个ArrayLists(或者根据你的类和方法结构,它们可能是简单的列表) - 一个用于方法(作为委托),一个用于结果。

因此,foreach方法将遍历委托并使用结果列表作为参数调用它们(您可以使用方法接受这些参数并使用它们)并将结果添加到结果列表中。