为什么我需要Sum和Bank类来计算Money?

时间:2012-05-01 09:35:20

标签: oop

我正在阅读Test Driven Development: By Example。我在第13章。第12章和第13章向Plus对象引入了Money操作。 Money对象可以加上其他Money个对象。

作者在解决方案中添加了两个类(BankSum)和一个接口(IExpression)。这是最终解决方案的类图。

Class diagram

Money存储金额和货币,例如10美元,5 BAHT,20瑞士法郎。 Plus方法返回Sum个对象。

public class Money : IExpression
{
    private const string USD = "USD";
    private const string CHF = "CHF";

    public int Amount { get; protected set; }

    public string Currency { get; private set; }

    public Money(int value, string currency)
    {
        this.Amount = value;
        this.Currency = currency;
    }

    public static Money Dollar(int amount)
    {
        return new Money(amount, USD);
    }

    public static Money Franc(int amount)
    {
        return new Money(amount, CHF);
    }

    public Money Times(int times)
    {
        return new Money(this.Amount * times, this.Currency);
    }

    public IExpression Plus(Money money)
    {
        return new Sum(this, money);
    }

    public Money Reduce(string to)
    {
        return this;
    }

    public override bool Equals(object obj)
    {
        var money = obj as Money;

        if (money == null)
        {
            throw new ArgumentNullException("obj");
        }

        return this.Amount == money.Amount &&
            this.Currency == money.Currency;
    }

    public override string ToString()
    {
        return string.Format("Amount: {0} {1}", this.Amount, this.Currency);
    }
}

Sum存储两个来自构造函数参数的Money对象。它有一个方法Reduce返回新的Money对象(通过添加两个对象的数量来创建新对象)

public class Sum : IExpression
{
    public Money Augend { get; set; }

    public Money Addend { get; set; }

    public Sum(Money augend, Money addend)
    {
        this.Augend = augend;
        this.Addend = addend;
    }

    public Money Reduce(string to)
    {
        var amount = this.Augend.Amount + this.Addend.Amount;

        return new Money(amount, to);
    }
}

Bank有一种方法 - Reduce。它只是调用传入IExpression参数的Reduce方法。

public class Bank
{
    public Money Reduce(IExpression source, string to)
    {
        return source.Reduce(to);
    }
}

IExpression是由MoneySum实施的界面。

public interface IExpression
{
    Money Reduce(string to);
}

这些是我的问题。

  1. Bank对此阶段的解决方案没有任何好处。我为什么需要它?
  2. 为什么我需要Sum,因为我可以在类Plus的{​​{1}}内创建并返回Money对象(就像作者对Money所做的那样)?
  3. 银行和总和的目的是什么? (现在,它对我没有任何意义)
  4. 我认为Times对我来说听起来很奇怪,因为方法名称。你认为这是一个好名字吗? (请建议)

1 个答案:

答案 0 :(得分:2)

继续阅读。肯特贝克是一个非常聪明的人。他或者有充分的理由为什么他以这种方式创造了这个例子,后来会很清楚,或者这是一个糟糕的解决方案。

如果map-reduce是最终目标,“减少”是一个非常好的名称。