Проблема с иерархией вызовов - PullRequest
0 голосов
/ 28 октября 2011

У меня есть ситуация, когда я вызываю функцию / метод в каскадном стиле. Смотрите следующий пример для иллюстрации и вопроса. Хотел бы я знать какое-то техническое слово для этой ситуации. Людям было бы легче понять, о чем я говорю.

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") передано, то оно откроет окно Dashboard, вызвав DoOpenDashboard. На этом этапе мой процесс не должен возвращаться к checkforsoemthing, а затем войти в систему. Я надеюсь, что это имеет смысл.

Ответы [ 2 ]

0 голосов
/ 28 октября 2011

Вы пытаетесь убедиться, что ваши методы проверены только один раз?Возможно, вам нужно, чтобы некоторые свойства запрашивались несколько раз, но проверялись только один раз.

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();            
    }
}
0 голосов
/ 28 октября 2011

Не совсем понятно, о чем вы спрашиваете здесь. Ваш псевдокод показывает метод Login (), вызываемый в конструкторе вашего класса. Если ваш код работает именно так, то для предотвращения повторного вызова Login вам необходимо избегать создания новых экземпляров этого класса.

Тем не менее, я думаю, что вы действительно спрашиваете об анти-паттерне Arrow:

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

EDIT

Я пытался избежать копирования и вставки, но так как исходное сообщение, кажется, не было достаточно ясным, вот выбор из Coding Horror, как указано выше:

Где это уместно, я выравниваю код стрелки, выполняя следующее:

  1. Заменить условия защитными оговорками. Этот код ..

    if (SomeNe Необходимое Условие) { // код тела функции } * * Тысяча двадцать-один

    .. лучше работает как пункт охраны:

    if (! SomeNe Необходимое Условие) { бросить новое RequiredConditionMissingException; } // код тела функции

(обратите внимание, что есть и другие техники, перечисленные в списке, но я думаю, что этой первой пока хватит)

Таким образом, каждая дополнительная проверка не приводит к другой вложенности, если - если одна из проверок не пройдена, вызов метода завершится неудачно. Это также можно сделать, не вызывая исключения, вызвав 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;
}
...