调用层次结构问题

时间:2011-10-27 20:14:41

标签: c# class-design hierarchy

我有一种情况,我在级联风格中调用函数/方法。有关说明和问题,请参阅以下示例。我希望我对这种情况知道一些技术性的话。人们会更容易理解我在说什么。

public static class test
{
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        if (Login("johndoe","password")) 
        {
            if(checkForSomething("johndoe"))
            {
                DoOpenDashboard();

                // Now it opens dashboard, it has several buttons. 
                // Each button does several different things
                // On this example I am just giving you two level of hierarchy
                // but in my actual program, there are 7 levels.
            }
        }
    }

    public static bool Login(string userid, string password)
    {
        //valid user
        return true;
    }

    public static bool checkForSomething(string userid) 
    {
        return true;
    }

如果子方法成功运行,如何避免进程返回上一个调用方法/函数?

例如,登录方法正在调用checkForSomething("johndoe")。如果传递checkForSomething("johndoe"),则它将通过调用DoOpenDashboard打开仪表板窗口。此时我的进程应该不应该回到checkforsoemthing,然后登录。我希望这是有道理的。

2 个答案:

答案 0 :(得分:0)

不清楚你在这里问什么。您的伪代码显示在类的构造函数中调用的Login()方法。如果这确实是你的代码工作的方式,那么为了防止再次调用Login,你需要避免创建这个类的新实例。

但是,我认为你真的在询问Arrow反模式:

http://codinghorror.com/blog/2006/01/flattening-arrow-code.html

修改

我试图避免复制&粘贴,但由于原始帖子似乎不够清楚,这里有一个来自上面链接的Coding Horror的选择:

  

在适当的情况下,我通过执行以下操作来展平箭头代码:

     
      
  1. 用保护条款替换条件。这段代码..

         

    if(SomeNecessaryCondition){       //功能体代码   }

         

    ..作为一个保护条款效果更好:

         

    if(!SomeNecessaryCondition)   {       抛出新的RequiredConditionMissingException;   }   //功能体代码

  2.   

(请注意,还列出了其他技术,但我认为第一个就足够了)

这样,每次附加检查都不会导致另一个嵌套if - 一旦任何检查失败,方法调用将失败。这也可以通过让button1_Click调用返回bool的函数(成功为true,失败为false)并在失败条件下立即返回false来抛出异常:

private void button1_Click(object sender, RoutedEventArgs e)
{
    if (AllSystemsGo())
    {
        DoOpenDashboard();
    }
}

private bool AllSystemsGo()
{
    if (!Login("johndoe","password"))
        return false;

    if (checkForSomethingEvil("johndoe"))
        return false;

    if (!checkForSomethingImportant())
        return false;

    return true;
}

答案 1 :(得分:0)

您是否尝试确保仅检查一次方法?也许你需要多次查询一些属性,但只测试一次。

private bool? canLogin;
private bool? somethingOk;

private bool CanLogin
{
    get
    {
        if (canLogin == null)
            canLogin = Login("johndoe","password");
        return canLogin.Value;
    }
}

private bool SomethingOk
{
    get
    {
        if (somethingOk == null)
            somethingOk = checkForSomething("johndoe");
        return somethingOk .Value;
    }
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    if (this.CanLogin && this.SomethingOk && // other checks) 
    {
        DoOpenDashboard();            
    }
}