Userクラスが抱える問題

ここでやっとUserクラスが抱える問題。Userクラスを今のモデリング観点と照らし合わせてみると、個人顧客と法人顧客の関心事の異なる問題を、たった1つのUserクラスで取り扱ってしまっています。つまり、複数の問題解決のために、Userクラスが流用されている構造です。特定の問題解決を意図した構造になっていないんです。

このユーザーというのは、個人でも法人でもどうとでも解釈可能で、利用者のあらゆる側面を意味しているように見えてしまっています。Userクラスが、顧客管理クラスから見れば個人に見えるし、法人管理クラスからは法人に見えている。結果、利用者に関係するさまざまな概念を内包できてしまうわけです。

要は、個人と法人では解決したい問題が違います。だから、ミクロなシステムとしては別です。解決したい問題によって扱う要素が違うと先ほど説明しました。個人では生年月日、法人では法人番号、各ミクロのシステムで必要とする情報が違うのに、一緒くたにしてしまっているんです。

そのため、結果として何が起こったかというと、単一責務原則違反や、さっきの生年月日、法人番号など、一貫性のない構造。クラスが巨大化したり、密結合になってしまっている。みなさんのサービスのUserクラスは大丈夫ですか?

Userクラスが抱える問題の本質は、モデリングされているようで、ぜんぜんモデリングされていない。種類の異なる問題がシステム内に複数存在することを、作り手が意識できていないところが起因している。特定の問題解決のために、一側面だけが抽出されていない。

それぞれの問題に対応する個別の解決システムとして分離されているべきものが、密結合になってしまっている問題を抱えている。

モデリングの問題を解決する方法

では、そのモデリングの問題を解決しようという話です。それには、問題それぞれに応じたモデリングをしようというところです。Userクラスが解決しようとしていた問題、関心事をすべて列挙します。問題、つまり関心事それぞれに対応するモデルを設計し直す。そうして初めて、リファクタリングのゴールとなる、あるべき設計が見えてきます。

さっきの動画では、彼らは最後にUserクラスを分割しようとして失敗して全員爆死したわけですが(笑)。ちゃんと分割すれば、爆死せずに済んだというところです。

モデリングに必要な考え方で、関心の分離と分割統治というのがあります。関心の分離というのは、関心事ごとに分離した構成要素でソフトウェアを構築するという考え方。分割統治は、小さな問題に分割し、個別に解決する考え方です。

基本的にはこの2つの考え方に基づいて、関心事それぞれに対応するモデリングをしていけばいいわけです。「では関心事の違いって何?」「どの観点で分離すればいいの?」など、いろいろ疑問が出てくると思います。いくつかアプローチの仕方があるので紹介します。

“主語クソデカ問題”から見るアプローチ方法

“主語クソデカ問題”というのがあります。名前は、概念のある一点を指し示すのではなく、範囲を示すものだと思います。クソデカの名前の例として、商品というものがありますが、これまた意味がガバガバです。

(スライドの)右の図で示すように、商品の意味があまりにも広すぎて、予約や注文、配送など、いろいろなものに関連づいてしまって。商品クラス自体も、いろいろなロジックを持って巨大化して、密結合になっています。Userクラスも、はっきり言ってクソデカ主語の筆頭なわけです。

そのため、大事なのは、名前設計。モデリングするうえで、名前の設計は超重要です。どうするかというと、具体的で意味範囲の狭い言葉を選びます。ザルな解釈を許容しない。一意に意味を特定可能な、特化した名前を設計します。

例えば商品の例も、より意味の狭い予約品や、注文品など、小さく分解します。こういう特化した名前を選ぶのです。特化した名前を設計して、モデルを分割することによって、各モデルの関連を最小限に抑えられるわけです。

この考えに基づくと、少なくともユーザーは個人と法人に分けられます。でもまだこれは完成系ではありません。

ユースケース図から見るアプローチ方法

