调用层次结构问题

发布于 2024-12-12 10:30:59 字数 1085 浏览 0 评论 0原文

我遇到一种情况,我以级联方式调用函数/方法。请参阅以下示例以了解说明和问题。我希望我知道一些关于这种情况的技术术语。人们会更容易理解我在说什么。

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 打开 Dashboard 窗口。此时,我的进程不应该返回检查某件事,然后登录。我希望这是有道理的。

I have a situation where I am calling function/method in cascading style. See following example for illustration and question. I wish I knew some technical word for this situation. It would be easier for people understand what I am talking about.

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;
    }

How do I avoid process to go back to previous calling method/function if child method runs sucessfully?

For example login method is calling checkForSomething("johndoe"). If checkForSomething("johndoe") is passed then it will open Dashboard window by calling DoOpenDashboard. At this point my process should should not go back to checkforsoemthing, and then login. I hope it makes sense.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毁我热情 2024-12-19 10:30:59

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

但是,我认为您确实在询问 Arrow 反模式:

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

编辑

我试图避免复制和复制粘贴,但由于原始帖子似乎不够清楚,以下是上面链接的《编码恐怖》中的节选内容:

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

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

    如果(一些必要条件){
    // 函数体代码
    }

    .. 作为保护子句效果更好:

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

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

这样,每个附加检查都不会导致另一个嵌套 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;
}

Not really clear on what you're asking here. Your pseudocode shows the Login () method being called in your class's constructor. If this really is how your code is working, then to prevent calling Login again you need to avoid creation of new instances of this class.

However, I think you are really asking about the Arrow anti-pattern:

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

EDIT

I was trying to avoid copy & paste, but since the original post seems not to have been clear enough, here's a selection from Coding Horror as linked above:

Where appropriate, I flatten that arrow code by doing the following:

  1. Replace conditions with guard clauses. This code..

    if (SomeNecessaryCondition) {
    // function body code
    }

    .. works better as a guard clause:

    if (!SomeNecessaryCondition)
    {
    throw new RequiredConditionMissingException;
    }
    // function body code

(note that there are other techniques also listed, but I think that this first one will suffice for now)

This way, each additional check doesn't lead to another nested if - once any check fails, the method call fails. This can also be done without throwing an exception by having button1_Click call a function that returns a bool (true for success, false for failure) and immediately returning false on a failed condition:

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;
}
傲世九天 2024-12-19 10:30:59

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

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();            
    }
}

Are you trying to make sure that your methods are checked only once? Perhaps you need some properties to be queried multiple times, but tested only once.

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();            
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文