- 追加された行はこの色です。
- 削除された行はこの色です。
* 言いたいこと、簡単に言うならば [#k9d15b45]
この、記事で言いたいことを先に言うならば、イソップ童話に例えると3匹の子豚の話にちかいかもしれない。「クラスを細かな分類でつくれば、バグがへって、後工程で楽なのに、理解してもらえる現場が少なすぎるよ」という嘆きである。
* 開発よりも、テストにコストがかかる [#e73bdfff]
自分はいろいろな開発プロジェクトに参画してきた経験からいえることだが、開発コストがかかるのは、テストとバグ対応だと言える。
バグというのは、勘違いからくる。
* よくある時間関連の間違いの例 [#s35e2121]
たとえば、時間関連の勘違いも多い。
よく、深夜1時のことを25時として扱うというのがあったりする。これと、世界標準時間でいうところの時間とごっちゃにして、あれ、●月×日のデータがない。みたいなことを言ってたりとかする。
期間についても、開始と、終了を一つの期間という入れ物に持っておらず、
終了が、開始の前になっても、なんのチェックもしてないということにきづかないとかいう現場が結構ある。
これらは、小さなデータの単位をStringやDate形などで持つのではなく、責任を持ったデータを管理する入れもの(クラス)を用意することで防げるのだ。
それがValueObjectの使い方なのだ。イソップ童話の3匹の子豚の話で例えるならば、ValueObjectとは、レンガに相当するものだと思う。
* 現場リーダのプライドが導入の遅れ [#qa5ae571]
しかし、それを現場のリーダにレクチャーなどしようものならば、レクチャーされた側は、プライドを気づつけらたようなそぶりを見せる。間違いないとおもう。だいたいのリーダは、口では、「意見があれば、歓迎します」とかいうが、自分が見た感じでは、それぞれ価値観があり、それに反対する勢力としてカウントされてしまう傾向が強い。世渡り的には、アドバイスなどはしないのが良いということになってします。
中には、ValueObjectについて、まちがった認識を逆にレクチャーしてきたケースもあった。
そういう時は、「あぁ、そうだったんですね。勉強になりました。」と答えるのが大人の返しかたなのである。
そういう現場は、謎のバグになやまされてかわいそうなことがおおいのだが、それは、リーダが自分のプライドを守ったつけを払っているのであるから、自業自得である。
* 最近の自分の体験 [#y79e2344]
そんな自分も最近Mysqlに格納したタイムスタンプと、格納したタイムスタンプを取得すると1秒ずれるという現象に見舞われた。
Mysql5.7以降は、データを取り込む再に値を四捨五入するようになったのだ。
ValueObjectでこの場合の時間の型のとらえ方を分けるのだ。なぜ、とらえ方を分けるのかというと、四捨五入が必要であるという知識と、実装を分離させるために分けるのだ。
例えばシステム時刻のことをRawDateとかいう名称のクラスに格納するとして、データベースからselect文で取得した時刻のことをStoredDateとかというクラスに分けて管理するのだ。
そして、RawDateからStoredDateに変換する場合は、MySQL5.7以降で行われる四捨五入の仕組みを入れるようにしておくのだ。
そうすれば、その四捨五入しなければならないという知識を、これらのクラスに閉じ込めておけるのだ。
クラスを利用する側は、そのMySQL5.7以降の知識を持たずに、安全にプログラムができるわけである。
* 結局はレンガで家をたてばコストが安い [#sef0190e]
プログラム量は増えるが、そこに使うコストがもったいない、とおもってはいけないのである、これは、バグを取り込まないようにするための必要経費なのだ。
疎通確認がおわり、単体テストがおわり、結合テストと、進めていくにしたがって、不具合を見つけるためのコストは増えていく、数行のコードを書く手間ぐらい、たいしたことはないのだ。
* まだ、わかってない人が多い [#g03f2326]
ところが、よのなかの、プロジェクトのリーダはそれがわかっていないのが、大多数だなぁと、いろいろなプロジェクトに参画してきておもうのであった。
** 数学的に説明を試みる [#ad12bf71]
人間には、ワーキングメモリーというものがあり、平均は7だそうだ。workmem = 7 とする。
MySQLのミリ秒四捨五入のような、しらないと、バグになるレベルの込み入った知識が1つあることを knowledge = 1 とする。
ソースコードに含まれる込み入った知識が必要な確率をpとする。
ソースコードの量をcodeAmmountとする
したがって以下の式になる。
knowledge = codeAmmount x p
人間が注意を払うには、ワーキングメモリーに知識が入っている。いいかえると、気をつけなければならないことの数には上限があることを以下の式で表すことにする。
** 不注意でバグを生み出しだす条件式 [#mf74c585]
knowledge > workmem = 7
*** ワーキングメモリーがすくないバカなひとほど、開発方法の間違いに早めに気が付く [#b11ac301]
workmenには、個人差があり、優秀な人ほど高くなる。
またコード量が増えまくてはじめて、「あっ、このやり方は限界だ。。。」と気が付くわけである。
バカほど、早めに気が付き、怪我が少ないので、優秀ということになるのである。
* バリューオブジェクト作るコストと、ややこしいバグを解消するコストとのトレードオフ [#l292ae43]
そこで、ValueObjectを作って、知らないとバグになる知識を、そのクラスの中に閉じ込めてしまうというのが良いというのは、自分の主張だが、数式で表してみたいと思う。
しらないとバグになるややこしい知識1個あたりのvalueオブジェクトを作るコストをcostValueobjectとすると、
valueObjectをつかうことで支払うコストは
knowledge x costValueobject である。
valueObjectを使わないことで支払うコストは、1知識あたりのバグ改修のコストをbugFixCostとすると
knowledge x bugFixCost である。
** costValueobject の見積り [#y3325c2d]
知識を得るためのコスト
クラスに作りこむためのコスト
このクラスを利用する側は、知識をもっていなくてもこのクラスを使ってさえいれば、
知識をもった状態と同等のことになる
** bugFixCost [#y5fe49cd]
知識を得るコストを修正箇所を別の担当者が行うたびに支払う
再テストのコスト
バグが起きるタイミングは、本番時など、後工程になりがち。後工程で見つかる不具合ほどコストがかかるのは、説明しないけど、そういうことだ。
大きなプロジェクトになれば、なるほど分業化されるので、問題の切り分け分析のコストがかかる。
他にも、そのうち、こういうコストがかかると、おもいつくと思う。
個人的にやばいと思うのは、本番時に、ややこしい間違えやすい知識を、初見の運用者がメンテナンスするようなシチュエーションだ。
信用を失うというのは、プライスレスなコストではないだろうか。。。