在牛人的博客中提到了..如果你的代码可以copy-past的时候,那么久证明你的代码出现了重复.而这种重复仅仅是虚假的代码行的增加而不是像其他的代码复用那样降级成本.
copy-pase代码意味着你违法了不重复自己的原则(DRY原则).
而一旦你在你的方法中或者方法直接开始了copy-past,那么久意味着你的代码需要Extract Method. 恩在文章(1)(2)中介绍了部分的重构方法.
在提取放置之后呢,还可以根据情况利用Move Method重构手法,将其搬移到一个类中,然后在原来的调用处转为对该类方法的调用。或者利用Replace Method with Method Object,将这些职责封装为专有的类。关于Move Method重构手法 和 Replace Method with Method Object 会在 文章<从文章"避免复制与粘贴"到文章"Move Method"的反思>系列中自我理解.这里就先放一放.
这里呢牛人举了一个自己的实际的工作的例子来说明如何避免的copy-past.我讲理解性的描述一下他的过程
首先他有一个a 类 ,其中有个私有方法是设置参数变量unit的单位是rmb还是dollar. 然后这个方法被他的另一个函数creatUnit调用
class a
{
private void setUnitType( Unit unit)
{
string type = "rmb";
String moneyType = resource.getMoneyType();
if (moneyType.toLowerCase().equals(type)){
unit.setReportType(Unit.china_money);
} else {
unit.setReportType(Unit.usa_money);
}
}
protected void creatUnit()
{
Unit unit;
unit.setCreditAmount = 100;
setUnitType( unit);
}
}
但是呢,悲剧的是他发现在b类中的某个函数也需要给Unit对象设置单位
class b
{
protected void changeUnit()
{
Unit unit;
//需要调用一个给Unit设置单位的函数
}
}
我发现在b类中同样需要设置unit的类型。然而,setUnitType()方法却被定义为a的私有方法,无法被b对象调用。最简单的做法是采用复制的方式,将这段代码复制到b中。好了,如果此时我们不能忍住copy-paste的简便所带来的诱惑,或许就会陷入重复的泥沼了。Copy的动作绝对应该鸣起刺耳的警声。我们需要对这一做法保持足够的警惕。
然后呢..大牛就干了之下的事情
在他看了呢setUnitType干的事情无法就是给UnitType的对象赋值单位..因为他的UnitType中已经有了set和get方法,他只要再次在unitType中写一个私有方法让get函数返回就可以了. {Move method 重构}
class Unit
{
public: setUnitType()
{
}
public: getUnitType()
{
return getUnitTypeByInfo();
}
private void getUnitTypeByInfo( Unit unit) //由于从a挪到了unit类这里需要Rename Method以及Extract Method等重构手法。
{
string type = "rmb";
String moneyType = resource.getMoneyType();
if (moneyType.toLowerCase().equals(type)){
self.type = Unit.china_money
} else {
self.type = Unit.usa_money
}
}
}
这样的话类a改为
class a
{
protected void creatUnit()
{
Unit unit;
unit.setCreditAmount = 100;
unit.setUnitType( unit.getUnitType() )
}
}
class b
{
protected void changeUnit()
{
Unit unit;
unit.setUnitType( unit.getUnitType() )
}
}
由于大牛的例子比较繁琐,所以就用这个简化的有错误的例子来说明原理,心领意会即可..
简单的说就是a类的一个函数功能 和 b类的一个函数功能是一样的..那么你可以把a类的函数功能拷贝到b类中,但是这样的话就是copy-past.很不好.但是他发现a类的这个函数功能和b类的这个函数功能都是对c类对象的操作.所有他就想法设法的把这部分操作挪到了c类自身中进行..这样的话在a类和b类中仅仅调用c类的方法即可.而不用有两份相同的代码了.