我有一个情况,我有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();
}
显然,这是一团糟。我不想发送那么多参数,我不想使用静态类(可能不是一个好习惯)。
你会如何处理这种情况?
答案 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方法将遍历委托并使用结果列表作为参数调用它们(您可以使用方法接受这些参数并使用它们)并将结果添加到结果列表中。