Очистка вложенных операторов if, чтобы сделать их более читабельными?

Я пишу проект, и часть, которой я занимаюсь сейчас, очень быстро приобретает форму стрелки. Как я могу удалить вложенные операторы if, но при этом вести себя так же?

Код ниже может выглядеть не так уж плохо сейчас, но я планирую провести рефакторинг, чтобы включить больше методов.

public async Task FirstDiffTestAsync()
{
    string folderDir = "../../../";
    string correctReportDir = folderDir + "Reports To Compare/Testing - Copy.pdf";
    string OptyNumber = "122906";

    //Making a POST call to generate report
    string result = ReportGeneration(OptyNumber).Result;
    Response reportResponse = JsonConvert.DeserializeObject<Response>(result);
    string newURL = reportResponse.documentUrl;

    //Logging the Response to a text file for tracking purposes
    await File.WriteAllTextAsync(Context.TestRunDirectory + "/REST_Response.txt", result);

    using (StreamWriter w = File.AppendText(Context.TestDir + "/../log.txt"))
    {
        //Checking if the Integration failed
        if (reportResponse.Error == null)
        {
            //now we have the url, reading in the pdf reports
            List<string> Files = new List<string> { correctReportDir, newURL };
            List<string> parsedText = PdfToParsedText(Files);

            DiffPaneModel diff = InlineDiffBuilder.Diff(parsedText[0], parsedText[1]);

            // DiffReport is a customised object
            DiffReport diffReport = new DiffReport(correctReportDir, newURL);
            diffReport.RunDiffReport(diff);

            //In-test Logging
            string indent = "\n      - ";
            string logMsg = $"{indent}Opty Number: {OptyNumber}{indent}Activity Number: {reportResponse.ActivityNumber}{indent}File Name: {reportResponse.FileName}";
            if (diffReport.totalDiff != 0)
            {
                await File.WriteAllTextAsync(Context.TestRunDirectory + "/DiffReport.html", diffReport.htmlDiffHeader + diffReport.htmlDiffBody);
                logMsg += $"{indent}Different lines: {diffReport.insertCounter} Inserted, {diffReport.deleteCounter} Deleted";
            }
            LogTesting(logMsg, w);

            //Writing HTML report conditionally
            if (diffReport.totalDiff != 0)
            {
                await File.WriteAllTextAsync(Context.TestRunDirectory + "/DiffReport.html", diffReport.htmlDiffHeader + diffReport.htmlDiffBody);
            }
            Assert.IsTrue(diffReport.insertCounter + diffReport.deleteCounter == 0);
        }
        else
        {
            LogTesting($" Integration Failed: {reportResponse.Error}", w);
            Assert.IsNull(reportResponse.Error);
        }
    }
}

Я ожидал увидеть десять уровней отступа, когда прочитал заголовок. Это нормально

Caius Jard 16.03.2022 07:57

Если вы счастливы использовать return среднюю часть тела (некоторые люди этого не делают), переверните логику if, чтобы вместо этого две строки else выполнялись if, а return из метода в if. Удалите остальные 20+ строк (ранее в if) из обложки любым условным выражением. Я рад структурировать такие методы, как «верхний раздел делает ifs для проверки правильности данных, возвращает или бросает, если нет, тогда остальную часть тела не нужно хоронить в длинном блоке else»

Caius Jard 16.03.2022 07:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Лучший способ сделать это — написать отдельную функцию, содержащую этот блок кода, а затем вызвать эту функцию вместо вложенных операторов if.

В вашем случае это будет примерно так:

private async void checkTotalDiff(diffReport) {
      ...
}

Вы можете передать все, что вам может понадобиться в параметрах. Таким образом, в вашем основном коде вы можете заменить операторы if на checkTotalDiff(diffReport) и сохранить результат (если он есть) в переменной.

Также обратите внимание, что я использовал void для возврата, но вы можете изменить тип в зависимости от того, что возвращает функция.

Ответ принят как подходящий

Я бы не стал рассматривать это как чрезмерное количество вложенных операторов if. Это хорошо, как есть. В противном случае вы можете сделать следующее (также предложено @Caius Jard):

public async Task FirstDiffTestAsync()
{
    string folderDir = "../../../";
    string correctReportDir = folderDir + "Reports To Compare/Testing - Copy.pdf";
    string OptyNumber = "122906";

    //Making a POST call to generate report
    string result = ReportGeneration(OptyNumber).Result;
    Response reportResponse = JsonConvert.DeserializeObject<Response>(result);
    
    //Checking if the Integration failed
    if (reportResponse.Error != null)
    {
        LogTesting($" Integration Failed: {reportResponse.Error}", w);
        Assert.IsNull(reportResponse.Error);
        return;
    }

    string newURL = reportResponse.documentUrl;

    //Logging the Response to a text file for tracking purposes
    await File.WriteAllTextAsync(Context.TestRunDirectory + "/REST_Response.txt", result);

    using (StreamWriter w = File.AppendText(Context.TestDir + "/../log.txt"))
    {
        //now we have the url, reading in the pdf reports
        List<string> Files = new List<string> { correctReportDir, newURL };
        List<string> parsedText = PdfToParsedText(Files);

        DiffPaneModel diff = InlineDiffBuilder.Diff(parsedText[0], parsedText[1]);

        // DiffReport is a customised object
        DiffReport diffReport = new DiffReport(correctReportDir, newURL);
        diffReport.RunDiffReport(diff);

        //In-test Logging
        string indent = "\n      - ";
        string logMsg = $"{indent}Opty Number: {OptyNumber}{indent}Activity Number: {reportResponse.ActivityNumber}{indent}File Name: {reportResponse.FileName}";
        if (diffReport.totalDiff != 0)
        {
            await File.WriteAllTextAsync(Context.TestRunDirectory + "/DiffReport.html", diffReport.htmlDiffHeader + diffReport.htmlDiffBody);
            logMsg += $"{indent}Different lines: {diffReport.insertCounter} Inserted, {diffReport.deleteCounter} Deleted";
        }
        LogTesting(logMsg, w);

        //Writing HTML report conditionally
        if (diffReport.totalDiff != 0)
        {
            await File.WriteAllTextAsync(Context.TestRunDirectory + "/DiffReport.html", diffReport.htmlDiffHeader + diffReport.htmlDiffBody);
        }
        Assert.IsTrue(diffReport.insertCounter + diffReport.deleteCounter == 0);
    }
}

Другие вопросы по теме