2012-02-25 68 views
0

我有一个代表注册过程中的一个步骤的类。当用户在填写完步骤后单击保存,然后执行我希望在注册过程结束时执行步骤时执行的其他操作以及在步骤中调用保存时,我希望某些步骤可以执行。那个阶段。我决定使用拥有一个国家的想法,但它似乎有一个糟糕的代码味道。有关如何改进此设计的任何意见?OO设计问题

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"); 
     } 
    } 
} 
+2

属于codereview。 – 2012-02-25 14:36:26

回答

1

忽视其他问题的代码,如果你采用这种设计,你会与步骤一个单片类风去。我想创建一个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(); 
    } 
} 
+0

每一步都将是它自己的课程。这个样本类被称为Step1,这是因为当你保存一个步骤时,会有一些保存动作,当我们在Step5(最后一步)时,它会调用保存所有前面的步骤,但是需要完成一组不同的动作。处于最终状态。 – user1054637 2012-02-25 14:46:55

0

如果我undersdand你的答案(+上贾斯汀的回答您的评论)正确,每一步都可以在“处理”和“完成”状态并取决于它处于哪个状态,您想要调用不同的Save()IsValid()方法。

此外,一旦您到达最后一步,每一步都会自动“完成”。

从您发布的代码中,似乎并不像一个步骤需要知道他目前处于哪种状态。您只是想根据您是否在最后一页上执行不同的操作。

是否有原因让您不想创建封装“已完成”逻辑的特定方法(例如SaveCompleted()IsValidCompleted())?

我不明白为什么Step类应该决定要执行哪个代码,因为决定是在步骤之外进行的,在这个步骤中,您将跟踪活动步骤。

基于某种可以从外部修改的隐藏状态自动执行正确的事情的“魔术方法”通常会导致不一致,意外的问题和长的调试会话。

我会建议你创建一个接口,如贾斯汀建议的,其他两个包含“已完成”代码的方法。 (有很多方法可以实现这一点,比如使用抽象基类来代替(可能的优点是“完成”方法可以默认为“处理”方法)或单独的接口(仅暴露“完成”方法到最后一页,而不启用它来调用regualr方法)等等,等等)

+0

我想我只是觉得它看起来更整洁,让方法看起来像逻辑流程,而不是分解成单独的方法。我重申你的观点:分离关切。我也会在你的文章结尾看看这些建议 – user1054637 2012-02-25 15:38:05

0

作为除了Justin的答案,这里是一个维基百科的链接Finite-state machine,因为你正在试图建立一个有限状态机。该链接提供了关于主题的理论背景知识。如果您的注册过程变得更加复杂,文章中提到的州/事件表将有助于制定事件的流程。