もう1つ大事な観点があります。実際にモデリングするときは、まずユースケース図を書くことになると思います。ただ、ここでアクターをモデルとして使ってはいけません。この図でシステムは、あくまで四角い箱の中なわけです。アクターは、箱の外にいるじゃないですか。

あくまでシステムの利用者なわけなので、アクターをモデル化すると、Userクラスもよくない性質を帯びはじめます。しかし一方で、利用者の名前や電話番号、システムを動作するために必要な利用者の側面は確かにあるわけです。

ではどうするか? というところです。システム上でどう表現されているかに着目するのが大事です。非常に秀逸な例ですが、みなさんがよく使っている、GitHubの設定メニューです。

アカウントや、プロフィール、表示テーマ、セキュリティなど、いろいろな関心事ごとに項目が分かれています。これすごく参考になりますよ。これを参考にすると、Userクラスは次のようになります。

個人アカウントと法人アカウント。実際には関心事ごとにさらに多くのモデル、例えばさっき見たプロフィールが作られるようになると思います。各モデルに関連のある知識を集約して、カプセル化すればいいです。

この資料で一番伝えたいことです。ここだけ理解してもらえれば文句なし! それは、現実世界の物理的存在とシステム内のモデルは、1対1になるとは限らない。むしろ1対Nの関係になる可能性があります。たった1つのモデルに統一しないで、関心事に応じたモデルをそれぞれ設計することが大事です。これを名目と現物の分離と言います。

モデリングの発展議論

以上がUserクラスの問題についての解説です。ここからはモデリングの発展議論になります。価値の本質とイノベーションについて議論した話です。

最初に2つ例を挙げます。大昔、中世など、当時昔の人々は疫病の原因を悪魔と呼んでいたと思います。悪魔とモデリングしていた。悪魔と呼んで、当時どう対処しましたかね? 

お祈りしたり、悪魔払いをしたり。でも、そんなので効果的に対処できていましたかね? できていなかったと思います。のちに細菌が発見されて、対処方法も劇的に革新されてきた歴史がある。

もう1つの例、「エバンゲリオン? あぁ、あのガンダムですよね? ロボットのやつ」。こういう雑な認識の人に『エヴァンゲリオン』とか『ガンダム』のゲーム開発を任せられますか? という話なわけです。

何を言いたいかというと、実際の開発で我々が扱うビジネスは、もっともっと複雑です。ビジネスの深い理解もないのに、問題の本質に到達できますか? という話なわけです。

さっきの例えですが、我々は実は悪魔というモデリングをしているんじゃないかと。ちゃんと本質を突き詰めて、細菌を発見できているか? というところです。システム化対象の人の営みについて、認識の解像度が低かったり、問題の本質を理解していないと、問題解決に正しく貢献するモデリングは難しくなると思います。

ちょっと残念な例で、「私、技術に興味ありますけど、ビジネスに興味ありませんから。仕様はビジネス側で考えてください」。こういうちょっと残念な考えを持っているエンジニアって、現実に一部います。でも、こういう考えを持っていると、結局設計が瓦解して、顧客に訴求するシステムが作れなくなってしまう可能性が高くなると思います。

イノベーションで有名な、世界に自動車を広めたフォードさんの言葉です。「もし顧客に彼らの望むものを聞いていたら、彼らは『もっと速い馬が欲しい』と答えていただろう」と。

馬車しかなかった時代は、自動車という概念がないわけなので、みんなそう答えます。仕方がないです。でもそうじゃない。手段に囚われずに、もっと早く移動したいというニーズ、本質的な問題に着目することで、新しい乗り物、自動車というイノベーションが生まれたんです。

我々のシステム開発でも、システム化対象の概念をそのまま名前どおりにモデリングしているだけだと、イノベーションは生まれないと思います。「その概念、実はただの手段じゃないの?」と疑問をもつことが大事なんじゃないかと思いました。これに関して、僕がいいなと思う例を2つ挙げます。

例の1つは、みなさんよく知っているTwitter、あくまで僕の解釈ですが、Twitterの最大の特徴と考えられるモデルは、リツイートだと思います。

