iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
0

在昨天的例子中,我們把x, y抽到Point類別,讓這段Kata代碼擺脫資料泥團的壞味道。雖然解決了資料泥團的問題,但是這段代碼還是有其他的壞味道存在。

public class Dartboard
{
    private readonly Dictionary<DistanceRange, string> _magniDistanceDict = ...

    private readonly Dictionary<AngleRange, int> _scoreAngleDict = ...

    private readonly List<string> _fixResultMagni = ...

    public string GetScore(Point point)
    {
        var mangi = GetMagniByPosition(point);
        var score = _fixResultMagni.Contains(mangi) ? "" : GetScoreByPosition(point);
        return mangi + score;
    }

    private string GetMagniByPosition(Point point)
    {
        var distance = point.GetDistance();
        return _magniDistanceDict.FirstOrDefault(entry => entry.Key.IsThisDistance(distance)).Value;
    }

    private string GetScoreByPosition(Point point)
    {
        var angle = point.GetAngle();
        return Convert.ToString(_scoreAngleDict.First(entry => entry.Key.IsThisRange(angle)).Value);
    }

    private double GetDistance(Point point)
    {
        return Math.Sqrt(point.X * point.X + point.Y * point.Y);
    }
    
    private double GetAngle(Point point)
    {
        var result = Math.Atan2(point.Y, point.X) * 180.0 / Math.PI;
        return result > 0 ? result : 360 + result;
    }
}

昨天的代碼中有兩個方法GetDistance和GetAngle被省略沒有列出來,分別是根據點的位置計算距離與角度。如果仔細觀察這兩個方法可以發現,這兩個方法只都使用到了Point類別,不像其他方法使用到了Dartboard的欄位。

在上面的例子中Dartboard直接使Point的屬性去計算距離和角度,這是另外一個壞味道:Feature Envy。因為Dartboard需要使用Point的X, Y去計算距離和角度,導致Dartboard相依於Point的X, Y,也讓Point需要暴露X, Y給Dartboard使用。

我們可以把Point移進GetDistance和GetPoint移進Point類別中,讓Point透過自己的方法去計算距離角度。這樣也能把x, y更好的封裝在Point類別裡面,隱藏實作細節。

public class Point
{
    private readonly double _x;

    private readonly double _y;

    ...

    public double GetDistance()
    {
        return Math.Sqrt(_x * _x + _y * _y);
    }

    public double GetAngle()
    {
        var result = Math.Atan2(_y, _x) * 180.0 / Math.PI;
        return result > 0 ? result : 360 + result;
    }
}

很多時候在比較不熟悉Domain的情況下,我們很難在一開始設計的時候就物件應該如何設計,應該要有什麼類別,或者是什麼方法應該在什麼類別裡面。但是只要透過不斷的察覺壞味道,從代碼的相依來看出類別之間的關係並且即時重構,就能讓我們的代碼越來越乾淨。


上一篇
Day 19 它們總是一起出現
下一篇
Day 21 集合容易散發的壞味道
系列文
在Kata中尋找Clean Code是否搞錯了什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言