使用多态替换条件:指在进行类型检查和执行某些类型操作时,最好将算法封装在类中,并且使用多态来对代码中的调用进行抽象
举例理解:看定义可能比较迷糊,其实说的简单一点,对于使用分支语句并且分支条件是和类型检查相关的程序段,如 if(type == typeof(TypeA)){...}else if(type == typeof(TypeB)){...},可以把{...}中的Code,尝试放到if的条件中去。然后通过检查Type就可以直接返回需要的东东了,这样做可以利用已有的继承层次进行计算,比较便于维护。如果还是觉得说的太抽象,可以看看下面的代码感觉一下。
项目实例:用WPF做一个网游的客户端Demo,里面需要对商品,邮件,物品栏做分页操作。于是手动写了几个分页的类。开始是把分页的计算方法都写在了事件里面的,每一个Button绑定一个事件,每次需要修改或者使用分页的时候,都要找到相关类进行修改,复制,各个方法的耦合程度大增,程序可读性,复用性和可维护性都不太好。虽然这个项目是很久之前做的了,但这里既然想起来了,觉得还是可以尝试用这种重构方法,效果如何大家自己看看吧。
先来看看原始的未经过重构的代码:
原始代码
//x:目标页数索引值 y:每页显示记录个数 这里不Care你是如何取到这几个值的和对这两个Int值合法性的验证
protected void btnFirstPage_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn != null)
{
repDataList.DataSource = Getdata(x,y); //Get Date from DB
}
}
protected void btnPrePage_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn != null)
{
repDataList.DataSource = Getdata(x, y); //Get Date from DB
}
}
protected void btnNextPage_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn != null)
{
repDataList.DataSource = Getdata(x, y); //Get Date from DB
}
}
protected void btnlastPage_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn != null)
{
repDataList.DataSource = Getdata(x, y); //Get Date from DB
}
}
private DataSet Getdata(int targetPageIndex, int numberPerPage) //Get Date from DB
{
throw new NotImplementedException(); //Here some code to retrive Data from DB
}
重构后
public abstract class Paging
{
public int TargetPageIndex { get; set; }
public int NumberPerPage { get; set; }
public abstract DataSet DataList { get; }
}
public class FirstPage : Paging
{
public FirstPage(int targetPageIndex, int numberPerPage)
{
TargetPageIndex = targetPageIndex;
NumberPerPage = numberPerPage;
}
public override DataSet DataList
{
get
{
return Getdata(TargetPageIndex, NumberPerPage);
}
}
}
public class PrePage : Paging
{
public PrePage(int targetPageIndex, int numberPerPage)
{
TargetPageIndex = targetPageIndex;
NumberPerPage = numberPerPage;
}
public override DataSet DataList
{
get
{
return Getdata(TargetPageIndex, NumberPerPage);
}
}
}
public class NextPage : Paging
{
public NextPage(int targetPageIndex, int numberPerPage)
{
TargetPageIndex = targetPageIndex;
NumberPerPage = numberPerPage;
}
public override DataSet DataList
{
get
{
return Getdata(TargetPageIndex, NumberPerPage);
}
}
}
public class LastPage : Paging
{
public LastPage(int targetPageIndex, int numberPerPage)
{
TargetPageIndex = targetPageIndex;
NumberPerPage = numberPerPage;
}
public override DataSet DataList
{
get
{
return Getdata(TargetPageIndex, NumberPerPage);
}
}
}
前台调用代码
protected void btnPaging_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn == null) return;
Paging page;
switch (btn.CommandArgument)
{
case "FirstPage":
page = new FirstPage(x,y);
repDataList.DataSource = page.DataList;
break;
case "PrePage":
page = new PrePage(x, y);
repDataList.DataSource = page.DataList;
break;
case "NextPage":
page = new NextPage(x, y);
repDataList.DataSource = page.DataList;
break;
case "LastPage":
page = new LastPage(x, y);
repDataList.DataSource = page.DataList;
break;
}
}