みなさんも知っているとおり、リツイートは、リツイートされたツイートがフォロワーのタイムラインに表示される仕様。つまり、リツイートってタイムラインを変換する能力があります。これによって、良くも悪くも話題性の高いツイートが拡散される仕組みである。コミュニケーションをイノベートした存在だと僕は思います。

もう1つは、任天堂のリングフィットアドベンチャー。プレイヤーのフィットネスで敵を攻撃するという画期的なゲームです。このゲームにはフィットスキルというものがあって、プレイヤーの運動で敵を攻撃します。フィットスキルは、プレイヤーの運動を攻撃力に変換する能力を備えていると、僕からは見えます。

これらの例に示したように、世の中の優れた情報システムは、有益な変換能力を持っています。コンピューターが何かって言うと、本質は信号処理です。信号処理をさまざまな演算や変換に応用することで、我々は恩恵を得ています。そのため、優れた変換能力を内包したモデルを設計することが、イノベーションの鍵ではないかと僕は考えます。

概念の名前を表面的になぞられるだけのモデリングだと、リツイートやフィットスキルという画期的なモデルは、決して生まれてこないと思います。ちなみに、こういう本質的な価値向上に貢献するモデルを、ドメイン駆動設計では深いモデルと呼びます。

ビジネス課題の解像度をあげる2つのメリット

これまで説明したように、モデリングにはビジネス課題とか概念が密接に結びついています。そのため、モデリングするとき、ビジネス課題を深掘りして理解の解像度を上げることで、少なくともここに書かれているような2つの利点を得られる。

まず1つの利点としては、Userクラス絡みですが、一貫性があって、疎結合高凝集なクラス設計に貢献するモデルができる。技術的負債を負わせない、負債の解消に役立つ。

もう1つの利点は、先ほどのイノベーションの例のようにビジネス課題の解決に大きく貢献するモデル設計につながって、サービスの価値向上を期待できる。そのため、エンジニアリングとビジネスは、近接しなきゃいけないと考えます。

これを促進するのが、僕が今月入社したREADYFORの乳化というコンセプトです。この乳化というのは、組織の中にエンジニアリングが自然に溶け込んでいる状態を指しています。このコンセプトでイノベーションとパフォーマンスを最大化するということを目指しています。

これはまさしくエンジニアリングとビジネスの近接を実現するコンセプトで、あるべき設計や問題解決に大きく貢献する設計を推進していけると感じて、僕はREADYFORにジョインしました。

Userクラスの負債化はモデリングが問題

まとめです。モデリングとは、特定の問題解決のために、物事の特定の側面を抽象化したものである。Userクラスが負債化しやすいのは、まともにモデリングされていないのが原因。現実世界の物理的存在とシステム内のモデルは、1対Nの関係になる可能性がある。

一貫性があり、疎結合高凝集な設計に役立つモデリングをするには、システム化対象の人の営みや、営みに伴う問題解決の理解が必須です。問題の深い理解は品質面だけでなく、より有益なモデル設計につながったり、システム価値の向上を期待できるところです。

最後にちょっとおまけです。私、本を出版することになりました。その名も、『悪魔の設計(仮)』。この本は「クソコード動画を書籍化してみませんか」という、技術評論社の編集者さんからの提案で、アンチパターン駆動の設計技術本です。

よくない実装はどんな問題を引き起こすかとか、問題解決にはどんな設計が必要かを解説する本です。ソフトウェア開発に潜む悪魔を退治する設計本です。読者対象は設計を知らない、または興味があるけど、何を学んでいいかよくわからない設計の初心者を対象としています。初級から中級にハシゴをかけることを主眼にしています。

今もう9割近く執筆が完了していて、技術評論社から2021年全国出版予定です。出版のあかつきには、ぜひみなさん手に取ってもらえるとありがたいです。

発表としては以上です。みなさん、ご清聴ありがとうございました。