2011-06-15 38 views
-2

我公司开发的Windows应用程序,其中一个按钮是有一个表上的按钮被点击时,然后几个系列的功能将后运行一个一个像下面一个需要概念在C#中的特定类型的应用程序

Button_Click() 

{ 

function1(); 

function2(); 

function3(); 

function4(); 

function5(); 

function6(); 

function7(); 

function8(); 

function9(); 

function101(); 

function1(); 

function12(); 

function13(); 

} 

每个功能都可以完成一些工作。所以我的应用程序运行良好,但我需要知道如何以更多结构的方式设计这种工作。所以请指导我如何结构的方式,我可以一个接一个地调用所有函数。一位经验丰富的专家开发人员将如何处理这项工作或他们如何一个接一个地调用函数。感谢

回答

2

这一切,如果该功能需要以特定的顺序或不被调用取决于。

如果不是:使用发布/订阅模式。

如果需要以特定的顺序:

不要使用功能,添加功能类和使用管道像下面。

public interface IPipeline 
{ 
    void AddLast(IPipelineHandler handler); 
    void AddFirst(IPipelineHandler handler); 

    void Invoke(IPipelineContext context); 
} 

public interface IPipelineContext 
{ 
    Form SourceForm {get; } 

    // The result that the pipeline should produce. (change from object to a specific type) 
    object Result {get; } 

    //and other properties that each handler will need. 
} 

public interface IPipelineHandler 
{ 
    string Name {get; } 
    void Process(IPipelineContext context); 
} 

在管道实现,调用与相同情况下每个处理程序:

public void Invoke(IPipelineContext context) 
{ 
    foreach (handler in _handlers) 
    { 
     try 
     { 
      handler.Process(context); 
     } 
     catch (Exception err) 
     { 
      //abort or continue with the next handler? 
     } 
    } 
} 
+0

你的代码是好的,但我无法理解我如何在我的场景中使用它。基本上我不是很先进的用户。这将是更好的,如果你请给我充分的代码,所有我的function1(),function2()等等将被称为一个接一个与你的上述代码。谢谢。我只需要看看我的函数如何在你的实现中被调用。 plzz帮助我。谢谢 – Mou 2011-06-15 08:33:14

3
  • 给你entitiess有意义的名称
  • 给你entitiess有意义的名称
  • 给你entitiess有意义的名称
  • 给你entitiess有意义的名称
  • 的通用代码
  • 可能信号/解压缩功能插槽/侦听器/观察者的概念适合你。

编辑:重构例子:

假设你的代码是:

void Button1_Click() { 
    function1(); 
    function2(); 
    function3(); 
    function4(); 
    function5(); 
}  
void Button2_Checked(int variable0) { 
    if (variable0) { 
     function1(); 
     function2(); 
    } else { 
     function1(); 
     function2(); 
     function3();  
     function4(); 
     function5(); 
    } 
} 

步骤0-10是找到所有有意义的名称,按钮,功能, 变量中,参数(一次只重命名一个实体;为避免发帖,我跳过了这个):

void orderPizzaButton_Click() { 
    requestSalamis(); 
    requestAnchovis();   
    requestShitake();   
    requestCheese(); 
    requestGroundMeat(); 
}  
void lasagnePervesityLevel_Changed(int newValue) { 
    if (newValue <= 0) { 
     requestCheese(); 
     requestGroundMeat(); 
    } else { 
     requestSalamis(); 
     requestAnchovis();   
     requestShitake(); 
     requestCheese(); 
     requestGroundMeat(); 
    } 
} 

第11步是找到commons在这些功能,并从中提取新的,可重复使用的功能 :

void orderPizzaButton_Click() { 
    requestStrangeIngredientCombination(); 
}  
void lasagnePervesityLevel_Changed(int newValue) { 
    if (newValue <= 0) { 
     requestCheese(); 
     requestGroundMeat(); 
    } else { 
     requestStrangeIngredientCombination(); 
    } 
} 

void requestStrangeIngredientCombination() { 
    requestSalamis(); 
    requestAnchovis();   
    requestShitake(); 
    requestCheese(); 
    requestGroundMeat(); 
} 

第12步是优化您的常用代码搜索(认为它作为一种标准化的):

void orderPizzaButton_Click() { 
    requestStrangeIngredientCombination(); 
} 
void lasagnePervesityLevel_Changed(int newValue) { 
    if (newValue <= 0) { 
     requestStandardComponents(); 
    } else { 
     requestStrangeIngredientCombination(); 
    } 
} 

