代碼重構之代碼的壞味道

       自己寫段有壞味道的代碼無所謂,痛苦的是看那些充斥着壞味道的代碼。每當看到這樣的代碼,一股重構的衝動;當重構也很痛苦時,丫的不管了,重寫。

你的代碼有壞味道嗎?聞聞就知道了。

一:Duplicated Code(重複代碼)

       如果你在一個以上的地方看到相同的代碼,恭喜你,Duplicated Code來了。這些代碼很有可能是Control+C和Control+V搞出來的,有人認爲這樣比寫個方法快多了。

       看下面兩個方法:

public function changeAction(roleId : int, resArray : Array, actionId : int) : void
{
    if (_roleDictionary[roleId] != null)
    {
        // 給部位id賦值
        var body : int = resArray[0];
        var clothes : int = resArray[1];
        var hair : int = resArray[2];
        var weapon : int = resArray[3];
        if (int(body) < -2 || int(clothes) < -2 || int(hair) < -2 || int(weapon) < -2)
        {
            return;
        }
        var bodyArray : Array = getAction(body,actionId);
        var clothesArray : Array = getAction(clothes,actionId);
        var hairArray : Array =getAction(hair,actionId);
        var weaponArray : Array =getAction(weapon,actionId);
        var myMovieClip : MovieClipStateMachine = _roleDictionary[roleId];
        myMovieClip.changeAction(actionId, [bodyArray, clothesArray, hairArray, weaponArray]);
    }
}

public function changeWeapon(roleId : int, resArray : Array, actionId : int) : void
{
    if (_roleDictionary[roleId] != null)
    {
        // 給部位id賦值
        var body : int = resArray[0];
        var clothes : int = resArray[1];
        var hair : int = resArray[2];
        var weapon : int = resArray[3];
        if (int(body) < -2 || int(clothes) < -2 || int(hair) < -2 || int(weapon) < -2)
        {
            return;
        }
        var bodyArray : Array = getAction(body,actionId);
        var clothesArray : Array = getAction(clothes,actionId);
        var hairArray : Array =getAction(hair,actionId);
        var weaponArray : Array =getAction(weapon,actionId);
        var myMovieClip : MovieClipStateMachine = _roleDictionary[roleId];
        myMovieClip.changeAll([int(body), int(clothes), int(hair), int(weapon)], 
            [bodyArray, clothesArray, hairArray, weaponArray]);
    }
}

          一個很簡單的解決方法是採用Extract Mathod方法提煉出重複代碼,調用之:

public function changeAction(roleId : int, resArray : Array, actionId : int) : void
{
	if (_roleDictionary[roleId] != null)
	{
		var myMovieClip : MovieClipStateMachine = _roleDictionary[roleId];
		myMovieClip.changeAction(actionId, getRoleResList(actionId,resArray));
	}
}

public function changeWeapon(roleId : int, resArray : Array, actionId : int) : void
{
	if (_roleDictionary[roleId] != null)
	{
		var myMovieClip : MovieClipStateMachine = _roleDictionary[roleId];
		myMovieClip.changeAll([int(resArray[0]), int(resArray[1]), int(resArray[2]), int(resArray[3])],
                     getRoleResList(actionId,resArray));
	}
}

private function getRoleResList(actionId:int,resArray:Array):Array{
	if(resArray==null || resArray.length!=4) return null;
	var body:int=int(resArray[0]);
	var clothes:int=int(resArray[1]);
	var hair:int=int(resArray[2]);
	var weapon:int=int(resArray[3]);
	if(body<-2 || clothes<-2 || weapon<-2 || weapon<-2) return;
	var data:Array=new Array();
	data[0]=getAction(body,actionId);
	data[1]=getAction(clothes,actionId);
	data[2]=getAction(hair,actionId);
	data[3]=getAction(weapon,actionId);
	return data;
}
      

       代碼重複有下面幾種情況和解決方案:

  • 多個函數中含有相同的代碼:Extract Mathod提煉重複代碼
  • 多個互爲兄弟類中含有相同的方法:先使用Extract Mathod方法, 然後用Pull up Method將提煉的代碼放到超類中
  • 多個無關類中含有相同代碼:一是放入某個類中,其他類去調用,二是用Extract Class方法提煉出獨立類,所有類調用該獨立類的接口,等等
  • 多個類中的代碼只是相似:用Extract Mathod方法將相似和差異分離,再用Form Template Method獲得一個Template Method
  • 多個函數用不同的算法做相同的事情:用Substitute Method選出較好的一個,把其它的幹掉啊,你以爲後宮呢

二:Long Method(過長函數)

         函數過長,如果加上代碼寫的不清晰,那就和看天書沒什麼差別了。你不得不加註釋以告知你的意圖,如果到了要用註釋來告知你的實現手法的話,這個函數真的很有必要分解了。記住,用代碼來解釋代碼。代碼只是用來簡單說明函數的用途和用法,而不是描述如何實現某個功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章