Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

もうひとつのデザインについての話をしよう

こんにちは、Javaエンジニアの内波です。

前職では企業向けの業務システムをカスタムで作っていたりしました。

今回は、その前職で新人の頃に先輩から教わり、今後もずっと鍛えていかなければいけないと思っている、「システムのデザイン」についての考え方をお話しようと思います。  

ロジックではなくデザインを考えろ

あるシステム開発プロジェクトの終盤、機能テストにて問題を発見しました。

その原因は単純なものに見え、それを解決するための対応案をすぐに考え付いた私は、意気揚々とその解決策を先輩へ伝えましたが、あっさりと却下されました。

先輩曰く

目先のことに捕われすぎている。 君が言っているのは今回の問題を解決するための『ロジック』だ。 ロジックを考えてはいけない。我々はシステムを設計しているんだ。 ロジックではなくデザインを考えなければいけない。

その言葉を聞いた瞬間は、その2つの言葉が意味するものがどのように違うのか解らず、「?」が頭に浮かびました。

それを察したのか先輩は言葉を継ぎました。

例えば君の案を採用したとして、こういうパターンの時はどうなる?あるいはこんなケースでも大丈夫?

その問いに対して「そういうときは……」と答えようとした私を遮り、

重要なのはそれらに対応できているかいないかじゃなく、そういった疑問が生まれることがまずいんだ。正しくデザインできていれば、もっと大きなレベルでそれを担保できるから、そもそも聞く必要はない。 逆に言うと、今回の問題は、その設計がまずっていたから発生している。だから、そこを変えなければ意味が無い。

そこまで言われてようやく先輩の言わんとしていることがなんとなく理解できました。

それまで「基本設計」やら「詳細設計」と言った言葉に触れていながら、単に作成する物の違いやスケジュールの区切りのような物としてしか意識できていなかった「設計」というものが何を意識して行わなければいけないものなのかを感じ取ることができたのです。

それ以降、システムを作る際には必ず、仕組みをデザインするということを心がけようとしていますが、そんな中で私が陥ってきた罠と、具体的な心がけをご紹介しましょう。  

1.局所最適解の罠

いきなりですが、盲点というものをご存知でしょうか。(wikipedia:盲点)

盲点とは、人の眼には原理的に見ることのできないエリアがあり、特定の方向からくる光は検知することができないというものです。 眼をカメラに例えれば、毎回撮影した画像の真ん中にぽっかりと穴が開いていることになります。

人がこの盲点を特に意識しないのは、盲点の情報を勝手に補完するという謎技術が存在しているためですが、wikipediaのページに書かれている「実験」によって、実際に見ることができないポイントというものを体感することができます。

このような点が存在する理由は、光の情報を脳へと伝えるための視神経が、光を感知するための部分を貫いて眼の裏側に回っているためです。 スマートフォンのカメラに例えるなら、配線がわざわざ筐体の外側から、レンズ部分を貫いて中に入り込んでいるようなものです。 最新の端末売り場に行ってそのような製品が並んでいたらどうでしょう。

売り場の店員はこう言います「映らない部分があるんじゃないかって?大丈夫、最新のPhotoshop技術を使って欠けた部分を補っているから、自然な画になりますよ!」

もし私がゼロから人間を設計してこのような眼の形にしたのだとしたら、このあまりにもイけていない仕様にしてしまった若き日の自分を殴り飛ばすために、すぐさまタイムマシンに乗るでしょう。

眼がこのようなデザインになったのは、後から見れば、その時その時に最も有利な形が生き残ってきた結果そうなっただけ、ということになります。 おそらく盲点を補完する謎技術もその一環なのでしょう。

遺伝子それ自体は目的を持って変化したりはしませんが、仮に擬人化したとしたら、これはまさに冒頭で私が犯した過ちと似ていないでしょうか。 「とりあえずこの穴を埋めれば問題は解決する」 目先の問題に捕われるあまり、もっと良い解があることに気づいていません。

この罠は「問題」が明確であればあるほど陥りやすいです。

エンジニアならば誰もが大抵、見つけたバグを改修したつもりで、新たなバグを生み出してしまったことが、一度や二度はあるでしょう。 そしてその時に、さらに分岐を追加してそのバグに対応したりなんかして。 その時に問題になっているのは、ソースコードが汚くなるといったレベルの話ではなく、目指すべき方向を誤っていることが問題なのです。 カメラの話でいうなら、欠けた画像の補完が目的ではないし、もっというと配線を裏側に持っていくことや穴をなくすことことすら目的ではありません。 何が目的か。それを知っているのはそれに取り組んでいる人間だけです。

自分が作ろうとしているシステムが、どのようなサービスを提供しようとしているのか、それを含めて、本質的に目的を考える必要があります。  

2.過度な汎用性の罠

ちょっとだけシステムのデザインを理解した気になっていた私が、とりあえず汎用的になっていれば良いデザインだという勘違いをしていたころに陥った罠です。

データベースにとあるテーブルを追加する際、想定されている要件以上に、あらゆるパターンに対応できるようにと、目一杯ふんわりした構造・カラム名称にして、汎用的な機能を作った気でいました。

