Как сделать этот код более читабельным? - PullRequest
10 голосов
/ 21 октября 2010

Я написал это сегодня, и мне стыдно.Что мне нужно сделать, чтобы этот хаотичный материал был более точным и читаемым среди других?

switch ((RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType)Enum.Parse(typeof(RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType), ihdType.Value))
    {
            //REF:This can (but should it?) be refactored through strategy pattern
        case RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType.ReportPlanWithEffects:
            grvEconomicCriteria.DataSource = RequestReportsCalculatingStoredProcedures.ReportsDataParser(
                            RequestReportsCalculatingStoredProcedures.ReportPlanWithEffects(requestNo, RequestReportsCalculatingStoredProcedures.GetAlgorithmNoByRequestNo(requestNo)));
            break;
        case RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType.ReportPlanWithEffectsForFacts:
            DateTime factDate;
            try
            {
                factDate = Convert.ToDateTime(ihdDate.Value);
            }
            catch(FormatException)
            {
                grvEconomicCriteria.DataSource = RequestReportsCalculatingStoredProcedures.ReportsDataParser(
                            RequestReportsCalculatingStoredProcedures.ReportPlanWithEffectsForFacts(requestNo, RequestReportsCalculatingStoredProcedures.GetAlgorithmNoByRequestNo(requestNo), DateTime.MinValue));
                break;
            }
            grvEconomicCriteria.DataSource = RequestReportsCalculatingStoredProcedures.ReportsDataParser(
                            RequestReportsCalculatingStoredProcedures.ReportPlanWithEffectsForFacts(requestNo, RequestReportsCalculatingStoredProcedures.GetAlgorithmNoByRequestNo(requestNo), factDate));
            break;
        default:
            break;
    }

Ответы [ 9 ]

17 голосов
/ 21 октября 2010

Вы всегда можете использовать псевдоним для очень длинного типа RequestReportsCalculatingStoredProcedures:

using RRCSP = RequestReportsCalculatingStoredProcedures;

Примечание: вам нужно будет использовать полное имя (включая пространство имен) вusing директива.

11 голосов
/ 21 октября 2010

Помимо того, что другие говорили о сокращении имен и т. Д., Вам следует подумать о том, чтобы извлечь код из оператора case в вызовы функций, чтобы вы получили что-то вроде

switch (myMassiveVariable)
{
    case RequestReportStoredProcedureType.ReportPlanWithEffects:
        RunReportWithEffects(requestNo);
        break;
    case RequestReportStoredProcedureType.ReportPlanWithEffectsForFacts:
        RunReportWithFacts(requestNo);
        break;
}

немного привести в порядок вещи.

5 голосов
/ 21 октября 2010

Честно говоря, одна из самых больших проблем здесь - это только длина имен ваших переменных.

Очевидно, вы должны указать переменные / типы / и т.д.описательные имена.Но есть момент, когда это становится немного экстремальным.Один парень на моей работе известен тем, что называет методы такими именами, как:

DoSomethingVerySpecificHereIsOneOfItsSideEffectsAndHereIsAnother

В вашем случае я замечаю большую избыточность.Например, у вас есть класс с именем RequestReportsCalculatingStoredProcedures, а затем в этом классе вы, кажется, имеете перечисление с именем RequestReportStoredProcedureType.Поскольку перечисление уже является вложенным типом в RequestReportsCalculatingStoredProcedures, возможно, вы могли бы просто назвать его Type?

В качестве альтернативы, очень эффективный способ сократить эти имена (по крайней мере вfile) будет использовать простое объявление using:

using E = RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType;

Тогда посмотрите, что происходит с вашим кодом:

using RRCSP = RequestReportsCalculatingStoredProcedures;
using E = RRCSP.RequestReportStoredProcedureType;

// ...

// Note: RRCSP = RequestReportsCalculatingStoredProcedures, and
//       E = RRCSP.RequestReportStoredProcedureType

