我有一个代表注册过程中一步的课程。我有一些事情,当用户在填写完步骤后单击保存时,我希望该步骤执行,然后在我们处于注册过程结束时我希望该步骤执行的其他操作,并在步骤中调用保存那个阶段。我决定使用一个状态的想法,但似乎有一个糟糕的代码味道。有关如何改进此设计的任何意见?
public class Step1
{
public Enum State
{
InProcess = 1,
EndProcess
}
private State processState;
public Step1(State currentState)
{
processState = currentState;
}
public bool IsValid()
{
bool result;
if(processState = State.InProcess)
{
result = PerformCheck1();
}
else if(processState = State.EndProcess)
{
result = PerformCheck2();
result = PerformCheck3();
}
else
{
throw new Exception("Cannot determine process state");
}
return result;
}
public void Save()
{
if(processState = State.InProcess)
{
DoThing1();
}
else if(processState = State.EndProcess)
{
DoThing2();
DoThing3();
DoThing4();
}
else
{
throw new Exception("Cannot determine process state");
}
}
}
答案 0 :(得分:1)
忽略代码的其他问题,如果你使用这个设计,你最终会得到一个单一的Step for class。我会创建一个IStep接口,并使每一步都成为自己的类:
public interface IStep
{
bool IsValid { get; }
void Save();
}
public class BeginStep : IStep
{
public bool IsValid
{
get
{
return PerformCheck1();
}
}
public void Save()
{
DoThing1();
}
}
public class EndStep : IStep
{
public bool IsValid
{
get
{
// Skipped PerformCheck2() since the result is directly overwritten
return PerformCheck3();
}
}
public void Save()
{
DoThing2();
DoThing3();
DoThing4();
}
}
答案 1 :(得分:0)
如果我正确地回答你的答案(+你对贾斯汀的答案的评论),每一步都可以处于“处理”和“完成”状态,并且根据它所处的状态,你想要调用不同的{{1 }和Save()
方法。
此外,一旦到达最后一步,每一步都会自动“完成”。
从您发布的代码中,似乎步骤不需要知道他目前处于哪种状态。您只想根据您是否在最后一页上执行不同的操作。
您是否有理由不想创建封装“已完成”逻辑的特定方法(例如IsValid()
和SaveCompleted()
)?
我不明白为什么Step类应该决定执行哪个代码,因为决定是在步骤之外做出的,在那里你跟踪活动步骤。
基于可以从外部修改的某些隐藏状态自动执行正确操作的“魔术方法”通常会导致不一致,意外问题和长时间调试。
我建议你按照Justin的建议创建一个界面,另外两个方法包含“已完成”的代码。 (有很多方法可以实现相同的功能,例如使用抽象基类(可能的优点是“已完成”方法可以默认为“处理”方法)或单独的接口(仅显示“已完成”方法)到最后一页,没有让它调用regualr方法)等等。)
答案 2 :(得分:0)
作为贾斯汀回答的补充,这里是维基百科到Finite-state machine的链接,因为你要创建的是有限状态机。该链接提供了有关该主题的理论背景知识。如果您的注册过程变得更加复杂,本文中提到的State / Event表将有助于制定事件流。