Szukam właściwego patterna zamiast używać wielu IFów

0

Witajcie, taka historia:

          bool _runNextStep = true;

          using (IWebDriver driver = new ChromeDriver())
            {              
                WdPageRequest req = new WdPageRequest(driver);


                if (req.GoToPage() == false)
                {
                    MessageBox.Show("Nie wyświetlił strony");
                    _runNextStep = false;
                }

                if (_runNextStep == true)
                {
                    if (req.FillForm("777777") == false)
                    {
                        MessageBox.Show("Nie uzupełnił pola");
                        _runNextStep = false;
                    }
                }

                if (_runNextStep == true)
                {
                    if (req.SetType(1) == false)
                    {
                        MessageBox.Show("Nie uzupełnił typu");
                        _runNextStep = false;
                    }
                }
[...]

Czy istnieje jakiś pattern, żeby skrócić ten kod / sprawić żeby był bardziej przejrzysty?

2
        bool _runNextStep = true;
        using (IWebDriver driver = new ChromeDriver())
        {              
            WdPageRequest req = new WdPageRequest(driver);

            if (!req.GoToPage())
            {
                MessageBox.Show("Nie wyświetlił strony");
                _runNextStep = false;
            } 

            if (_runNextStep)
            {
                if (!req.FillForm("777777"))
                {
                    MessageBox.Show("Nie uzupełnił pola");
                     _runNextStep = false;
                }
                if (!req.SetType(1))
                {
                    MessageBox.Show("Nie uzupełnił typu");
                     _runNextStep = false;
                }
            }
1

Chain of Responsibility?

1

Maszyna stanów?

0

Użyj wyjątków i nie komplikuj sprawy

7

Jeżeli byś wydzielił do tego jakąś klasę, to byłoby znacznie czytelniej :P

var wd = new WdPageRequest();
bool _runNextStep = true;

var requirements = new List<(Func<WdPageRequest, bool> Requirement, string Error)>();

requirements.Add((x => x.GoToPage(), "Nie wyświetlił strony"));
requirements.Add((x => x.SetType(1) && _runNextStep, "Nie uzupełnił pola"));
requirements.Add((x => x.FillForm("7777") && _runNextStep, "Nie uzupełnił pola"));
            
foreach (var req in requirements)
{
    if (!req.Requirement.Invoke(wd))
    {
        Console.WriteLine(req.Error);
        _runNextStep = false; break;
    }
}
public class WdPageRequest
{
    public bool FillForm(string a)
    {
        return false;
    }
    public bool SetType(int a)
    {
        return true;
    }
    public bool GoToPage()
    {
        return true;
    }
}
1
WdPageRequest req = new WdPageRequest(driver);

if (!req.GoToPage()) {
  throw new AssertionException("Nie wyświetlił strony");
}
                 
if (!req.FillForm("777777"))
  throw new AssertionException("Nie uzupełnił pola");
}

if (!req.SetType(1))
  throw new AssertionException("Nie uzupełnił typu");
}

1

Czasem trzeba używać ifów, po to one są. Nie bójmy się ifów, nie popadajmy w paranoję :D

1
NeutrinoSpinZero napisał(a):

Czasem trzeba używać ifów, po to one są. Nie bójmy się ifów, nie popadajmy w paranoję :D

@NeutrinoSpinZero, a innym razem można użyć regresji wielomianowej :D

1

Ja bym to po prostu rozbil na mniejsze funkcje. Kazdy blok IF bedzie oddzielna funkcja, wtedy pierwsza linia kodu bedzie mogla wygladac tak:

        var runNextStep = DisplayedPage(req) && FilledForm(req) && FilledType(req);

        // Przyklad funkcji sprawdzajacej
        static bool DisplayedPage(WdPageRequest req)
        {
            if (req.GoToPage())
                return true;

            MessageBox.Show("Nie wyświetlił strony");
            return false;
        }
1

Najlepszym rozwiązaniem powinno być zainstalowanie Nunit (lub innego dowolnego) i rozbicie tego na testy jednostkowe. VS ma chyba też wbudowany framework do testów jeżeli się nie mylę.

3

Nie ma nic złego w ifach, po co wymyślać na siłę "patterny" jak można to po prostu zakodować.

Tylko wywal przyrównania == true i == false.

0

Super! Pozwolę sobie dopytać jeszcze jedną kwestię. Wysłanie danych mam zrobione w taki sposób, że (wg wzorca PageObject Selenium):

WdPageResponse resp = wd.SubmitForm();

Wykonuje to czynność i zwraca nową stronę

public WdPageResponse SubmitForm()
{
      CaptchaTxtbox.SendKeys(Keys.Enter);
      return new WdPageResponse(driver);
}

Finałowym krokiem jest pobranie danych do formularza: textBox1.Text = resp.GetResponse();

.. no to pytanie: czy możliwa jest taka konstrukcja żeby możliwe było działanie takiego kodu:

var wd = new WdPageRequest(driver);
[..]
requirements.Add((x => x.wd.GoToPage(), "Nie wyświetlił strony"));
requirements.Add((x => x.wd.SetType(1), "Nie uzupełnił pola"));
requirements.Add((x => x.wd.FillForm("7777"), "Nie uzupełnił pola"));
requirements.Add((x => x.WdPageResponse resp = req.SubmitForm(), "Nie uzyskał odpowiedzi - wysłanie zapytania"));
requirements.Add((x => x.textBox1.Text = resp.GetResponse(), "Nie uzyskał odpowiedzi - ekstrakcja danych"));

Dzięki i pozdrawiam

WeiXiao napisał(a):

Jeżeli byś wydzielił do tego jakąś klasę, to byłoby znacznie czytelniej :P

var wd = new WdPageRequest();
bool _runNextStep = true;

var requirements = new List<(Func<WdPageRequest, bool> Requirement, string Error)>();

requirements.Add((x => x.GoToPage(), "Nie wyświetlił strony"));
requirements.Add((x => x.SetType(1) && _runNextStep, "Nie uzupełnił pola"));
requirements.Add((x => x.FillForm("7777") && _runNextStep, "Nie uzupełnił pola"));
            
foreach (var req in requirements)
{
    if (!req.Requirement.Invoke(wd))
    {
        Console.WriteLine(req.Error);
        _runNextStep = false; break;
    }
}
public class WdPageRequest
{
    public bool FillForm(string a)
    {
        return false;
    }
    public bool SetType(int a)
    {
        return true;
    }
    public bool GoToPage()
    {
        return true;
    }
}
0

Jeszcze trochę to uprościłem, ale pytanie o to, jak upchnąć funkcję wysyłającą formularz w listę jest ciągle aktualne.

using (IWebDriver driver = new ChromeDriver())
            {
                bool runNextStep = true;
                WdPageRequest req = new WdPageRequest(driver);

                var actions = new List<(bool Action, string Error)>()
                {
                    (req.GoToPage(), "Nie wyświetlił strony"),
                    (req.FillForm("7777"), "Nie uzupełnił pola"),
                    (req.SetType(1), "Nie uzupełnił typu"),
                };


                foreach (var act in actions)
                {
                    if (!act.Action)
                    {
                        MessageBox.Show(act.Error);
                        runNextStep = false;
                        break;
                    }
                }

                // jak to upchnąć w listę actions??
                if (runNextStep)
                {
                    WdPageResponse resp = req.SubmitForm();
                    textBox1.Text = resp.GetResponse();
                }
            }

1 użytkowników online, w tym zalogowanych: 0, gości: 1