switch ((E)Enum.Parse(typeof(E), ihdType.Value))
    {
        //REF:This can (but should it?) be refactored through strategy pattern
        case E.ReportPlanWithEffects:
            grvEconomicCriteria.DataSource = RRCSP.ReportsDataParser(
                RRCSP.ReportPlanWithEffects(
                    requestNo,
                    RRCSP.GetAlgorithmNoByRequestNo(requestNo)
                )
            );
            break;
        case E.ReportPlanWithEffectsForFacts:
            DateTime factDate;
            try
            {
                factDate = Convert.ToDateTime(ihdDate.Value);
            }
            catch(FormatException)
            {
                grvEconomicCriteria.DataSource = RRCSP.ReportsDataParser(
                    RRCSP.ReportPlanWithEffectsForFacts(
                        requestNo,
                        RRCSP.GetAlgorithmNoByRequestNo(requestNo),
                        DateTime.MinValue
                    )
                );
                break;
            }
            grvEconomicCriteria.DataSource = RRCSP.ReportsDataParser(
                RRCSP.ReportPlanWithEffectsForFacts(
                    requestNo,
                    RRCSP.GetAlgorithmNoByRequestNo(requestNo),
                    factDate
                )
            );
            break;
        default:
            break;
    }

Это более читабельно?На мой взгляд, да, в первую очередь потому, что на это просто не так сложно смотреть.Очевидно, что вы делаете компромисс, хотя, поскольку используемые псевдонимы менее сразу очевидны, чем исходные имена.Как и все остальное, в конечном итоге все сводится к личному суждению.

5 голосов
/ 21 октября 2010

Я твердо верю в описательные имена переменных, классов и методов. Я бы всегда выбрал ясность, а не краткость, однако одно простое в применении правило состоит в том, что если у вас есть часть ваших имен, которая всегда повторяется, вы можете сократить это. Например, у вас есть:

RequestReportsCalculatingStoredProcedures

Это хорошо. Это объясняет, что это ясно. Однако у вас есть члены этого класса или объекта, которые также начинаются с этого имени, плюс дифференцирующие имена в конце. Например:

RequestReportStoredProcedureType

Это может быть сокращено до StoredProcedureType, или даже, возможно, с TemplateType.

Я знаю, что многие программисты будут спорить о чем-то вроде RRCalcSP или о каких-то совершенно неясных соглашениях об именах, но я бы никогда не стал жертвовать ясностью именования во избежание переноса строк и т. Д.

Честно говоря, то, что вы имеете в своем первоначальном примере, не является хаотичным или постыдным. Это так долго, что вам приходится иметь дело с переносом строк.

Кроме того, щедрое использование комментариев делает вещи намного понятнее.

3 голосов
/ 21 октября 2010

Если у вас есть некоторый контроль над кодом, который вы используете, я бы порекомендовал:

  1. Перевести перечисление RequestReportsCalculationStoredProcedures.RequestReportStoredProcedureType во внешнюю область. Внутреннее имя уже достаточно многословно, и вам не нужно уточнять внешнее имя.

  2. Попробуйте заменить длинные имена классов именами, поясняющими их намерения, без описания деталей того, как они выполняют свою работу.

  3. Обеспечивает перегрузку RequestReportsCalculationStoredProcedures.ReportPlanWithEffectsForFacts, для которой не требуется параметр алгоритма, поскольку вы, по-видимому, в любом случае можете искать его по запросу No. Это исключает подробный вызов RequestReportsCalculationStoredProcedures.GetAlgorithmNoByRequestNo, когда вам не нужно предоставлять нестандартный алгоритм.

2 голосов
/ 21 октября 2010

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

Класс RequestReportsCalculationStoredProcedure, который я переименовал бы в RequestReports. Мне кажется, что часть StoredProcedure - это деталь реализации, которая больше никого не касается. Я не уверен, что слово «Расчет» приносит в таблицу, поэтому я также удалил его.

