読者です 読者をやめる 読者になる 読者になる

MyEnigma

とあるエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

11. ドメインの言葉を使ったコード Dan North:『プログラマが知るべき97のこと』

以下の記事は,オライリージャパン社から出版された

プログラマが知るべき97のこと』

の中から1つのエッセイを選び,

そのエッセイを,クリエイティブコモンズ3.0の条件の元で転載したものです.

Creative Commons ― 表示 3.0 アメリカ合衆国 ― CC BY 3.0

もし,他のエッセイを読みたい場合には,

記事末のリンクを辿るか,

以下のリンク先のTwitterアカウントのつぶやきからお探し下さい.

Twitter Account: 97 Things Bot


11. ドメインの言葉を使ったコード ダン・ノース (Dan North):『プログラマが知るべき97のこと』

例えば,コードベースの中に,

次のようなコードが見つかったとします.

if(portfolioIdsByTraderId.get(trader.getId()).containsKey(portfolio.getId())){...}

このコードを見ても,何をやりたいコードなのかを

すぐには理解できずに思わず頭を掻きむしる・・・.

そんな人が多いのではないでしょうか?

どうもtraderオブジェクトからIDを取得して,

そのIDを使って「MapのMap」からMapを取得しているようではあります.

その「内側」のMapにportfolioオブジェクトのIDが

存在しているのかを確認しているようです.

portfolioIdsByTraderIdの宣言部分が次のようになっているのを見れば,

もっと頭を掻き毟りたくなるでしょう.

Map<int, Map<int, int>>portfolioIdsByTraderId;

だんだんわかってきました.

どうやら,あるトレーダが,

あるポートフォリオにアクセスできるか否かを

確認するためのコードのようです.

そして,これから同じコードを

(もっと言えば,ほとんど同じで実は細部が微妙に違っているコードを)

あちこちで見ることになるでしょう.

例えば,特定のポートフォリオにアクセスできるかだけを確認するなどです.



では,次のような書き方ならどうでしょうか?

if(trader.canView(portfolio)){...}

これなら頭を掻きむしることはありません.

「あるトレーダがあるポートフォリオにアクセスできるか否かを確かめる」

コードであろう,ということはすぐにわかるし,

その確認を具体的にどのようにするのかを知る必要はないからです.

おそらく中では同じように「MapのMap」を扱うなどの

面倒な処理が行われるのでしょう.

そんなことは,こちらで考えなくても,

Traderオブジェクト任せにしておけば済むわけです.



ここで問題なのは,

読者が実際に扱うコードが,

上の2つのうちどちらに近いのかということです.



かつてプログラミングに使えるデータ構造は,

非常に基本的なものに限られていました.

ビットかバイトかキャラクタです.

(正確にはすべてがバイトだったのですが,

表面上,文字や記号として扱うこともできました.)

数値の扱いはやや面倒でした.

コンピュータでは2進数が基礎となり,

10進数をそのまま扱うことができないからです.

このため,何種類かの浮動小数点型を使い分けるということをしてきました.

その後,配列や文字列(文字列も正確には配列の一種),

さらにスタックやキュー,ハッシュ,リンクリスト,スキップリスト,

その他にも現実世界には存在しないような面白いデータ構造が加わりました.

コンピュータサイエンスの世界は,

現実世界を制限あるデータ構造にどう対応付け,表現するのか?

という問題にずっと取り組んできました.

真のベテラン技術者なら,

取り組みの歴史がどのようなものだったのかを語れるでしょう.



そして現在,私たちは「ユーザ定義型」というものを使うことができます.

「そんなの知っているよ」と思うでしょうが,

これが非常に大事なのです.

ユーザ定義型が使えるか否かで状況はかなり変わるからです.

ある分野(ドメイン)に「トレーダ」や「ポートフォリオ」といった

概念が存在しているとすれば,それを例えば,

Trader, Portfolioという名前の型を定義してモデリングすることができます.

更に重要なのは,

こうした概念間の「関係」も,

ドメインの言葉を使ってモデリングできるということです.



仮にドメインの言葉を使わずにコードが書かれていたとすると,

読む側は

「一見してもわからないが,

 このint型のデータは,トレーダーのIDを表し,

 でもあのint型のデータは実はポートフォリオのIDを表す」

といった「暗黙の了解」が必要になってしまいます.

混ぜるな危険!,

両者を混同してしまわないように細心の注意が必要だということです.

また,何らかのビジネス上の決まり

(同じポートフォリオでも

参照可能なトレーダと

法的に参照を許されないトレーダがいる,など)

を,ユーザ定義型を使わずにアルゴリズムで,

例えば,キーのMapに関連が存在するかどうかで表現した場合には,

監査やコンプライアンスの担当者には

わかりにくいプログラムが出来上がるでしょう.



プログラムに暗黙の了解の部分があると,

他人が見た時,

それがわからずに苦労することになります.

暗黙の了解の部分などは作らず,

できるだけ明解にしておくべきでしょう.

あるキーを手がかりに取得した別のキーを使って

存在チェックをするというのは,

明解だとはとても言えません.

そんなコードを見て,すぐに

「なるほど,このコードは利害衝突を防止するための

ビジネスルールの実装だな」

などと直感する人はそうはいないでしょう.



コードがどのような概念を表現しているのかは,

できる限り一目でわかるようにしておくべきです.

そうすれば,

他のプログラマがコードを見る時に,

いちいち

「まず,必要な概念を理解してから,

 それに当てはまるコードを探す」

などということをしなくても,

何が書いてあるのかすぐに理解できます.

また,ドメインモデルが成長した時に,

(あなたのドメイン理解が深まる度に)

コードをそれに合せて進化させることが可能になります.

さらにカプセル化も十分ならば,

特定のビジネスルールに対応するコードを

一箇所に集中させることができます.

コードを修正する際も,

他のコードへの影響を心配する必要がないので,

誰にも迷惑をかけずに修正ができるのです.



何ヶ月か時間が経ってからコードを見たプログラマは,

きっと最初にコードを書いた人に感謝するでしょう.

そしてそのプログラマは,

最初にコードを書いた本人かもしれないのです.



■著者データ

[ダン・ノース (Dan North)]

Dan Northは,

自らアジャイル手法,リーン手法*1によって

ソフトウェアを書くプログラマであると同時に,

こうした手法のコーチングも行なっている.

「人が一番大事.

 そしてシンプルで実践的なソフトウェアを書くことも大事」

という信念を持つ.

また,

「ソフトウェア開発チームが直面する問題の殆どは,

 コミュニケーションに関するものだ.」

というのも信念の1つである.

そしてこれは,

ソフトウェア開発チームに限ったことではなく,

人間に共通して言えることだと信じている.

この信念から,

「言葉を正しく使う」

ということを常に重要視し,

ビヘイビア駆動開発*2,コミュニケーション,学び

について情熱を燃やし,

情報を発信している.

大学を卒業した1991年以来,

一貫してIT業界で仕事をしてきた.

ブログも参照のこと.

DanNorth.net


*1:製造業を中心に展開されているリーン生産方式の考え方(リーン思考)をソフトウェア製品に適用した開発手法。アジャイルソフトウェア開発手法の1つに数えられる。:リーンソフトウェア開発 − @IT情報マネジメント用語事典

*2:ビヘイビア駆動開発 (振舞駆動開発; behavior driven development; BDD)とは、プログラム開発手法の一種で、テスト駆動開発から派生した物である。ビヘイビア駆動開発 - Wikipedia