Çağrı Hiyerarşisi ile Sorun

Basamaklı tarzında işlev/yöntem çağıran bir durum var. Örnekleme ve soru için aşağıdaki örneğe bakınız. Keşke bu durum için bir teknik kelime bilebilseydim. İnsanların neden bahsettiğimi anlaması daha kolay olurdu.

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

Çocuk yöntemi başarılı bir şekilde çalışıyorsa, önceki çağrı yöntemine/işlevine geri dönmek için işlemden nasıl kaçınırım?

Örneğin, giriş yöntemi checkForSomething ("johndoe") çağırıyor. checkForSomething ("johndoe") geçilirse, DoOpenDashboard'u arayarak Pano penceresini açar. Bu noktada sürecimin kontrol edilmesine geri dönmemesi ve sonra giriş yapması gerekiyor. Umarım mantıklıdır.

1
İstediğiniz şey (kolayca) yapılabilse bile, kaç kez çağırdığınıza göre farklı davranan bir yönteme sahip olursanız, tek sorumluluk ilkesini hala ihlal edersiniz. Sistemi korumak kesinlikle zor olacaktır.
katma yazar R0MANARMY, kaynak
Senin sorununun anlaşılması çok zor. Kullanıcınızın zaten giriş yapmış olup olmadığını belirtmek için sınıfınıza bir statik değişken veya örnek üyesi ekleyemez ve yalnızca Giriş() 'i çağırırsanız, bu boolean'ın değeri yanlış mıdır?
katma yazar Kiley Naro, kaynak
Bunu içeren sınıfın aynı adına sahip bir yönteme sahip olamazsınız.
katma yazar Miguel Angelo, kaynak
Lütfen soruyu kod bloğu dışına taşıyın ... şimdi olduğu gibi okumak imkansız.
katma yazar Miguel Angelo, kaynak

2 cevap

Burada ne sorduğun konusunda pek net değil. Sözdizim kodunuz, sınıfınızın yapıcısında çağrılan Login() yöntemini gösterir. Bu gerçekten kodunuzun nasıl çalıştığını gösteriyorsa, tekrar Oturum açmayı engellemek için bu sınıfın yeni örneklerinin oluşturulmasını önlemeniz gerekir.

Ancak, ok anti-desenini gerçekten sorduğunuzu düşünüyorum:

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

DÜZENLEME

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

(ayrıca listelenen başka tekniklerin de olduğunu unutmayın, ancak bence ilk önce bunun için yeterli olacaktır)

Bu şekilde, her ek kontrol başka bir iç içe geçmez, eğer herhangi bir kontrol başarısız olursa, yöntem çağrısı başarısız olur. Bu ayrıca, button1_Click seçeneğine sahip bir istisna atmadan, bir boole (başarı için true, başarısızlık için false) döndüren ve başarısız bir durumda hemen false döndüren bir işlevi çağırmak için de yapılabilir:

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;
}
0
katma
Belli ki biri ya da diğeri değil. Açıkçası bu kod derleme değildir ve tahmininiz benimki kadar iyidir, dönüş değeri bir hata mı yoksa yöntem adı bir hata mıdır?
katma yazar sq33G, kaynak
Bu bir kurucu değil, sadece sınıfla aynı adı taşıyan bir yöntem (bir dönüş türüne sahip olduğunu unutmayın).
katma yazar R0MANARMY, kaynak
Mümkün olan her yerde "Düzleştirilen Ok Kodu" nda belirtildiği gibi kontraksiyon kontrolü kullanıyorum. Ben kodu vb6 kod iş mantığı ayıklanıyor. İş mantığını çıkardığımdan ve anladığımdan beri, korkunç bir duruma geçiyorum.
katma yazar Shai, kaynak

Yöntemlerinizin yalnızca bir kez kontrol edildiğinden emin olmaya çalışıyor musunuz? Belki birden çok kez sorgulanmak için bazı özelliklere ihtiyacınız var, ancak sadece bir kez test edildi.

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
katma