简体   繁体   English

重构我的C#代码:if-else语句和代码重复

[英]Refactor my C# code : if-else statement and code repetition

Given: 鉴于:

private void UpdataFieldItems(List<FieldItemBase> existingFieldItems, List<FieldItemBase> selectedFieldItems)
    {
        List<FieldItemBase> newFieldItemsSelected;
        var fieldSelectionChanges = GetFieldSelectionChanges(out newFieldItemsSelected);//retuns a Flagged enum

        if (Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem))
        {
            StartEditMode();
            SetColumnDescriptorsToAdd(newFieldItemsSelected);
            UpdateItems(selectedFieldItems);

            SetColumnsToShow();
            CustomizeAlignmentAndCellFormatters(_tfaTableGrid.TableGrid);

            if (_tfaTableGrid.TableGrid.ColumnDescriptors.Count() > 0)
            {
                SetAdditionalFirstGroupedColumn();
            }

            StopEditMode();
        }

        else if (Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary))
        {
            StartEditMode();

            UpdateItems(fieldItems);
            SetColumnsToShow();

            if (_tfaTableGrid.TableGrid.ColumnDescriptors.Count() > 0)
            {
                SetAdditionalFirstGroupedColumn();
            }

            StopEditMode();

        }

        else if (Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Order) ||
                 Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedCustomFieldItem) ||
                 Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.RemovedItem))
        {
            UpdateItems(fieldItems);
            SetColumnsToShow();

        }
            Invalidate();
    }

//Coding.cs
public static bool EnumHas(FieldSelectionChanges selectionChanges, FieldSelectionChanges valueToCheck)
        {
            return (selectionChanges & valueToCheck) == valueToCheck;
        }

I am willing to refactor the above code. 我愿意重构上面的代码。 There are two things that i don't like about the code above: 关于上面的代码,我不喜欢两件事:

1) Writing same method calls in different cases, its not being possible to pull out the common method calls from these cases. 1)在不同的情况下编写相同的方法调用,不可能从这些情况中提取常见的方法调用。

2) The readability of this code is very bad. 2)这段代码的可读性非常糟糕。 It would be very confusing to understand and debug, if later needed. 如果以后需要,理解和调试会非常混乱。

Can someone suggest a design pattern for this code? 有人可以建议这个代码的设计模式吗? or some way to improve upon the above two concerns? 或某种方式来改善上述两个问题?

Thanks for your interest. 谢谢你的关注。

  1. Use extract method for body of each if statement 对每个if语句的主体使用extract方法
  2. Create Dictionary> to choose appropriate action for fieldSelectionChanges. 创建字典>为fieldSelectionChanges选择适当的操作。 This is Strategy pattern 这是战略模式

Well the part that is repetitive/somewhat ugly is the IF statements. 那么重复/有点难看的部分是IF语句。

Suggest holding the result of those IF conditions in a boolean variable, and leverage that. 建议将这些IF条件的结果保存在布尔变量中,并利用它。

This code isnt complete, but you get the idea. 这段代码不完整,但你明白了。

        bool scenarioOne = Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
        bool scenarioTwo = Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary);
        bool scenarioThree = Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Order) || Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedCustomFieldItem) || Coding.EnumHas(fieldSelectionChanges,FieldSelectionChanges.RemovedItem);

        if (scenarioOne || scenarioTwo)
            StartEditMode();

        if (scenarioOne) {
            SetColumnDescriptorsToAdd(newFieldItemsSelected);
            UpdateItems(selectedFieldItems);
        }
        else if (scenarioTwo || scenarioThree) {
            UpdateItems(fieldItems);
        }

        if (scenarioOne || scenarioTwo || scenarioThree)
            SetColumnsToShow();

Obviously, pick better names for the variable. 显然,为变量选择更好的名称。

Or better yet, seperate out into seperate methods. 或者更好的是,分开进入单独的方法。

I would make the different conditions more expressive in terms of what it actually does to your application seeing you already use quite descriptive method names for the actions. 我会根据它对您的应用程序的实际操作使得不同条件更具表现力,因为您已经为操作使用了相当描述性的方法名称。 Something like: 就像是:

        private void UpdataFieldItems(List<FieldItemBase> existingFieldItems, List<FieldItemBase> selectedFieldItems)
        {
            List<FieldItemBase> newFieldItemsSelected;
            var fieldSelectionChanges = GetFieldSelectionChanges(out newFieldItemsSelected);//retuns a Flagged enum

            if (IsValidChange(fieldSelectionChanges))
            {
                List<FieldItemBase> targetfields = null;
                if (IsInEditMode(fieldSelectionChanges))
                    StartEditMode();

                if (IsItemAdded(fieldSelectionChanges))
                {
                    SetColumnDescriptorsToAdd(newFieldItemsSelected);
                    targetFields = selectedFieldItems;
                }
                else
                    targetFields = existingFieldItems;

                UpdateItems(targetFields);
                SetColumnsToShow();

                if (IsItemAdded(fieldSelectionChanges))
                    CustomizeAlignmentAndCellFormatters(_tfaTableGrid.TableGrid);

                if (IsInEditMode(fieldSelectionChanges))
                {
                    if (_tfaTableGrid.TableGrid.ColumnDescriptors.Count() > 0)
                        SetAdditionalFirstGroupedColumn();
                    StopEditMode();
                }
            }

            Invalidate();
        }

        private bool InEditMode(FlaggedEnum fieldSelectionChanges)
        {
            return Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary) || Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
        }

        private bool IsItemAdded(FlaggedEnum fieldSelectionChanges)
        {
            Coding.EnumHas(Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
        }

        private bool IsValidChange(FlaggedEnum fieldSelectionChanges)
        {
            return Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Order) ||
                   Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedCustomFieldItem) ||
                   Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.RemovedItem) ||
                   Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary) ||
                   Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
        }

        //Coding.cs
        public static bool EnumHas(FieldSelectionChanges selectionChanges, FieldSelectionChanges valueToCheck)
        {
            return (selectionChanges & valueToCheck) == valueToCheck;
        }

I would suggest extracting the three blocks into separate, well-named, methods. 我建议将这三个块提取为单独的,名称很好的方法。 This will improve the readability if the UpdateFieldItems method. 如果使用UpdateFieldItems方法,这将提高可读性。 Since the three blocks are totally different, there is imo no way of consolidating these further. 由于这三个区块完全不同,因此无法进一步整合这些区块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM