簡體   English   中英

如何在不造成混亂的情況下引用多個類?

[英]How to refer to multiple classes without creating a mess?

我遇到的情況是我有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();
}

顯然,這是一團糟。 我不想發送那么多參數,也不想使用靜態類(可能不是一個好習慣)。

您將如何處理這種情況?

對我來說,這聽起來像是您可以通過“責任鏈模式”來完成的事情。 至少這是我要研究的方向。

如果您走這條路,那么您將對將來增加/刪除步驟的更清潔的實現方式持開放態度。

而且,就多個數據集而言,John Koerner是正確的,因為您應該有一個在每個步驟中都更新的數據模型。 這將使您實施干凈的責任鏈。

有一個類是您的數據模型,可以在整個過程中使用。 這些步驟將更新其數據模型,這是傳遞給每個后續步驟的唯一對象。

僅創建一個類並使用不同的方法作為步驟

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

似乎Java的內部類比C#擁有的內部類更適合於此。 但是,C#在許多其他方面都好得多,我們讓它通過。

您應該創建一個包含所有數據的類。 如果您的步驟很簡單,則該類中的每個步驟應該有一個方法。 如果您的步驟很復雜,請將它們分成幾類,但讓它們每個人都可以訪問數據類。

您可以將IProcess接口與方法Run(Wizard)和屬性Name ,使用多個進程,每個人都繼承IProcess,並使用包含在列表中運行的進程的類Wizard。 所以:

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類中。

這只是許多變體之一。 您可以看一下責任鏈模式,就像賈斯汀建議的那樣

我想說一個典型的例子,說明了責任鏈的變化。

這是一個例子:

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

為什么不為所有步驟創建一個類並在該類中實現狀態管理? 例如

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++;
   }
}

我將有兩個ArrayLists(或者取決於您的類和方法結構,它們可能是簡單的Lists)-一個用於方法(作為委托)和一個用於結果。

因此,foreach方法將遍歷委托並以結果列表作為參數來調用它們(您可以容納您的方法以接受此類參數並使用它們)並將結果添加到結果列表中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM