我写了这组代码并觉得它很差 质量。如您所见,在四个案例陈述中的每一个 我最终重复了很多相同的代码,除了 每种情况都有一些变化。不同的项目;会话名称,网格名称 和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;
}
}
答案 0 :(得分:23)
您应该能够将案例的各个部分提取到参数化的辅助函数中:
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;
}
}
这是一个选项,还有进一步的重构,我敢肯定。
对于更深层次的重构,我会使用一组选项对象,可能是委托或类似的来查看表驱动。这种方式的工作方式是该选项将成为一个对象而不是一个字符串,该选项将具有配置它的属性和调用适当委托的方法。它实际上取决于你想要维护的抽象级别。有时,从常规控件继承并在子类中提供配置信息是有好处的,这样他们就知道如何加载自己。
这里没有足够的空间来真正进入重构的深度。
答案 1 :(得分: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
。更重要的是,如果任何查找逻辑需要在任何地方重用,我们就不会重复自己。我们非常不受变化的影响,在这样的事实上我们永远不会重复自己。
答案 2 :(得分:9)
请记住,这只是对您所展示内容的重构。根据您展示的内容,您可能需要考虑对整个方法进行更深入的重构。然而,这可能是不可行的。
所以:
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();
}
答案 3 :(得分:2)
类似的东西应该有效:
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();
}
答案 4 :(得分:2)
这里只是为了好玩(这意味着它不太可能是一个好主意而且完全未经测试):
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();
}
}
如果我想能够动态地改变(即在运行时)选项匹配集,我只会做这样的事情,我希望执行的代码(加载算法)完全开放。
答案 5 :(得分:1)
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();
}
抛出异常的另一种方法是将选项字符串重新键入Enum,只包含您允许的值。这样你知道如果你得到一个正确的枚举作为输入参数,你的选项将被处理。
答案 6 :(得分:0)
创建两个函数GetGroup()
返回ManagerContext.Current.Group4
和GetGroupName()之类的函数,返回"deltaGroup"
之类的字符串。然后,所有代码都消失了。
答案 7 :(得分:0)
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();
}
}