在開發時,為了快速或是避免麻煩,可能會用簡單的代號,例如 aa 這種名稱,來暫時做為變數的名稱。這無可厚非,但是...假若在完成該功能當下,沒有進行最基本的重構—改名。
也許三個月後,也許一年後的某一天,突然發現程式有需求變動,不管你是要修改自己開發的程式,還是要維護前人遺留下來的軟體。這時,你將程式專案開啟,花費了一番苦戰,好不容易找到要修改變動的程式區塊。
看著程式碼中,各種無意義的命名,苦苦的思考,為什麼當初會這樣寫?這個變數是什麼意義?邊改寫程式,邊幹譙當初寫下這段程式的人。
上面的經驗,想必有許多人都有過這種經驗。
下面,我將以前接手,研究所學弟的原始碼分享給大家看,後面幾篇文章,都會做為範例操作。
老實說,當時,第一眼看到下面的程式碼時,只有傻眼二個字
public int[,] ga(int[,,] im_1, int[,,] im2_1)
{
int h = im_1.GetLength(1); int w = im_1.GetLength(0);
//Bitmap bimage = new Bitmap(w*3, h*3);
int[,] k = new int[2, ggg];
int[] k1 = new int[ggg];
int[,] k2 = new int[3, ggg];
for (int ie = 0; ie < ggg; ie++)
{
k1[ie] = 1000;
}
Random innerRnd = new Random(Guid.NewGuid().GetHashCode());
Random innerRnd1 = new Random(Guid.NewGuid().GetHashCode());
for (int j = 0; j < ggg; j++)
{
k[0, j] = (innerRnd.Next(255)) - Val01;
k[1, j] = (innerRnd1.Next(255)) - Val02;
}
progressBar1.Maximum = 26;
int iu, ju, temp, temp1, temp2;
int score = 0;
while (score <= 25)
{
score = score + 1;
progressBar1.Value = score;
for (int score1 = 0; score1 <= 15; score1++)
{
int[,] k111 = k;
Random innerRnd8 = new Random(Guid.NewGuid().GetHashCode());
int a1 = innerRnd8.Next(ggg);
Random innerRnd9 = new Random(Guid.NewGuid().GetHashCode());
int a2 = innerRnd9.Next(ggg);
double rrr = _RRR(k[0, a1], k[1, a1], im_1, im2_1);
double rrr_1 = _RRR(k[0, a2], k[1, a2], im_1, im2_1);
if (rrr > rrr_1)
{
k[0, a1] = k[0, a2];
k[1, a1] = k[1, a2];
k1[a2] = Convert.ToInt32(rrr_1);
k1[a1] = Convert.ToInt32(rrr_1);
}
else if (rrr <= rrr_1)
{
k[0, a2] = k[0, a1];
k[1, a2] = k[1, a1];
k1[a1] = Convert.ToInt32(rrr);
k1[a2] = Convert.ToInt32(rrr);
}
Random innerRnd33 = new Random(Guid.NewGuid().GetHashCode());
int Crossover = innerRnd33.Next(10);
if (Crossover <= 7)
{
Random innerRnd2 = new Random(Guid.NewGuid().GetHashCode());
int a4 = innerRnd2.Next(ggg);
Random innerRnd3 = new Random(Guid.NewGuid().GetHashCode());
int a5 = innerRnd3.Next(ggg);
int k_33 = (k[0, a4]) + Val01;
int k_44 = (k[1, a4]) + Val02;
int k_55 = (k[0, a5]) + Val01;
int k_66 = (k[1, a5]) + Val02;
string k_33_old = Convert.ToString(k_33, 2);
string k_33_old1 = k_33_old.PadLeft(8, '0');
string k_55_old = Convert.ToString(k_55, 2);
string k_55_old1 = k_55_old.PadLeft(8, '0');
Random innerRnd30 = new Random(Guid.NewGuid().GetHashCode());
int a44 = innerRnd30.Next(8);
中略
for (iu = 0; iu < ggg; iu++)
{
for (ju = 1; ju < ggg; ju++)
{
if (k2[2, ju - 1] > k2[2, ju])
{
temp = k2[2, ju - 1];
temp1 = k2[0, ju - 1];
temp2 = k2[1, ju - 1];
k2[2, ju - 1] = k2[2, ju];
k2[0, ju - 1] = k2[0, ju];
k2[1, ju - 1] = k2[1, ju];
k2[2, ju] = temp;
k2[0, ju] = temp1;
k2[1, ju] = temp2;
}
}
}
int ddd1 = 0;
for (iu = 0; iu < gggzz; iu++)
{
ddd1 = ddd1 + (k2[2, iu]);
}
int ddd_1 = Convert.ToInt16(ddd1 / gggzz);
dddd_2 = 0;
for (iu = 0; iu < gggzz; iu++)
{
dddd_2 = dddd_2 + Math.Abs(ddd_1 - k2[2, iu]);
}
}
if (Math.Sqrt(dddd_2) <= 0.005 && k2[2, 0] <= 5)
{
score = 26;
progressBar1.Value = 26;
}
}
int gg = 0;
int gg1 = 0;
int[,] good = new int[2, ggg];
for (int j111 = 0; j111 < gggzz; j111++)
{
gg = gg + k2[0, j111];
gg1 = gg1 + k2[1, j111];
}
int x_new = Convert.ToInt16(gg / gggzz);
int y_new = Convert.ToInt16(gg1 / gggzz);
int[,] x_y = new int[2, 1];
x_y[0, 0] = x_new;
x_y[1, 0] = y_new;
return x_y;
}
上面的程式碼,簡單來說,是使用基因演算法(Genetic Algorithm, GA),找出兩張影像的最佳疉合點。
若是要對這段程式進行維護或修改,其實花費額外的時間,在了解程式碼本身所代表的意義。
不易閱讀的因素,大致上包含
為了持續精進程式可讀性,我訂下了一些遊戲規則(原則)
- 請使用有意義的命名
- 在上版或釋出前,請刪除無意義或無用的註解。