クソコード動画『Userクラス』

仙塲 大也(以下、仙塲氏):こんにちは。ミノ駆動と言います。不運な時間がやってまいりました。まじめなセッションだらけなのに、はたしてこういう動画を流していいものかと。完全にネタ枠です。

このセッションの説明です。多くのサービスで技術的負債になりやすい筆頭格として、Userクラスがあります。本セッションでは、Userクラスの負債により引き起こされる弊害を描いた、風刺動画を上映します。

Userクラスではどんな課題が生じるのか。なぜ負債化しやすいのか。そして、負債解消に必要な観点について話します。なお、絶叫が響くので、みなさん音量には十分に注意してください。それでは始めます。クソコード動画『Userクラス』です。

(動画再生)

上司:おう、お前ら。ECサイト作るで。仕様は今んとこないが……よしなに考えて作ってくれや。

クラスB:へーい。

上司:ええか、時代はDXやぞ。DXで開発進めていけよ。お前ら。

クラスA:DXって何ですか?

上司:……。DXはDXや! ほな!

クラスA :まあ、ええか。

クラスB:何から作ったらええんやろか……。

クラスA:なにはともあれ……

クラスA&B:Userクラスやな!

クラスA:お、そっちでもUserクラスクラス作るんか? やったら一緒に作りませんか?

クラスB:そうやね。やりまっか。

クラスA:次はワイらの責務やな。ワイは注文側の顧客を管理するで。

クラスB:ほなワイは出品側の法人を管理するで。

決済クラス:お、Userクラスがあるんか。ワイらにも使わせてーな。

顧客管理クラス:ええよ、ええよー。

法人管理クラス:どんどん使ってー。

予約クラス:インスタンス変数、追加してええかー?

顧客管理クラス:ええよー。別に許可取らんでも好きに追加してや。

法人管理クラス:せやでー。ワイも追加するで。

顧客管理クラス:さてと、サービスもローンチされたし、ユーザーの登録にさっそく取り掛かるかな。

(新データを入力する)

法人管理クラス:ぎゃあああああ!?

顧客管理クラス:ん? なんか爆発音が……

法人管理クラス:げふっ……。ぬ、NullExceptionで……脇腹に256メートルの風穴が開いた……。だ、誰や! 法人番号にnull渡したヤツは!?

顧客管理クラス:あ、ワイや。

法人管理クラス:「ワイや」やないわ! 法人番号にnull渡すなや!

顧客管理クラス:え、でもワイんとこで使わへんし。嫌やったらそっちでnullチェックすればええがな。

法人管理クラス:ぐぬぬ……。

(nullチェック)

はー、死ぬとこやった。気を取り直して、こっちのユーザー登録するか。

(新データ入力)

顧客管理クラス:ぐおおおおおおおおおお、冠動脈が1,024本千切れたあああああ! 誰やあああああああ、生年月日にnull突っ込んだやつはああああああ!

法人管理クラス:あ、ワイかもしれん。

顧客管理クラス:ユーザーいうたら生年月日入れるもんやろが! 常識やぞ!

法人管理クラス:うちのユーザーは法人や。なんで法人に生年月日がいるねん。それにnullチェックすればええ言うたの自分やろ。

顧客管理クラス:ぐぬぬ……。

(nullチェック)

はー、つら。次のユーザー登録するか。

(新データ入力)

法人管理クラス:があああああ、肝臓が破裂したああああ! アホんだら! んな短い名前渡すなや! こっちは4文字以上の入力必須なんや!

顧客管理クラス:ユーザーさんがこの名前で登録したがってるんや。4文字以上はそっちの都合やろが。

法人管理クラス:ぐぬぬ……おのれ……

(新データ入力)

顧客管理クラス:ぐおおおおおおおおお! 眼球が65,535メートル飛び出たああああああ! (株)とか人名に使えん文字入れるなや! バリデーション違反やぞ!

法人管理クラス:知らんわ! そっちの都合やろが!

顧客管理クラス:もう許さへんで!

法人管理クラス:それはワイのセリフや! なにが顧客管理クラスや! 構造体みたいなナリしおって! 構造体はC言語みたいな化石言語のとこに帰れや!

顧客管理クラス:それは貴様も同じだろうがああああ!

法人管理クラス:ワイとは世界が違うわ! Userクラス分割して邪魔な部分排除したるわ!

顧客管理クラス:望むところだあああああ!

決済クラス:ぎゃああああああ! お前らなんてことしてくれるんや! ワイらもUserクラスにつながってるんやで!