しかしこれは例えば、眼を作るためのパーツとして、光を感知する部分も、信号を伝えるための神経も全部が全部を万能細胞によってデザインするようなものです。

どのパーツが何をするのか、設計した人間以外にはさっぱり分からず、 「神経部分が光を感知したりもするの?そのときはどういう動きになるの?」 といった新しい疑問までわいてきてしまいます。

幸いその時も、別の賢明な先輩が見てくれたおかげで 「テーブル構成からシステムが想像できないどころかソースコードを読んだとしてもこいつが何のために存在しているのか解らない」 と却下を受けることができました。

これも結局は目的を見失っていることから来ています。 提供しようとしているサービスの理想像すら超えた汎用性など、つぶあんのつぶ並に害しかありません。  

3.相乗りの罠

ある目的のためにデザインされたシステムに、ほんの少し小さな変更を加えると、全く別の要件がまかなえる。

聞こえは良さそうですが、最深の注意が必要です。

例えば光を検知する細胞。 光があたっている or あたっていないのON/OFF状態だけを管理していたはずなのに、「空気の振動を感知するようにすれば眼で音も聞ける!」という思いつきが生まれました。

しかも事情によりある一部分の細胞だけがそうなるだけで、他の大部分の細胞はもとのまま。 そして情報を伝達するための神経は光用と同じものを使うが、音情報が伝わるのは、普段利用されていなかったためあいている紫外線用の領域。

なにか嫌な予感がしませんか。

しかし、時間に追われている時に、この誘惑を断ち切るにはかなりタフな精神力が必要です。 なぜならゼロから耳システムを作るのは並大抵のことではないからです。 それに比べれば、「そうなっている」ということを知ってさえいれば、それほど大きな問題がなさそうに感じてしまい、逆にお酒とかが入っていたりすると 「完璧とは言わないけどまぁまぁいけてるんじゃないかな。最初にデザインしたときに汎用的にした自分を褒めたいな。」 とまで思ってしまったりすることもあります。

しかし、これをやってしまうと一子相伝の暗黙知を延々と受け継いでいく必要がでてしまうのです。 新しい人が来るたびに「紫外線領域って書いてあるけど、そこは音が通ってるからね」と。    

以下は上で述べたような罠に対するための心がけです  

1.レビュー

どんな時でもレビューです。レビューは偉大です。

チームメンバーから受ける1回のレビューに比べれば、この記事に書かれていることなど、つぶあんのつぶ並みに価値のない話です。 どうしたって一人では気づかない・気づけないことがありますから。

レビューがもらえる状況にあるならば(そして地球から100万光年離れた星に一人でいるのでもない限り、そうではない状況なんてそうそうないはずです)、是非レビューを受けましょう。

ただし、その場合はしっかりと自分のなかで考え抜いたものを作ってからにしましょう。中途半端な状態の案だと、その場で議論が始まって2人で一緒に案を練りだしたりして、視野や視点が被ってしまうことで罠が忍び寄ってきます。  

2.足さない

局所最適解の罠はおおむね、既存システムに手を入れる際に、目先の問題解決のため何かを「足す」ことを繰り返すパターンが多いです。

そのため、ある目的を達成するために何かを足すことを制限し、変えたり・減らしたりすることで解決できないかを考えるようにします。 特にプログラミングの場合、コードを減らす方向で対応できる場合は、良いデザインになる傾向がある気がします。

そもそも単純に何かを足すだけで事足りるようなことであれば、ちょっと賢い機械に任せれば、生物の進化よろしく対応できます。 一足とびで良いデザインにたどり着くことこそ人間の価値を発揮すべき場所です。 (もっともケースによってはそれも機械の方が賢くなっていたりするかもしれませんが)

足す方よりも時間がかかりそうだとしても、それはほんの短期間の話です。 本当に良いデザインにできるのであれば、きっとその後にもっとたくさんの時間を節約してくれます。恐れずに変えていきましょう。  

3.フレームワークに従う

良くできたフレームワークは、より良いデザインへと導いてくれます。

というよりも、どちらかというと私にとってのフレームワークとはそのためのものです。 単に便利なツール群を提供してくれるものではなく、思考を「枠」にはめることによって、深く考えずとも良くないデザインを除外してくれたり、 あたかも俳句における制約がより美しい詩を生み出す手助けをしているかのように、全くの自由な状態から物事を考えるよりも優れたデザインを思いつかせてくれたりします。

そのため、余裕があるのであれば、そのようなフレームワークを用意することに時間を使うのもいいでしょう。 たとえばマネーフォワードではWebアプリケーションフレームワークにRuby on Railsを採用していますが、それ以外にもエンジニア達が自ら考えた様々な「枠」を追加することでマネーフォワードらしいデザインが生まれるように、日々努力しています。

「デザインするためのデザイン」というわけですね。  

最後に

マネーフォワードでは、デザインについて考える仲間を募集しています。 みなさまのご応募お待ちしております!

マネーフォワード採用サイト https://recruit.moneyforward.com/

Wantedly https://www.wantedly.com/companies/moneyforward