iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
0
Software Development

在Kata中尋找Clean Code是否搞錯了什麼系列 第 22

Day 22 覆寫operator

昨天講到可以透過覆寫operator來讓物件操作更符合我們原先的操作邏輯。今天就來多聊一些其他不同的operator。我們常見的operator像是有"+"和"=="...等,還記得在串聯字串的的時候,我們會透過加號來做這件事。

string helloWorld = "hello" + "world" + "!"

假設我們有一個Money類別,用來記錄使用者錢與貨幣,類別裡面有加減運算。

public class Money
{
    private static readonly Dictionary<Currency, decimal> ExchangeRate = new Dictionary<Currency, decimal>()
    {
        {Currency.USD, 30},
        {Currency.TWD, 1},
        {Currency.JPY, 0.3m}
    };
    
    public decimal Value { get; set; }

    public Currency Currency { get; set; }

    public Money Minus(Money money)
    {
        return new Money()
        {
            Value = (GetTwdValue() - money.GetTwdValue()) / ExchangeRate[Currency],
            Currency = Currency,
        };
    }

    public Money Add(Money money)
    {
        return new Money()
        {
            Value = (GetTwdValue() + money.GetTwdValue()) / ExchangeRate[Currency],
            Currency = Currency,
        };
    }

    private decimal GetTwdValue()
    {
        return Value * ExchangeRate[Currency];
    }
}

使用端則是使用Add與Minus來計算金錢變化

var money1 = new Money()
{
    Value = 200,
    Currency = Currency.TWD
}

var money2 = new Money()
{
    Value = 100,
    Currency = Currency.TWD
}

var moneySum = money1.Add(money2); // 300 TWD
var moneyDiff = money1.Minus(money2); // 100 TWD

方法名稱本身還算清楚,我們在使用端可以透過方法名稱了解他的目的。但是我們還是能透過覆寫operator "+"和"-",讓使用端更加簡化。

public class Money
{
    ...
    
    public decimal Value { get; set; }

    public Currency Currency { get; set; }

    ...

		public static Money operator -(Money money1, Money money2)
    {
        return new Money()
        {
            Value = (money1.GetTwdValue() - money2.GetTwdValue()) / ExchangeRate[money1.Currency],
            Currency = money1.Currency,
        };
    }

    public static Money operator +(Money money1, Money money2)
    {
        return new Money()
        {
            Value = (money1.GetTwdValue() + money2.GetTwdValue()) / ExchangeRate[money1.Currency],
            Currency = money1.Currency,
        };
    }

    ...
}

把Add和Minus方法調整成覆寫operator之後,使用端就能更清楚。

var moneySum = money1 + money2; // 300 TWD
var moneyDiff = money1 - money2; // 100 TWD

除了"+"和"-"之外,我還也能覆寫"=="和"!="來幫助我們比較兩個不同的物件

public static bool operator ==(Money money1, Money money2)
{
    return money1.Value == money2.Value && money1.Currency == money2.Currency;
}

public static bool operator !=(Money money1, Money money2)
{
    return !(money1 == money2);
}

除了"+"、"-"、"=="和"!=",還有許多operator可提供我們覆寫,在Document中有列出哪些operator可以被覆寫。

我們在日常寫代碼的過程中常常使用到這些operator,卻很少注意到這些operator是怎麼被實作,在自己寫的代碼中也鮮少使用。透過覆寫operator,讓一些通用的操作,像是比較異同或數值加減運算,可以用這些operator表示,我們就可以更好的呈現代碼的意圖。


上一篇
Day 21 集合容易散發的壞味道
下一篇
Day 23 方法名稱與參數
系列文
在Kata中尋找Clean Code是否搞錯了什麼30

尚未有邦友留言

立即登入留言