花了一天时间,边看这个Money例子,边把这个java写的Money示例改成了Ruby,只是代码上加了注释,可以按书上的介绍来看。 总结一下:TDD方面,感觉确实是很好的开发方法。这种开发方法应该一直贯穿下去。 Ruby方面,途中对Ruby的多态(duck type)有了更深的了解。但是也碰到一些问题,没有列出来。解决了再说。 测试代码: test/test_dollar.rb
$: .unshift File.join(File.dirname(__FILE__),"..","lib") require 'test/unit' require 'dollar'
class TestDollar < Test::Unit::TestCase def testEquality assert(Dollar.new(5) == (Dollar.new(5))) assert_equal(false,Dollar.new(5) == (Dollar.new(6))) end
def testEquality assert(Dollar.new(5) == (Dollar.new(5))) assert_equal(false,Dollar.new(5) == (Dollar.new(6))) assert(Franc.new(5) == (Franc.new(5))) assert_equal(false,Franc.new(5) == (Franc.new(6))) assert_equal(false,Franc.new(5) == (Dollar.new(5))) end
def testEquality assert(Money.dollar(5) == (Money.dollar(5))) assert_equal(false,Money.dollar(5) == (Money.dollar(6))) assert(Money.franc(5) == (Money.franc(5))) assert_equal(false,Money.franc(5) == (Money.franc(6))) assert_equal(false,Money.franc(5) == (Money.dollar(5))) end
def testCurrency assert_equal("USD",Money.dollar(1).currency) assert_equal("CHF",Money.franc(1).currency) end
def testSimpleAddition five = Money.dollar(5) sum = five.plus(five) bank = Bank.new reduced = bank.reduce(sum,"USD") assert_equal(Money.dollar(10),reduced) end
def testPlusRetrunSum five = Money.dollar(5) result = five.plus(five) sum = result assert_equal(five,sum.augend) assert_equal(five,sum.addend) end
def testReduceSum sum = Sum.new(Money.dollar(3),Money.dollar(4)) bank = Bank.new result = bank.reduce(sum,"USD") assert_equal(Money.dollar(7),result) end def testReduceMoney bank = Bank.new result = bank.reduce(Money.dollar(1),"USD") assert_equal(Money.dollar(1),result) end
def testHashEquals hash = Hash["from,to" => 1] assert_equal(1,hash["from,to"]) end
def testReduceMoneyDifferentCurrency bank = Bank.new bank.addRate("CHF","USD",2) result = bank.reduce(Money.franc(2),"USD") assert_equal(Money.dollar(1),result) end
def testIdentityRate bank = Bank.new bank.addRate("CHF","USD",2) assert_equal(1,Bank.new.rate("USD","USD")) assert_equal(2,Bank.new.rate("CHF","USD")) end
def testMixedAddition fiveBucks = Money.dollar(5) tenFrancs = Money.franc(10) bank = Bank.new bank.addRate("CHF","USD",2) result = bank.reduce(fiveBucks.plus(tenFrancs),"USD") assert_equal(Money.dollar(10),result) end =begin def testMultiplication five = Dollar.new(5) five.times(2) assert_equal(10,five.amount) end
def testMultiplication five = Dollar.new(5) product = five.times(2) assert_equal(10,product.amount) product = five.times(3) assert_equal(15,product.amount) end =end
=begin def testMultiplication five = Dollar.new(5) assert_equal(Dollar.new(10),five.times(2)) assert_equal(Dollar.new(15),five.times(3)) end def testFrancMultiplication five = Franc.new(5) assert_equal(Franc.new(10),five.times(2)) assert_equal(Franc.new(15),five.times(3)) end =end
=begin def testMultiplication five = Money.dollar(5) assert_equal(Dollar.new(10,"USD"),five.times(2)) assert_equal(Dollar.new(15,"USD"),five.times(3)) end
def testFrancMultiplication five = Money.franc(5) assert_equal(Franc.new(10,"CHF"),five.times(2)) assert_equal(Franc.new(15,"CHF"),five.times(3)) end =end
=begin def testDifferentClassEquality assert(Money.new(10,"CHF")==(Franc.new(10,"CHF"))) end =end end
lib/dollar.rb
CODE:
class Money def self.dollar(amount) @amount = amount return Money.new(@amount,"USD") end
def self.franc(amount) @amount = amount return Money.new(@amount,"CHF") end
attr_reader :amount,:currency
def initialize(amount=nil,currency=nil) @amount = amount @currency = currency end def currency return @currency end
def times(multiplier) return Money.new(@amount * multiplier,currency) end
def plus(addend) return Sum.new(self,addend) end
def reduce(bank,to) @rate = bank.rate(currency,to) return Money.new(@amount/@rate,to) end
def ==(obj) money = obj return @amount.eql?(money.amount) && (self.currency).eql?(money.currency) end end
class Bank attr_reader :rates,:rate @@rates = Hash.new def addRate(from,to,rate) @@rates["#{from},#{to}"]=rate end
def reduce(source,to) return source.reduce(self,to) end
def rate(from,to) return 1 if from.eql?(to) @rate = @@rates["#{from},#{to}"] return @rate end end
class Sum attr_reader :augend,:addend,:amount def reduce(bank,to) @amount = augend.reduce(bank,to).amount + addend.reduce(bank,to).amount return Money.new(amount,to) end def initialize(augend,addend) @augend = augend @addend = addend end end
=begin def initialize(amount=nil,currency=nil) super(amount,currency) end =end
=begin def times(multiplier) @amount *= multiplier end =end
=begin def times(multiplier) return Money.new(@amount * multiplier,currency) end =end
=begin def ==(obj) dollar = obj @amount.eql?(dollar.amount) end =end
=begin attr_reader :amount
def initialize(amount=nil,currency=nil) super(amount,currency) end =end
=begin def times(multiplier) return Money.new(@amount * multiplier,currency) end =end
本文出自 “{ :Alex Space => " Ruby Notes " }” 博客,请务必保留此出处http://blackanger.blog.51cto.com/140924/44838 本文出自 51CTO.COM技术博客 |