顧客管理クラス:Userクラスを分割せんと、ワイら死んでまうんや! 少し痛みに耐えてくれや!

法人管理クラス:せやで! 「痛みに耐えて、よくがんばった。感動した!」ってえらい人に褒められるんや!

顧客管理クラス:いくで!

法人管理クラス:せーのっ!

GAME OVER

(動画終了)

仙塲氏:はい、こんな感じになりましたが。みなさんのところのUserクラスは大丈夫ですかね?

じゃあ解説に入ります。「『Userクラス』で考える技術的負債解消の観点」ということで、READYFOR株式会社の仙塲が発表します。

レジュメはこのようになっています。まず自己紹介、それから劇中の問題。システムとは何か。情報システム開発とモデリング。Userクラスが抱える問題。モデリング解決編、あと発展編とまとめ。最後、おまけという構成になっています。

自己紹介

まず自己紹介。私、Twitterではミノ駆動と名乗っています。不定期でクソコード動画など、風刺動画をTwitterに投稿しています。中の人は仙塲大也と言います。職歴はNECネットワーク・センサでファームウェア開発、キヤノンで組み込み系や Windowsアプリ開発、リファクタリングやリアーキをやってきました。

十数年、組み込みの世界にいましたが、2年前にWeb系のクラウドワークスにジョインしました。そこで巨大Railsアプリのリファクタリングをやってきました。今月、READYFORにジョインしました。同じくリファクタリングの仕事です。という感じで、リファクタリングやクソコード退治の仕事が大好きです。よろしくお願いします。

動画で起きた問題の振り返り

まず動画でどういう問題が起きたのかをちょっとおさらいします。まず、必要とするデータが状況によって異なる。法人管理クラスは法人番号を必要としているのに、顧客管理クラスは個人のユーザーを想定していため、法人番号を設定していなくてnullになっている。

逆に、顧客管理クラスは生年月日を必要としているのに、法人管理クラスは法人がユーザーだと思っているから、生年月日はいらないと思っている。互いに必要とするデータが違っているという問題です。

それから制約が異なる。同じ名前でも、かたや人名、もう一方は会社名だと思っているから、名前に関する制約が違ってしまっています。

それから3つ目、影響範囲の拡大。いろいろなクラスがUserクラスに依存しているために、なにか修正しようとすると、あらゆる箇所に影響が生じてしまう。ヘタにいじり回して、全員爆死となるわけです。

もはや設計ミスに近いですが、この手の技術的負債は、単にロジックを整理するだけのリファクタリングでは解決困難です。この発表では、Userクラスの負債解消に必要な観点について解説します。

Userクラスの問題をひもとくには、「そもそもシステムとは何か」とか、「我々が何のためにシステム開発をするのか」を理解する必要があります。少し長くなりますが、ぜひお付き合いしてもらえればと思います。

そもそもシステムとは何か?

まずシステムとは何か。世の中は、さまざまな社会的活動から成り立っています。例えば人とコミュニケーションを取るとか、目的地に移動する。それから、農作業するとか、買い物するとか、仕事するとかなんでもです。こういう社会的活動を、ここでは“人の営み”と呼ぶことにします。

“人の営み”は、はるか大昔からシステムによって実行されてきました。「ちょっと待ってくれ。太古の昔からシステム? そんな大昔からコンピューターなんてあったっけ?」っていう疑問を覚えませんか。システムって何だよと。

ここでちょっとシステムの定義を見てみます。Wikipediaからの引用ですが、“相互に影響を及ぼしあう要素から構成される、まとまりや仕組みの全体”って、なんかよくわからんって感じです。

これを噛み砕いて説明します。例えば、“目的地へ移動する”という営みを、大昔から支えてきたシステム。それは、二本足を交互に動かして移動するという二足歩行システムによって、人は目的地へ移動するのを果たしてきました。

もう1つの例、コミュニケーション。情報の発信側は発声器官、つまり喉を振動させて発声させる。音波を唇や舌を使って、加工して言葉を作る。情報の受け手は聴覚器官、つまり耳の鼓膜で音波を受け取って、それを脳で解釈するという会話システムで意思疎通を果たしてきました。

つまりわかりやすく言うと、(システムとは)人の営みを遂行し、問題を解決するためのなんらかの仕組みのことです。そのため、人体に備わる器官や臓器も、立派なシステムです。

人類は有史以来、いろいろな道具やシステムを発明したり開発したりして、既存のシステムを置き換えてきました。例えばコミュニケーション、近年ではSNS、移動は飛行機や自動車などの乗り物。農業は農具が発明されて、近代ではトラクターとか。買い物はAmazonのショッピングサイトと、システムが置き換わってきたんです。