Перечисление RequestReportStoredProcedureType, которое я переименовал бы в ReportPlan, так как это, казалось, лучше всего соответствует контексту (ReportType также возможен) Дополнительная многословность была удалена по аналогии с причинами, по которым класс, который ее охватывает, был переименован. Я оставил его внутри класса, так как он, кажется, обеспечивает некоторый контекст, и с сокращенными именами это казалось хорошей идеей.

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

С учетом этих изменений код будет выглядеть следующим образом:

switch((RequestReports.ReportPlan)Enum.Parse(typeof(RequestReports.ReportPlan), ihdType.Value)) {
            //REF:This can (but should it?) be refactored through strategy pattern
            case RequestReports.ReportPlan.WithEffects:
                Object reportPlan = RequestReports.ReportPlanWithEffects(requestNo);
                grvEconomicCriteria.DataSource = RequestReports.ReportsDataParser(reportPlan);
                break;
            case RequestReports.ReportPlan.WithEffectsForFacts:
                DateTime factDate;
                try {
                    factDate = Convert.ToDateTime(ihdDate.Value);
                }
                catch(FormatException) {
                    Object reportPlan2 = RequestReports.ReportPlanWithEffectsForFacts(requestNo, DateTime.MinValue);
                    grvEconomicCriteria.DataSource = RequestReports.ReportsDataParser(reportPlan2);
                    break;
                }
                Object reportPlan3 = RequestReports.ReportPlanWithEffectsForFacts(requestNo, factDate);
                grvEconomicCriteria.DataSource = RequestReports.ReportsDataParser(reportPlan3);
                break;
            default:
                break;
            }
1 голос
/ 21 октября 2010

Посмотрите на , используя команду .

Также я верю (не проверял), но вы можете сделать что-то похожее на:

RequestReportsCalculatingStoredProcedure myShortCut = RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType;

Тогда вместо ссылки на большие строки вы можете ссылаться на myShortCut.

0 голосов
/ 21 октября 2010

Я бы выступил за извлечение общих частей из описания дела

RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType dependingOnType =(RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType)Enum.Parse(typeof(RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType), ihdType.Value);

var EssentialData = null;
var AlgorithmChosen = RequestReportsCalculatingStoredProcedures.GetAlgorithmNoByRequestNo(requestNo);

switch (dependingOnType)
    {
            //REF:This can (but should it?) be refactored through strategy pattern
        case RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType.ReportPlanWithEffects:
           EssentialData  = RequestReportsCalculatingStoredProcedures.ReportPlanWithEffects(requestNo, AlgorithmChosen);
            break;
        case RequestReportsCalculatingStoredProcedures.RequestReportStoredProcedureType.ReportPlanWithEffectsForFacts:
            DateTime factDate = Datetime.MinValue;

            if (!DateTime.TryParse(ihdDate.Value, factDate)) {
                factDate = DateTime.MinValue;
            }

               EssentialData  = RequestReportsCalculatingStoredProcedures.ReportPlanWithEffectsForFacts(requestNo, AlgorithmChosen, factDate);

            break;
        default:
            break;
    }

grvEconomicCriteria.DataSource = RequestReportsCalculatingStoredProcedures.ReportsDataParser(essentialData);

Вы можете уточнить это событие больше, рассчитав

RequestReportsCalculatingStoredProcedures.GetAlgorithmNoByRequestNo(requestNo)

только один раз

изменить: как это:)

0 голосов
/ 21 октября 2010

Вы можете применить шаблон стратегии, как вы прокомментировали, или использовать словарь с делегатами (Func <> или Action <>), который на основе типа что-то делает. Вы можете сократить DateTime try / catch, используя метод DateTime.TryParse (). Кроме этого, в вашем коде больше всего не читаются длинные имена, так что вы можете поместить некоторые из них в переменные перед запуском кода

надеюсь, это поможет

...