「「現場で役立つシステム設計の原則」批判 (1) ~何のために、「データとロジックを一体に」するのか?~」の批判

こちらのエントリに違和感があったのでちょっと書いてみたいと思います。

PHP Mentors -> 「現場で役立つシステム設計の原則」批判 (1) ~何のために、「データとロジックを一体に」するのか?~

SalesOrder(受注)クラスの導入について

上記のコードが問題を含んでいる原因は、このコードが「値引きは数量のみに基づいて行われる」という知識を適切に隠蔽していないことにあるわけです。

本来は、値引き判定のロジックをどのオブジェクトに配するかを決めるにあたって、どのような知識を隠蔽すべきか、あるいは裏返して言えば、どのような知識は開示して構わないかという点に思いをめぐらすべきでした。

値引き条件などというものは、ビジネス上の都合により変更されやすいものです。このケースのように注文数量だけで値引き可否が決まるというケースもあるかもしれませんが、発注金額も考慮し、あるいは発注者が上得意かどうかも判断要素に含める、というように変更されるかもしれません。一方で、注文数量・金額・発注者が誰かなども含む受注内容に応じて値引き可否が決まる、という点はたぶん変わらないだろうと考えられます。

であれば、このケースで開示してよい知識と隠蔽したい知識とは以下のようになるでしょう:

開示してよい知識

受注ごとにその内容に応じて値引き可否が決まるという知識。

隠蔽したい知識

注文数量・金額等にもとづく具体的な値引き決定ルール。

これを踏まえれば、isDiscountable()は、Quantityクラスにではなく、呼び出し元であるamount()メソッドを含むSalesOrder(受注)といったクラスのメソッドであるべきだということになります

PHP Mentors -> 「現場で役立つシステム設計の原則」批判 (1) ~何のために、「データとロジックを一体に」するのか?~

現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法」のP.37ページのサンプルについて、こちらのブログのエントリでは情報隠蔽が適切でないからSalesOrder(受注)クラスを導入して情報隠蔽を適切にすべきだという流れになっています。

しかし、SalesOrder(受注)は一体どこからやってきたのでしょうか。「という点はたぶん変わらないだろうと考えられます。」と書かれているところからエントリを書かれた方の想像と考えられます。「現場で役立つシステム設計の原則」の方でもP.37ページの付近には「受注」という言葉がでてきません。割引という言葉が出てきているので受注も必然的にとついつい考えてしまいますが、明らかになっていない概念になります。なので、このサンプルの世界ではまだ受注というものがないと考えられます。

そうなるとSalesOrderクラスを導入することで値引きに関するロジックが隠蔽されるかもしれませんが、存在していないSalesOrderに関する知識を持たなければならないことになります。これでは過剰な設計になってしまいます。

ですので、P.37ページの時点では「値引きは数量のみに基づいて行われる」ということがコードで表現できていれば妥当である考えられます。

実務では想像による先取りは避けるべきでしょう。もっとドメインを確定させて同意を得てからでも遅くないはずです。同意が得られているのであれば話は変わってくるので、SalesOrder(受注)も良い案かもしれません。

なので、このエントリも「受注」という概念があると仮定してということであれば違う形で納得できるのかもしれません。

「ルール信奉の落とし穴」のところについて

こちらも気になったので。

しかも実践者である著者ご自身、たぶん本ケースを、良くない設計の例と見ておられない。ルールに従ってパズルを解くとそれだけで達成感が得られるので、ルールを超える視点は頭の隅に追いやられてしまうという傾向が生じるのかもしれません。

「ルールを超える視点は頭の隅に追いやられてしまうという傾向が生じる」といったところはその人の能力の問題でしょう。ルールや原則が現在の業務に対応できるか否かをしっかりと判断するのがエンジニアの仕事であると思います。