メソッドの分割ヒントをともさんが教えてくださった

感謝!
2
tomo🐧@learning @cocoatomo

@ihcomega よこなさんのプログラムにツッコミ入れる代わりに、自分のプログラムのリファクタの例を紹介してもいいかな?

2015-05-06 00:41:00
tomo🐧@learning @cocoatomo

@ihcomega はい! これ github.com/cocoatomo/reso… は Main クラスに全部書いてある「書き殴りバージョン」。これ github.com/cocoatomo/reso… が、処理を他のクラスに抜き出したバージョンです。

2015-05-06 00:49:44
tomo🐧@learning @cocoatomo

@ihcomega 実行時引数の処理が Main クラスに追加されてて分かりづらいけど、Main#execute メソッドの行数が減ってるのは分かると思います。その中からは、ReflectionUtils と Verifier のメソッドを呼んでるだけです。

2015-05-06 00:52:13
tomo🐧@learning @cocoatomo

@ihcomega 了解です。そしたら、とりあえず解説だけ書いておきますね。 Verifier インターフェースの実装クラスはこれ github.com/cocoatomo/reso… で、これも元の Main#execute よりはすっきりさせてます。

2015-05-06 01:01:52
tomo🐧@learning @cocoatomo

@ihcomega すっきりしてる理由は、元コードの大部分が単調なリフレクション処理だったので、それらの処理を static method しか持たない Util クラスに追い出したからです。 github.com/cocoatomo/reso…

2015-05-06 01:03:48
tomo🐧@learning @cocoatomo

@ihcomega 「Util クラスが発生すること自体どうなんだ!?」って議論はあるけど、Java の場合「単なる関数」にしたいものの置き場に困ることがあって、そういうとき自分は Util クラスを作っちゃいます。

2015-05-06 01:05:55
tomo🐧@learning @cocoatomo

@ihcomega 自分の基準では、こまごましたロジックの呼び出し側である Verifier#verify がすっきりすることが大事なので。 特に今回は「クラスオブジェクト取得」→「コンストラクタ取得」→「オブジェクト生成」という定型処理が多かったので、切り出すことにしました。

2015-05-06 01:08:46
tomo🐧@learning @cocoatomo

と、一通り偉そうなことを言ってみたり。

2015-05-06 01:11:13
きょん@アジャイルコーチ、システムアーキテクト @kyon_mm

@cocoatomo 僕がJavaに詳しくないのでよくわかっていないのですが、こういった場合に、デフォルト実装を使うというテクニックはアンチパターンだったりするのでしょうか?

2015-05-06 01:26:41
tomo🐧@learning @cocoatomo

@kyon_mm Util クラスに追い出した処理を Verifier インターフェースにデフォルト実装として付けることを考えている、という理解でよいでしょうか?

2015-05-06 01:32:02
きょん@アジャイルコーチ、システムアーキテクト @kyon_mm

@cocoatomo ReflectionUtilがinterfaceでよいのではないかなぁという感じです。(名前は変えるとして

2015-05-06 01:36:48
tomo🐧@learning @cocoatomo

@kyon_mm なるほど~。 ReflectionUtil に切り出した処理は、「外部に対して公開する自分ができること」ではなく「処理の見通しのために切り出したい処理 (= サブルーチン的な位置付け)」だったので、Util クラスに追い出しました。

2015-05-06 01:39:39
tomo🐧@learning @cocoatomo

@kyon_mm Verifier の実装クラスの private method でも良かったのですが、特に大きな違いは無さそうだったので今回は ReflectionUtils に切り出しました。

2015-05-06 01:41:19
tomo🐧@learning @cocoatomo

@kyon_mm Java の default implementation は Stream API を導入したときの「既存のインターフェースを修正したいが、既存の実装クラスは修正したくない」という要求の結果生まれたもの、と理解してるので、そのイメージとは違うかな、と思います。

2015-05-06 01:43:54
tomo🐧@learning @cocoatomo

@kyon_mm デフォルトメソッドの導入理由について、出展はこことかです。> blog.yujing.jp/entry/2013/06/… 導入理由と別の目的で使っても良いとは思うのですが、オブジェクトの内部状態を使わない単なる関数をインスタンスメソッドにするのは、ちょっと抵抗を感じました。

2015-05-06 01:51:14
きょん@アジャイルコーチ、システムアーキテクト @kyon_mm

@cocoatomo なるほどー。ありがとうございます!好みなんですが、自分的には、だいたいのメソッドはある状況におけるあるオブジェクトのアビリティとか福利厚生とかインフラみたいなイメージがあるので、ライフサイクルやスコープを明示的に見やすい実装のほうが好きってかんじですね。

2015-05-06 02:06:04
tomo🐧@learning @cocoatomo

@kyon_mm なるほど、今回の例で言えば「delegate 先を明示できる」ってメリットはありますね。それは考えたことがなかったので勉強になりました。

2015-05-06 02:22:16
tomo🐧@learning @cocoatomo

@ihcomega そうそう、解説とかコードとかで疑問とか質問とか大丈夫ですか? 何でも聞いてくださいな。

2015-05-06 21:37:02
tomo🐧@learning @cocoatomo

@ihcomega そこはやってみて、上手くいったり上手くいかなかったりを体験すると実感しますよ。 まずはあの judge メソッドをリファクタして (公開して) みてはどうでしょう?

2015-05-06 22:05:20