特にSNSやショッピングサイトなど、コンピューターによるものを、情報システムというふうに呼びます。

何のためにシステム開発をするのか

じゃあ何のためにシステムを開発して置き換えるのか? というところです。それは何かというと、問題解決の効率化のためです。例えば遠い遠い都道府県に旅行しに行くケースを考えてみると、徒歩だけで旅行できますか? やろうと思えば気合いでできると思います。でもめっちゃ大変。

だから、徒歩という二足歩行システムを、飛行機などのより優れたシステムに置き換えることで、何倍も効率化できるわけです。テクノロジーの本質は、能力の拡大縮小である。

そのため、システム設計者は効率化するにあたって、対象とする人の営みや、その問題に伴う問題の理解が必須です。問題を理解して、はじめて効率的に解決可能な仕組みを設計できる。逆に問題を理解していないと、問題解決に貢献しないシステムが作られてしまう問題があるわけです。ここ非常に大事なポイントなので、よく覚えておいてください。

情報システム開発とモデリング

ここからは、情報システム開発とモデリングの話になります。今説明したように、システム設計には人の営みや、その問題を理解することが大事だと言いました。そのため、システム化の対象の営みを分析して、どこをシステム化すればいいかとを考えなければいけません。

ここでは、ECサイトを例に考えてみます。人が買い物をするときは、まず利用者がいて、利用者が注文をして支払いをする。出品側は在庫管理をしたり、受けた注文に対して配送を手配したりします。この営みの中の利用者に着目して、利用者のシステム化を考えてみます。

利用者についてまわる情報は、いろいろなものがあります。名前、電話番号、クレカ情報、年齢や身長、さらには推しのアイドルや鼻毛の本数など、いろいろたくさんあるわけです。こういう情報すべてをシステム化すべきなのか、というところです。

ECサイトを作るのに、利用者の血圧や、今まで食べたパンの枚数はいるのか。これはどう考えてもいらないですよね。利用者のあらゆる属性をシステム化したらキリがありません。やろうと思えば、はっきり言って無限にある。

必要な部分って、一部分しかないはずです。その一部分とはどの範囲か? システムの定義と、システム化の目的を振り返ってみます。

システムの定義は人の営みを遂行し、問題解決をするためのなんらかの仕組み。システム化の目的は問題解決の効率化。だから、問題解決に必要な部分があればいいわけです。ECサイトでは赤枠で括った場所、名前とかクレカ情報、配送先、購入履歴。つまり、商品の売買に必要な情報があればよい。

一方で、青枠で括った、医療サービスで必要とする部分。それは血圧、体重、体脂肪とか、身体情報や健康情報があればいいです。つまり、何を解決したいかによって、システム化する部分が違います。

今挙げたようなシステム化したい概念を、システムの構成要素として整理していく。この整理する活動をモデリングと言います。

モデリングの定義

モデルの定義は何ぞや? と。ドメイン駆動設計の定義を引用すると、モデルは“ドメインの選択された側面を記述し、そのドメインに関連する問題を解決するために使用できる抽象化のシステム”。ドメインは“知識、影響力、活動の範囲のこと。プログラムを適用する対象領域がそのソフトウェアのドメイン”。ちょっとまた難しい言い回しなので、これも砕いて説明します。

モデルというのは、システム化対象の人の営みに登場する概念を抽象化したものです。これは、あくまで問題解決に貢献する部分だけを切り出して、システムの役に立つように似せて作ったもので。

(スライドの)右の図で示すように、サービスをマクロのシステムとすると、マクロなシステムはモデル、すなわち小さなシステム群から構成されると考えられます。

ここで抽象化の言葉の意味ですが、ちょっと注意が必要です。抽象化というと、犬と猫の共通要素から動物を導き出す、クラス設計でいう、汎化や抽象クラスをイメージするかもしれませんが、これはそうではなくて。

先ほどの利用者の例のように、膨大な具象パラメータのうち、エッセンスだけを抜き出して簡略化する、要約するという意味に近いです。

ここまでのモデルの定義や特徴を整理すると、特定の問題を解決するために存在するものだから、モデリングは概念の特化と言えます。登場概念を、特定の問題解決に貢献する側面のみを切り出してモデル化する。概念のすべての側面ではありません。あくまで“特化した一側面だけ”という点がすごく大事です。

ここすごく大事なポイントです。よく意識してください。ここからやっとUserクラスの話になります。

(次回につづく)