void requestStandardComponents() { 
    requestCheese(); 
    requestGroundMeat(); 
} 
void requestStrangeIngredientCombination() { 
    requestSalamis(); 
    requestAnchovis();   
    requestShitake(); 
    requestStandardComponents(); 
} 

虽然在这个例子中似乎没有保存代码,但实际上它往往是。此外,保存代码行并不重要,关键在于减少冗余,因为一旦你决定你的异端烤宽面条和奇怪的披萨也应该保留chilis和Sylvester Stallone的图像,你不仅会有代码复制,但是工作重复;最重要的是,有可能忘记代码中某些地方的新功能。当然,这非常糟糕,甚至是关键业务。假设你的客户希望他们的烤宽面条上有一个西尔维斯特·史泰龙的形象,就像你的营销活动承诺的一样,然后没有谁订购比萨饼就得到了这个形象,而只有那些订购了千层面的人。

还有更多的重构和设计,取决于实际的代码。我真的推荐 以获得以下书籍。另外,最重要的经验法则是:一次一步。做一个小的重构,编译,测试。

  • 重构 - 改善既有代码的由Martin Fowler Addison-Wesley出版社
  • C中的设计++编码标准:101分的规则,准则和最佳做法C++由Herb萨特,安德烈Alexandrescu的(C++在 - 深度系列)Addison-Wesley出版社
  • 设计模式:通过伽马,头盔,约翰逊,Vlissides(俗称四人帮,为四人帮)可复用面向对象软件的元素,再次Addison-Wesley出版社
+0

我应该遵循哪种设计模式来处理这种情况。你可以请示例代码来处理这种情况。 – Mou 2011-06-15 08:14:16

+0

我不确定这是否真的值得设计模式。对于有意义地命名事物并将重复的东西放入单独的,可重用的实体应该是常见的程序员意义上的。我会举一个例子。 – 2011-06-15 08:21:33

0

如果您正在创建的功能需要按照该顺序执行这些功能,那么为什么不将这些调用封装在方法中?这将为您提供更高级别的封装,并且意味着可以在其他地方(从菜单工具栏中调用)调用此函数,而不必担心如果所有函数都按正确的顺序调用。

为你的函数分配更多有意义的名字也是值得的,但我相信你只是将它们命名为functionX()来作为例子。

因此,举例来说:

Button_Click() 
{ 
    Print() 
} 

private void Print() 
{ 
    function1(); 
    function2(); 
    function3(); 
    function4(); 
    function5(); 
    function6(); 
    function7(); 
    function8(); 
    function9(); 
    function10(); 
    function11(); 
    function12(); 
    function13(); 
} 
+0

和更高层次的抽象,可以提高代码的可读性。如果这个功能是在其他地方执行的,那么你正在进行一个呼叫,而不是14.这也可以通过嘲弄进行更好的单元测试。 ---编辑---嗯,似乎我回应的人删除了他们的评论。 – 2011-06-15 08:05:47

+0

可能是Button_Click已经封装了这些函数?所以你写了同样的东西。 – Reniuz 2011-06-15 08:09:25

+0

当然,这是事实。有了这样的示例代码,很难知道完整的域。 Button_Click()向我表明了一个.NET的点击处理模式,因此也就是响应。所以如果Button_Click()是一个封装级别,那么我对更有意义的函数名称的评论就有更多的相关性。感谢您指出了这一点! – 2011-06-15 08:10:52

0

你期望的答案?不知道这些功能如何相互关联,没有人能够回答这个问题。

这些功能是否相互依赖?下一个功能是否必须在先前的功能完成之前等待?或者他们可能平行运行?这些功能是否总是相同或可以改变?也许你想配置它们,从而使按钮执行动态调用。甚至可能在运行时?

如果您没有任何要求,我认为您的当前代码没有问题。

你应该看看设计模式,如命令模式或管道&过滤模式,也许这可以帮助你。

+0

我只想知道我的情况如何处理正确的设计模式。功能不依赖于对方。是的,下一个函数将在prev完成之前等待。功能将始终相同。所以现在告诉我用小代码来实现正确设计模式的情况。谢谢 – Mou 2011-06-15 08:28:20

+0

在这种情况下,您当前的代码很好。你的代码有什么问题吗,是什么让你认为你的代码错了? – codymanix 2011-06-15 08:31:40