代码之家  ›  专栏  ›  技术社区  ›  Chris

防干图案

  •  4
  • Chris  · 技术社区  · 15 年前

    我写了这套代码,觉得很糟糕 在质量方面。如您所见,在四个case语句中的每一个 我最终重复了很多相同的代码,除了 每种情况都有一些变化。不同的项目;会话名称、网格名称 以及ManagerContext组名。有人能接受这些乱七八糟的代码吗? 给我看看更好的方法?

    private void LoadGroup(string option)
    {
        switch (option.ToUpper())
        {
            case "ALPHA":
                VList<T> alphaList = FetchInformation(
                                       ManagerContext.Current.Group1);
    
                if (Session["alphaGroup"] != null)
                {
                    List<T> tempList = (List<T>)Session["alphaGroup"];
                    alphaList.AddRange(tempList);
                }
                uxAlphaGrid.DataSource = alphaList;
                uxAlphaGrid.DataBind();
                break;
            case "BRAVO":
                VList<T> bravoList = FetchInformation(
                                       ManagerContext.Current.Group2);
    
                if (Session["bravoGroup"] != null)
                {
                    List<T> tempList = (List<T>)Session["bravoGroup"];
                    bravoList.AddRange(tempList);
                }
                uxBravoGrid.DataSource = bravoList;
                uxBravoGrid.DataBind();
                break;
            case "CHARLIE":
                VList<T> charlieList = FetchInformation(
                                       ManagerContext.Current.Group3);
    
                if (Session["charlieGroup"] != null)
                {
                    List<T> tempList = (List<T>)Session["charlieGroup"];
                    charlieList.AddRange(tempList);
                }
                uxCharlieGrid.DataSource = charlieList;
                uxCharlieGrid.DataBind();
                break;
            case "DELTA":
                VList<T> deltaList = FetchInformation(
                                       ManagerContext.Current.Group4);
    
                if (Session["deltaGroup"] != null)
                {
                    List<T> tempList = (List<T>)Session["deltaGroup"];
                    deltaList.AddRange(tempList);
                }
                uxDeltaGrid.DataSource = deltaList;
                uxDeltaGrid.DataBind();
                break;
            default:                
                break;
        }
    }
    
    8 回复  |  直到 13 年前
        1
  •  23
  •   Cade Roux    15 年前

    您应该能够将案例的各个部分提取到参数化帮助器函数中:

    function helper(grp, grpname, dg) {
        VList<T> theList = FetchInformation(grp); 
        if (Session[grpname] != null) 
        { 
            List<T> tempList = (List<T>)Session[grpname]; 
            theList.AddRange(tempList); 
        } 
        dg.DataSource = theList; 
        dg.DataBind(); 
    }
    
    private void LoadGroup(string option) 
    { 
            switch (option.ToUpper()) 
            { 
                    case "ALPHA": 
                            helper(ManagerContext.Current.Group1, "alphaGroup", uxAlphaGrid);
                            break; 
                    case "BRAVO": 
                            helper(ManagerContext.Current.Group2, "bravoGroup", uxBravoGrid);
                            break; 
                    case "CHARLIE": 
                            helper(ManagerContext.Current.Group3, "charlieGroup", uxCharlieGrid);
                            break; 
                    case "DELTA": 
                            helper(ManagerContext.Current.Group4, "deltaGroup", uxDeltaGrid);
                            break; 
                    default:                                 
                            break; 
            } 
    } 
    

    这是一个选项,我确信还有进一步的重构。

    对于更深入的重构,我将使用选项对象、可能的委托或类似的集合来查看表驱动。其工作方式是,选项将成为对象而不是字符串,并且该选项将具有配置它的属性和调用适当委托的方法。它实际上取决于您想要维护的抽象级别。有时,从常规控件继承并在子类中提供配置信息以使它们知道如何加载自己是值得的。

    这里没有足够的空间真正进入重构的深度。

        2
  •  15
  •   jason    15 年前

    我想要这样的:

    private void LoadGroup(string option) {
        Group group = GetGroup(option);
        string groupName = GetGroupName(option);
        Grid grid = GetGrid(option);
    
        BindGroup(group, groupName, grid);
    }
    
    Group GetGroup(string option) {
        // ideally this should be defined and initialized elsewhere
        var dictionary = new Dictionary<string, Group>() {
            { "ALPHA", ManagerContext.Current.Group1 },
            { "BETA", ManagerContext.Current.Group2 },
            { "CHARLIE", ManagerContext.Current.Group3 },
            { "DELTA", ManagerContext.Current.Group4 }
        };   
    
        return dictionary[option.ToUpperInvariant()];
    }
    
    string GetGroupName(string option) {
        return option.ToLowerInvariant() + "Group";
    }
    
    Grid GetGrid(string option) {
        // ideally this should be defined and initialized elsewhere
        var dictionary = new Dictionary<string, Grid>() {
            { "ALPHA", uxAlphaGrid },
            { "BETA", uxBetaGrid },
            { "CHARLIE", uxCharlieGrid },
            { "DELTA", uxDeltaGrid }
        };
    
        return dictionary[option.ToUpperInvariant()];
    }
    
    void BindGroup(Group group, string groupName, Grid grid) {
        VList<T> groupList = FetchInformation(group);
        if (Session[groupName] != null) {
            List<T> tempList = (List<T>)Session[groupName];
            groupList.AddRange(tempList);
        }
        grid.DataSource = groupList;
        grid.DataBind();
    }
    

    现在看看我们是如何很好地与变化隔离。 GetGroup 例如,可以改变它查找组的方式,我们不必担心在需要更改这些细节时查找组的所有位置。类似于 GetGroupName GetGrid . 更重要的是,如果任何查找逻辑需要在任何地方重用,我们都不会重复自己的工作。我们与变化隔离得很好,当这样考虑的时候,我们永远不会重复我们自己。

        3
  •  9
  •   Randolpho    15 年前

    记住,这只是对所显示内容的重构。根据您所展示的内容,您可能需要考虑对整个方法进行更深入的重构。然而,这可能不可行。

    因此:

    private void LoadGroup(string option)
    {
            switch (option.ToUpper())
            {
                    case "ALPHA":
                            BindData("alphaGroup", uxAlphaGrid, FetchInformation(ManagerContext.Current.Group1));
                            break;
                    case "BRAVO":
                            BindData("bravoGroup", uxBravoGrid, FetchInformation(ManagerContext.Current.Group2));
                            break;
                    case "CHARLIE":
                            BindData("charlieGroup", uxCharlieGrid, FetchInformation(ManagerContext.Current.Group3));
                            break;
                    case "DELTA":
                            BindData("deltaTeam", uxDeltaGrid, FetchInformation(ManagerContext.Current.Group4));                        
                            break;
                    default:                                
                            break;
            }
    }
    
    private void BindData(string sessionName, GridView grid, VList<T> data) // I'm assuming GridView here; dunno the type, but it looks like they're shared
    {
        if (Session[sessionName] != null)
        {
                List<T> tempList = (List<T>)Session[sessionName];
                data.AddRange(tempList);
        }
        grid.DataSource = data;
        grid.DataBind();
    
    }
    
        4
  •  2
  •   Andy West    15 年前

    与此类似的东西应该可以工作:

    private void LoadGroup(string option)
    {
            switch (option.ToUpper())
            {
                    case "ALPHA":
                            BindGroup(ManagerContext.Current.Group1, "alphaGroup", uxAlphaGrid);
                            break;
                    case "BRAVO":
                            BindGroup(ManagerContext.Current.Group2, "bravoGroup", uxBravoGrid);
                            break;
                    case "CHARLIE":
                            BindGroup(ManagerContext.Current.Group3, "charlieGroup", uxCharlieGrid);
                            break;
                    case "DELTA":
                            BindGroup(ManagerContext.Current.Group4, "deltaGroup", uxDeltaGrid);
                            break;
                    default:                                
                            break;
            }
    }
    
    private void BindGroup(GroupType group, string groupName, GridView grid)
    {
        VList<T> vList = FetchInformation(group);
    
        if (Session[groupName] != null)
        {
            List<T> tempList = (List<T>)Session[groupName];
            vList.AddRange(tempList);
        }
        grid.DataSource = vList;
        grid.DataBind();
    }
    
        5
  •  2
  •   Phil    15 年前

    这里有一个只是为了好玩(这意味着它不太可能是一个好主意,而且完全没有经过测试):

    public class YourClass
    {
        private Dictionary<string, Action> m_options;
    
        public YourClass()
        {
         m_options = new Dictionary<string, Action>
         {
          { "ALPHA",  () => LoadGroup(ManagerContext.Current.Group1, "alphaGroup", uxAlphaGrid) },
          { "BRAVO",  () => LoadGroup(ManagerContext.Current.Group2, "bravoGroup", uxBravoGrid) },
          { "CHARLIE",() => LoadGroup(ManagerContext.Current.Group3, "charlieGroup", uxCharlieGrid) },
          { "DELTA",  () => LoadGroup(ManagerContext.Current.Group4, "deltaGroup", uxDeltaGrid) },
         };
        }
    
        private void LoadGroup(string option)
        {
         Action optionAction;
    
         if(m_options.TryGetValue(option, out optionAction))
         {
                optionAction();
         }
        }
    
        private void LoadGroup(TGroup group, string groupName, TGrid grid)
        {
            VList<T> returnList = FetchInformation(group);
    
            if (Session[groupName] != null)
            {
                    List<T> tempList = (List<T>)Session[groupName];
                    returnList.AddRange(tempList);
            }
            grid.DataSource = returnList;
            grid.DataBind();
        }
    }
    

    如果我希望能够动态地改变(即在运行时)选项集匹配,并且我希望执行的代码(加载算法)是完全开放的,那么我只需要这样做。

        6
  •  1
  •   Tomas Aschan    15 年前
    private void LoadGroup(string option)
    {
        option = option.ToLower();
        sessionContent = Session[option + "Group"];
    
        switch(option)
        {
            case "alpha":
                var grp = ManagerContext.Current.Group1;
                var grid = uxAlphaGrid;
                break;
            case "bravo":
                var grp = ManagerContext.Current.Group2;
                var grid = uxBravoGrid;
                break;
            case "charlie":
                var grp = ManagerContext.Current.Group3;
                var grid = uxCharlieGrid;
                break;
            // Add more cases if necessary
            default:
                throw new ArgumentException("option", "Non-allowed value");
        }
    
        VList<T> groupList = FetchInformation(grp);
        if (sessionContent != null)
        {
            List<T> tempList = (List<T>)sessionContent;
            groupList.AddRange(tempList);
        }
    
        grid.DataSource = List("alpha";
        grid.DataBind();
    }
    

    引发异常的另一种方法是将选项字符串重新键入枚举中,只使用您允许的值。这样您就知道,如果您得到一个正确的枚举作为输入参数,那么您的选项将被处理。

        7
  •  0
  •   Pavel Radzivilovsky    15 年前

    有两个功能, GetGroup() 归还东西,比如 ManagerContext.Current.Group4 和getGroupName(),返回类似 "deltaGroup" .然后,所有代码都消失了。

        8
  •  0
  •   Ta01    15 年前
        private void LoadGroup(GridView gv, string groupName, ManagerContext m)
    {
        VList<T> list = FetchInformation(m); //not sure if ManagerContext will get what you need
        if (Session[groupName] != null)
        {
           list.AddRange(List<T>Session[groupName]);
           gv.DataSource = list;
           gv.DataBind();
        }   
    
    }