Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第09章 歩幅の調整 #13

Merged
merged 12 commits into from
Nov 6, 2017
Merged

第09章 歩幅の調整 #13

merged 12 commits into from
Nov 6, 2017

Conversation

at-grandpa
Copy link
Owner

@at-grandpa at-grandpa commented Nov 6, 2017

TODO

  • $5 + 10 CHF = $10(レートが2:1に場合)
  • $5 * 2 = $10
  • amountをprivateにする
  • Dollarの副作用どうする?
  • Moneyの丸め処理をどうする?
  • equals
  • hashCode
  • nullとの等価性比較
  • 他のオブジェクトとの等価性比較
  • 5CHF*2=10CHF
  • DollarとFrancの重複
  • equalsの一般化
  • timesの一般化
  • FrancとDollarを比較する
  • 通貨の概念
  • testFrancMultiplicationを削除する?

@at-grandpa
Copy link
Owner Author

サブクラスを消したい。通貨の概念を導入するのはどうだろう。

@at-grandpa
Copy link
Owner Author

これ、思いつく?どうやって思いつく?

@at-grandpa
Copy link
Owner Author

Flyweightパターンを用いて、必要十分な通貨オブジェクトを生成して管理したい。とはいえ、まだ文字列だけで十分だろう。

@at-grandpa
Copy link
Owner Author

at-grandpa commented Nov 6, 2017

こういう思考に至るのがなぜか。こういう思考に至るのはテスト駆動開発の恩恵ではないのか。別の恩恵があるのか。

@at-grandpa
Copy link
Owner Author

テストは通る。

 crystal spec' <

....

Finished in 1.7 milliseconds
4 examples, 0 failures, 0 errors, 0 pending

@at-grandpa
Copy link
Owner Author

徐々に2つのクラスの実装を近づけていきたい。各クラスの独自部分をどんどん外(Moneyクラス)においやっていく。

@at-grandpa
Copy link
Owner Author

テストは通る。テストがあると、こういった修正が安心してできる。

@at-grandpa
Copy link
Owner Author

テストは通る。

@at-grandpa
Copy link
Owner Author

さらに、コンストラクタの呼び出し側で@currencyを定義すれば、コンストラクタも共通化できる。

@at-grandpa
Copy link
Owner Author

コンパイルできない。

 crystal spec' <

Error in line 1: while requiring "./spec/money_spec.cr"

in spec/money_spec.cr:15: instantiating 'MoneyPackage::Money:Class#franc(Int32)'

      (MoneyPackage::Money.franc(5) == MoneyPackage::Money.franc(5)).should be_true
                           ^~~~~

in src/money_package/money.cr:18: wrong number of arguments for 'MoneyPackage::Franc.new' (given 1, expected 2)
Overloads are:
 - MoneyPackage::Franc.new(amount : Int32, currency : String)

      MoneyPackage::Franc.new(amount)
                          ^~~

@at-grandpa
Copy link
Owner Author

コンパイルが通り、テストも通る。

 crystal spec' <

....

Finished in 632 microseconds
4 examples, 0 failures, 0 errors, 0 pending

@at-grandpa
Copy link
Owner Author

で、ここで気づくのが、FrancのtimesメソッドがMoneyのfactoryメソッドではなく、直接自分のコンストラクタを呼んでいること。

この修正は割り込みだが、ちょっとした割り込みに限っては、修正してしまおう。

@at-grandpa
Copy link
Owner Author

テストは通る。ほんとテストあるおかげで、こういう修正が楽。

@at-grandpa
Copy link
Owner Author

小さいステップを踏んで、修正がらく。ちょっとイラッとするかもだけど、「小さくもできる」というのが大事。

@at-grandpa
Copy link
Owner Author

Dollarも一気にやってしまおう。

@at-grandpa
Copy link
Owner Author

一気に修正できた。

@at-grandpa
Copy link
Owner Author

今回のように、必要であれば歩幅を小さくし、行けるなら歩幅を大きくして良い。

@at-grandpa
Copy link
Owner Author

コンストラクタが一致したので、親クラスに持っていく。

@at-grandpa
Copy link
Owner Author

振り返り。

  • 大きめの設計変更にのめり込みそうだったので、その前に手前にある小さな変更に着手した
  • 差異を呼び出し側(FactoryMethod側)に移動することによって、2つのサブクラスを近づけていった
  • リファクタリングの途中で寄り道して、timesメソッドの中でFactoryMethodを使うように修正した
  • Francに行ったリファクタリングをDollarにも同様に、今度は大きな歩幅で一気に適用した
  • 完全に同じ内容になったコンストラクタを親クラスへ移動した

@at-grandpa
Copy link
Owner Author

どういう歩幅がいいかはどうやってわかるんだろうな。とりあえず整理がつかなかったら歩幅を小さくしようか、って話かな。

@at-grandpa
Copy link
Owner Author

at-grandpa commented Nov 6, 2017

TODO

  • $5 + 10 CHF = $10(レートが2:1に場合)
  • $5 * 2 = $10
  • amountをprivateにする
  • Dollarの副作用どうする?
  • Moneyの丸め処理をどうする?
  • equals
  • hashCode
  • nullとの等価性比較
  • 他のオブジェクトとの等価性比較
  • 5CHF*2=10CHF
  • DollarとFrancの重複
  • equalsの一般化
  • timesの一般化
  • FrancとDollarを比較する
  • 通貨の概念
  • testFrancMultiplicationを削除する?

@at-grandpa at-grandpa merged commit e16a4df into master Nov 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants