Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

Builders Box イベントレポート 〜クリーンアーキテクチャ〜 (前編)

はじめに

はじめまして。DSOC の Gees・Jes チーム所属の松本です。
普段は 名刺のデータ化システム「GEES」や、人事異動データ化システム「JES」の開発を、主にRuby on Railsで行っています。

今回は弊社が運営するBuilders Boxの主催で2021年1月29日 に行われた 「ON AIR #3 クリーンアーキテクチャ」のイベントレポートということで、自身のクリーンアーキテクチャの経験とを交えてレポートしたいと思います。


今回のイベントで一番印象に残ったのは、イベントの内容も然りですが、それ以上にMartin氏のなんと素敵な(豪快な)笑い方と笑顔! 最初の挨拶以外は日本語の同時通訳が提供されていたため日本語でイベントを聞いていましたが、その裏からもMartin氏の素敵な笑い声が聞こえてきていて、とても楽しそうにアーキテクチャの会話をされているのが非常に印象的でした。

私のクリーンアーキテクチャとの出会い

私のクリーンアーキテクチャとの出会いは前職になります。新規サービスを開発すると決まった時に、メンバーが「クリーンアーキテクチャなるものが流行しているのでこれで設計してみたい」と提案し設計を行いました。*1
Webページを中心にDDDやクリーンアーキテクチャについて調査し、メンバー間で議論を重ねて実装したのですが、クリーンアーキテクチャに関する解説記事は多く、クリーンアーキテクチャ難民と化していたというのが実態だったかなと当時を振り返って感じます。

次のような資料を参考にしていました
blog.tai2.net
noiseless-blog.net

イベントで心に残ったこと

上述のように、私のクリーンアーキテクチャへの理解が混沌としていた中で今回のイベントを受講した結果、Martin氏の言葉から数々の感銘を受けました。私が感銘を受けた内容をいくつかピックアップして紹介したいと思います。

アーキテクチャは意図を表す (Architecture is about INTENT)

Martin氏が、氏のご子息が実装したRuby on Railsのレビューを依頼されたときに、「なぜ、アプリケーションの全体をみて一番最初に理解できることが『このアプリケーションが何をするものか』ではなく、『このアプリケーションがRailsのアプリケーションであること』なのか」という点に疑問を持たれたそうです。
例えば建築物は設計図面を見たときにどんな建物を建築しようとしているかがひと目で分かるのに、ソフトウェアのアーキテクチャはそうなっていない。ソフトウェアの設計図(ソースコード)も同様に、読む人に対してこのシステムが何をするシステムであるか、システムの意図はなにか、がわかるべきである、というのがMartin氏の主張でした。

この意見を聞いて私も思い当たるところがありました。他の設計者が実装したシステムをレビューする際に、例えばそれがRailsで設計されていた場合、「app/modelsの下を見るとどんなクラスがあって、クラス名からこんなことをするのかな〜」という点までは感じることはできます。しかし、実際アプリケーションがそれらのモデルを利用して何をするか、「ユースケース」の観点では実装がいろいろなところに散らばっていることが多いです(fat model, fat controller, service layer 等)。最終的にはコントローラー層からメソッドを逐次たどって、やっとアプリケーションの意図が理解できたという経験もあります。

f:id:kiyonori-matsumoto:20210209103755p:plain
Railsのフォルダ構成

Martin氏の提唱する「クリーンアーキテクチャ」に則って設計を行うことで、アプリケーションの意図がほとんど「Interactor」*2 に集中するため、そのコードさえ読めば何をするためのアプリケーションであるかが理解できる、というのはクリーンアーキテクチャの強みの一つであると改めて感じました。

データベースは詳細 (The database is a detail)

まず詳細(detail)という単語の意味を正確に理解するために、Martin氏の著書から以下定義を引用します。*3

あらゆるソフトウェアシステムは、大きく2つの要素に分割できる。「方針」と「詳細」だ。
方針の要素は、ビジネスのすべてのルールや手順を含んでいる。方針には、システムの本当の価値がある。
詳細は、人間・そのほかのシステム・プログラマが、方針についてやり取りするために必要なものだが、方針の振る舞いに影響を与えるものではない。
詳細には、IOデバイス、データベース、ウェブシステム、サーバー、フレームワーク、通信プロトコルなどが含まれる。


Robert C. Martin, 角 征典, 高木 正弘. Clean Architecture 達人に学ぶソフトウェアの構造と設計 (Japanese Edition) (Kindle の位置No.2266-2271). Kindle 版.


上記引用を元にMartin氏の言葉を整理すると、ビジネスルールは「方針」だがデータベースは「詳細」で、システムとしての価値を持つのは「方針」である、データベースはその他のIOデバイスの一つでしか無い、という意味に考えられます。更にMartin氏は、「データベースが発明された理由は磁気ディスクへの書き込みの複雑さを解消させるため」であり、近年のPCではハードディスクではなくSSDが利用されているため、例えばBinary TreeやLinked List等、慣れ親しんだフォーマットでデータを保存することも容易であると述べていました。*4

この考えを聞いて私は3層アーキテクチャを思い返しました。3層アーキテクチャはデータベースが変わらないものとして定義されている一方、クリーンアーキテクチャではデータベースが変わりやすい(変えやすい)ものとして定義されているのが大きな違いだと考えます。3層アーキテクチャの考え方は根強く、私自身も「データベースが変わりやすい」という定義に違和感を覚えていました。しかしデータベースを変えやすいもの、ただのIOデバイスの一つとして定義し、依存関係を明確にさせることで、IOに関する拡張が容易にでき、かつテストもしやすくなるため参考にするべき考え方であると感じました。

余談ですが、講演の中でMartin氏がニヤリとしながら次のように述べていたのが印象にあります。

「データベースはソフトウェアの全ての中心にあり、アプリケーションはデータベースを中心として周囲に構成されている」と言い出した人は誰でしょうか?私は知っています。データベースのベンダーです。

よいアーキテクチャは重要な決定を先送りできる(A good architecture allows major decisions to be deferred)

今回のイベントでMartin氏が最も伝えたかったことは、よいアーキテクチャは重要な決定を先送りできるということだと思います。ビジネスとしてやりたいことが決まっていないことは少ないハズで、*5 そのビジネスロジックを真っ先に実装して動かしながら、例えばデータベースに保存する実装やUIのアニメーション等、重要ではない部分の設計を先送りできるように作ることで、将来的な要件の変更等に柔軟に対応できるとMartin氏は説明していました。

Martin氏は具体例として、「FitNesse」というWikiの開発における同僚との会話を上げて紹介していました。*6

「最初にデータベースを決めよう mysqlかな?」


「まだ決めなくてもいいんじゃないか?例えばマークアップ言語をHTMLに変換する部分など、他にやるべきことがあるのでは?」


「やったのでそろそろデータベースを決めよう」


「まだ決めなくてもいいのでは?ハッシュテーブルにページデータを持つことで開発は進められる」


「そろそろデータを永続化したくなってきたのでデータベースを決めよう」


「ファイルシステムにデータをダンプすることで永続化する仕組みができた!」

というやり取りを経て最終的には、データベースを利用しないフラットファイルで保存する形式が採用されたというケースです。

このケースを元に、データベースを先に決めていた場合はよりよいオプションを選択できていなかった可能性があるとMartin氏は述べており、ソフトウェアのアーキテクチャによって取れる戦略の幅が変わる、すなわちよいアーキテクチャであるほど重要な決定を遅らせることが可能となる、と結論づけていました。

個人的にも、クリーンアーキテクチャのよい部分が変更に強いという点だと感じています。AWSやGCP、Azureに代表されるクラウドベンダーは顧客を取り込むべく様々なマネージドサービスを提供しています。クラウドのマネージドサービスを利用するのは便利である反面、そのサービスが廃止されたときのことを常に頭に入れなければならないと感じています。そのような時にクラウドサービスを「詳細」としてビジネスロジックから切り離しておく設計がなされていれば、サービスが無くなる時が来ても慌てずに対処できるようになるため、マネージドサービスを積極に取りいていくことへのリスクが下げられるのでは無いでしょうか。

クリーンアーキテクチャとは

最後にMartin氏の講演をまとめてクリーンアーキテクチャについての私の考察で終わろうと思います。
クリーンアーキテクチャといえばこの図が有名で、この図の通り実装するにはどうすればいいかという観点で悩むことも多いかもしれません。私もその一人でした。

f:id:kiyonori-matsumoto:20210210152151p:plain
The clean architecture (https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html より引用)

今回の講演をまとめると、以下のようにアーキテクチャを実装するとよいソフトウェアが出来上がり、あの図はそれを1枚の絵で示したに過ぎない、ということでしょう。

  • 「方針」が「詳細」に依存してはいけない
  • ビジネスロジック以外は全て「詳細」である
  • 依存する「詳細」が少なければ少ないほど、重要な決定を先送りできる

上記考え方をソフトウェアの実装に落とし込むためのツールとしてクリーンアーキテクチャが存在し、依存性の注入を利用することで依存関係を「詳細」から「方針」に限定できるということだと考えます。

更に、Martin氏は講演の中でテスタビリティについても言及されており、クリーンアーキテクチャで実装を行うことでテスト時に依存性を注入できるため、モックによるテストが簡単にできるという利点も十分にあると感じました。

終わりに

今回はクリーンアーキテクチャのイベントレポートと言う形で、私が印象に残ったことを中心に執筆させていただきました。
今回のイベントでは質問も多く、1時間という短い時間でしたがTwitterなどを見ていてもとても盛り上がったイベントだったのではと思います。
QAコーナーのレポートは、同じDSOCのメンバーによる別記事で紹介する予定です。

また来週2/22(月)〜1週間の期間限定で本イベントのアーカイブ動画をBuilders Boxの会員サイト上で閲覧できるそうです。こちらのWebサイトよりご登録の上、ぜひMartin氏の生の声をお聞きください。

*1:その当時はPythonで実装していました

*2:有名なクリーンアーキテクチャの絵で言うところのUsecase

*3: Geek Seek で買いました jp.corp-sansan.com

*4:SSDはSSDの制約があるので、簡単に書くだけというわけには行かないとは感じています

*5:時々そういうプロジェクトもあるかもしれませんが

*6:http://fitnesse.org/FrontPage

© Sansan, Inc.