6

在代码中试验 Cockburn 用例

我正在编写一些复杂的 UI 代码。我决定将 Cockburn 用例用于鱼、风筝和海平面(由 Martin Fowler 在他的《UML Distilled》一书中讨论)。我将 Cockburn 用例封装在静态 C# 对象中,以便我可以针对代表 UI 工作流程中步骤的静态常量测试逻辑条件。这个想法是您可以阅读代码并知道它在做什么,因为包装的对象及其公共内容通过名称空间为您提供了英语用例。

此外,我打算使用反射来抽出包含所描述用例的错误消息。这个想法是堆栈跟踪可以包含一些英语用例的 UI 用例步骤。结果证明这是一种有趣的方式来实现一个迷你的、伪轻量级的域语言,但无需编写 DSL 编译器。所以我的问题是这是否是一个好方法?有没有人做过类似的事情?


c# 示例片段如下

假设我们有一些 aspx 页面,它有 3 个用户控件(有很多可点击的东西)。用户必须单击一个特定用户控件中的内容(可能进行某种选择),然后 UI 必须在视觉上提示用户选择成功。现在,当该项目被选中时,用户必须浏览网格视图以在其他用户控件之一中找到项目,然后选择某些内容。这听起来很容易管理,但代码可能会变得丑陋。

在我的例子中,用户控制主页捕获的所有发送的事件消息。这样,页面就像 UI 事件的中央处理器一样,可以跟踪用户点击时发生的情况。

因此,在主 aspx 页面中,我们捕获了第一个用户控件的事件。

using MyCompany.MyApp.Web.UseCases;   

protected void MyFirstUserControl_SomeUIWorkflowRequestCommingIn(object sender, EventArgs e)
{
  // some code here to respond and make "state" changes or whatever
  //
  // blah blah blah


  // finally we have this (how did we know to call fish level method?? because we knew when we wrote the code to send the event in the user control)
  UpdateUserInterfaceOnFishLevelUseCaseGoalSuccess(FishLevel.SomeNamedUIWorkflow.SelectedItemForPurchase)

}



protected void UpdateUserInterfaceOnFishLevelGoalSuccess(FishLevel.SomeNamedUIWorkflow  goal)
{
  switch (goal)
  {
     case FishLevel.SomeNamedUIWorkflow.NewMasterItemSelected:
           //call some UI related methods here including methods for the other user controls if necessary....
           break;
     case FishLevel.SomeNamedUIWorkFlow.DrillDownOnDetails:
           //call some UI related methods here including methods for the other user controls if necessary....
           break;
     case FishLevel.SomeNamedUIWorkFlow.CancelMultiSelect:
           //call some UI related methods here including methods for the other user controls if necessary....
           break;

     // more cases...


     }
  }

}


//also we have
protected void UpdateUserInterfaceOnSeaLevelGoalSuccess(SeaLevel.SomeNamedUIWorkflow  goal)
{
  switch (goal)
  {
     case SeaLevel.CheckOutWorkflow.ChangedCreditCard:
        // do stuff


     // more cases...


     }
  }

}

因此,在 MyCompany.MyApp.Web.UseCases 命名空间中,我们可能有这样的代码:

class SeaLevel...
class FishLevel...
class KiteLevel...

嵌入在类中的工作流用例可以是内部类或静态方法或枚举或任何为您提供最干净命名空间的东西。我不记得我最初做了什么,但你明白了。

4

2 回答 2

2

我从来没有这样做过,但我经常考虑以 UC 风格编写代码,首先是主要成功路径,并且在下面遇到异常时放入扩展。还没有找到这样做的借口 - 很想看到有人尝试它并编写代码,即使在实验之后我们认为它很糟糕,尝试和参考仍然很有趣。

于 2010-06-07T00:07:26.827 回答
1

我认为这是设计模式(四人组)中中介者模式的一种变体——所以我会说这是一种有效的方法。在 Pattern 中,他们讨论了控件之间复杂的交互是使用它的原因。

编辑:维基百科上的调解员链接

于 2008-09-23T12:03:28.577 回答