Aikの技術日記

技術的な進捗とか成果とかを細々と投稿するブログです。時々雑記も。

Clean Architectureを読んで Part1

はじめに

お久しぶり?です、筆者です。

最近になって、技術書を読みたい熱が再燃してきており…。
中でもこちらの本がとても気になってる次第です。

www.amazon.co.jp

そうです、泣く子も黙る『Clean Architecture』本です。
会社の大先輩や大大先輩から「この本いいぞ〜」と言われ興味はありまくってたのですが…。
いかんせん内容が難しいので…距離を置きがちでいました。

しかし、社会人になって2年目…うん、まだ2年目ですがね。
そろそろ読んでもいい頃合いかなと思い、決心した次第です。

今シリーズでは、Clean Architectureの本自体の感想や、当本に関連深い動画や記事を見てみた感想を書いていければと思います。

ちなみに今回はPart1としてClean Architectureの本…ではなく、こちらの実践動画を見てみた感想や気になるポイントを書いていけたらと。

職場の大先輩からお勧めされたのですが、本よりもより実践的な内容で分かりやすいとのことで…。
「この動画を見て内容が分かるなら、本を読んでみてもいいかもしれない」という判断にも使えるとのこと。

それでは行きましょう!

Clean Architecture…の動画を見て

まずは動画全体の感想から。

Clean Architectureの本を読んでない状態で視聴しても問題ないほど、分かりやすくかつ具体的な説明が多かったです。
もちろん、本を読んでから動画を見てもいいかもしれませんが…。
(筆者の様な)「本読むの怠い〜」ってタイプの方が取っ掛かりで見るには最適かと。

また、この動画作成者さん自身が作成された記事もとても参考になりました。

nrslib.com

こちらは本動画の記事版…というわけではなく、こちらのスライドが起点の記事の様です。

このため、動画で話されていた内容を全網羅された記事ではありませんでしたが…。
動画内容を簡単に復習したいと言う時に、とても参考になるなと思いました。

ちなみに動画自体のクオリティ(テンポ等)については並程度のクオリティです。

YouTubeの生放送のアーカイブ動画なので、YouTube生放送を見慣れた方なら問題無いでしょうが…。
(筆者の様に)例えば1万再生位いってる程のニコニコボイロ実況動画や、カットを多用してサクサク見れる様工夫してくれてる有名YouTuber or Vtuberの方々の動画を見慣れてる場合、動画テンポが悪いなぁと感じやすかったです。
((まぁYouTube生放送とボイロ実況を比べる時点で酷ですがね…

ただ、多少のテンポの悪さなんぞ気にならないくらいには内容が素晴らしい動画だった様に思えます。

ここからは、動画を見ていって「面白い!」と感じた事について小ネタ形式で見ていければ。

小ネタ

Clean Architectureの求める事

動画内で「Clean Architectureのやりたいことは「ヘキサゴナルアーキテクチャ」と一緒」と述べられていた所があり。
当然のことながら「ヘキサゴナルアーキテクチャとはなんだ…?」となったので少し調べてみました。

アプリケーションを、ユーザー、プログラム、自動テストあるいはバッチスクリプトから、同じように駆動できるようにする。
そして、実際のランタイムデバイスとデータベースから隔離して、開発とテストをできるようにする。


イベントが外側の世界からポートに届くと、特定テクノロジーのアダプターが、利用可能な手続き呼び出しか、メッセージにそれを変換して、アプリケーションに渡す。
よろこばしいことに、アプリケーションは、入力デバイスの正体を知らない。
アプリケーションがなにかを送る必要があるとき、それはポートを通じてアダプターに送られて、受信側のテクノロジーが必要とする信号を生む(人力であれ自動であれ)。
アプリケーションは、実際に他方のアダプターの正体を知ることはなしに、全側面のアダプターと意味的に完全なやりとりをする。


参考: ヘキサゴナルアーキテクチャ(Hexagonal architecture翻訳) | blog.tai2.net

ヘキサゴナルアーキテクチャは主に六角形で描かれる、多角形の全辺が外部とのインターフェイスであり、内部にさらにアプリケーションレイヤーやドメインコンテキストといった1つ以上のレイヤーを持つアーキテクチャである。
層構造はレイヤードアーキテクチャと同じであり、要はレイヤードアーキテクチャを最下層を軸に一回転させて全方位に対して層構造の性格が変わらないようにしただけである。


参考: ヘキサゴナルアーキテクチャとレイヤードアーキテクチャの違いとマイクロサービス - falsandtruのメモ帳

…うん、わからない…。
ちなみに動画内説明には…:

「ヘキサゴナルアーキテクチャもClean Architectureも、やりたいのはビジネスロジックと他の処理層を分離する事。
ビジネスロジックを他の層と分離する事で、大規模なリファクタリング(使用フレームワークの変更レベル)や自動テストもできるシステムに近くのだ」

…とありました。ほぇえ…。

ちなみに、似た様なことはゲームプログラミングにも言えるそうです。

会社の大先輩曰く…素人がゲームプログラミングをすると「描画と判定処理を同時に行う」様なプログラムが出来上がるとのこと。
例えば落ちものパズルゲーだと、「このオブジェクトが画面上の○○のラインにまで到達したら、その位置で固定化する」…みたいに。
この様にできているプログラムは、非常に開発がしにくいとのこと…まぁそりゃそうでしょうね。

このため、ゲームプログラミングでも「描画をする機構(View)」と「判定処理をする機構(Model)」、「入力を受け付ける機構(Controller)」に分けるのは非常に重要なことらしいです。
以前筆者が触ってみたゲームエンジンAIMS」では、最初からこのMVCで処理を分けて書く様になってたので気づけませんでしたが…。
1から作るのであれば、その様にするのもいいですねぇ。

ちなみに言わなくてもわかる通り、オニオンアーキテクトとは全く異なるものです。
(JavaJavaScriptくらい違う)
形状がおんなじなので「親戚かな?」と思ったけど違うみたいですね…。

スタブの概念

動画を引き続きみていくと、「スタブ」という用語について述べているシーンが。
筆者的には「スタブってよく聞くけどなんだっけ…」となっていたので、これを機に調べてみました。

スタブ(stub)とは、コンピュータプログラムのモジュールをテストする際、そのモジュールが呼び出す下位モジュールの代わりに用いる代用品のこと。
下位モジュールが未完成でも代わりにスタブを用いることでテストが可能になる。
逆に上位モジュールの代わりに用いる代用品をドライバ(ソフトウェアの場合)またはコントローラ(ハードウェアの場合)と呼ぶ。
ただし、仮のモジュールではなく正規のモジュールについてもドライバまたはコントローラと呼ばれる事があるので、区別するために「テストドライバ」や「サンプルドライバ」などと呼ぶ事も多い。


なお、stubの原義は使い残し、半券、切り株と言った意味である。
参考: スタブ - Wikipedia

これはコードに起こすとわかりやすいでしょうか。
例えば下記の様なシステムをフロントエンド、バックエンドで別れて作る時…:

フロントエンド担当: Aさん
- [View] View/
  - Hoge/
    - index.cshtml <- HogeModel.csで生成されるデータを出力
- [ViewModel] ViewModel/
  - HogeViewModel.cs

バックエンド担当: Bさん
- [Controller] HogeController.cs
- [Model] HogeModel.cs

※DBはすでに構築済みとする
  • index.cshtmlに何を表示するか?
  • UIを作りたいがHogeMode.csからの返却値がないとViewを作れない…

…など、様々な問題が出てきます。

でも例えば、ViewModelを先に定義しておき…。
HogeController.csに仮のデータを返却する「スタブ関数」を作ってしまえば、返却値を返す実装を行うことなく作業の分担ができる様になります。
また、もしデータ登録が必要になる処理であっても、同じ様に入力値となるViewModelを先に定義し、HogeController.csに登録処理の側の処理だけを行う「スタブ関数」を作ってしまえば同様に分業可能です。

そして、このスタブ関数がDIという形で実装されていたら、更にやりやすくなります。
フロントエンドとバックエンドの結合試験は、実装先を変えてあげるだけで環境が整えられます。便利!

動画でも触れられていましたが、開発初期段階だと「とりあえずUIを作るだけ作りたい!」という状況は多発する様で。
((新機能リリース時でも同様のことは起こりますけどね
そういった時に、この様な構造は非常にマッチするとのことです。

これをもっと発展させると、「Production用には実際に動くコードが書かれた処理をDIし、Debug用にはテストデータを返却する処理をDIする」…という考え方になるそうで。
(もちろんこの時、ViewModelの構成は統一化しないといけません)

上記の様にすることで、「DB取得時の実装」の様な、より低レイヤーに近い実装作業を「完全に分離下orアウトソーシング」できる様になるとのこと。
UIに関しては密なやりとりが発生するのもあるので、アウトソーシングはなかなかしにくいですが…。
DB取得時の実装は、仕様書さえあればできるパターンも多いですからね。
この領域をアウトソーシングできるのはとてもメリットがありそうです!

…小ネタについてはここまで、お次は動画内で述べられていた「Clean Architectureのデメリット」について深掘りしたいなと。

Controllerはゲームのコントローラーと一緒だ

動画内でControllerの説明があった際に素敵な説明がありました。
それはControllerはゲームのコントローラーと一緒というもの。

ゲームのコントローラーはゲーム上では「人間の操作(入力)を、システムがわかりやすい様に変換する」ことしか行っていません。
PS4のコントローラーやSwitchのJoy-Conは、ゲームに対し直接処理をするわけではないですよね?
Controller層でも同じことが言えるのです。

Controller層はModel層、View層どちらともつながっている便利な層なので、ついついいろんな処理を書きがちですが…。
「Controllerをゲームのコントローラーと捉えてみる」と、自然と処理を分けて書ける様になるなぁと…。

動画配信主が同じく投稿されている、以下の動画でも同じ様なことを説明されてありました。
こちらの動画もすごくわかりやすくておすすめです|д゚*)つ

Clean Architectureのデメリット

WebAppとの親和性がない

Clean Architectureでは、View層に当たる「Presenter」というものは「値を返さず、画面上に何かを出力するもの」として認識されているそうです。

しかし、Webシステムになると「値を返さず、画面上に何かを出力する」というのをシステムが請け負うことはできません。
Webシステムが最終的に返却するのは「HTTPプロトコルに則ったHTTPレスポンス」であり、画面上に描画を行うのは「ブラウザ」が担う役割だからです。
これにより「Modelの状況により常にViewが更新され続ける」…といった処理は無理になってきます。

Android/iOSアプリだと、これに該当するものとして「Presenter」というものがあるらしいですが…筆者にはピンときませんでした。
(アプリ開発やったことないですしね…)

これに対応するため、MVCをWebに対応させた「MVC2」という用語もあるそうで。
(従来のMVCは「古典的MVC」と呼ぶそうです)

従来のMVCとどう異なるのか…簡潔かつわかりやすい説明があったので引用させていただきます:

一般的なWebアプリケーションの流れで説明すると、
- 「コントローラ」がHTTPリクエストを受け付け、
- 「モデル」がDBからデータをとってきてデータ処理を行い、
- 「ビュー」が「モデル」のデータを元にHTMLへ整形する
ということになります。


参考: MVCをWebに適用した「MVC2」 | Java好き

ちなみに、元々MVCというものは「Smalltalkのウィンドウプログラム開発の設計指針として生まれたもの」だそうで…。
そりゃ今とは考え方違うわってなりそうですな。
※参考: MVC と MVC2 について改めて考えてみる - スタジオ・アルカナ技術ブログ

@inject Hell

Clean Architectureでは、ビジネスロジックを司る「UseCase」層をController層と完全に分離する構成となっています。
ただ、これにより「UseCase層に新しく何かを作るたびに、Controller層をいちいち修正しないといけない」事になっちゃいます…。
(@inject Hellと呼ばれているそうです)

これの対応策として、動画では「injectするのを自動で行わせる機構を作る」というのを提案していました。
人力でやったら絶対に漏れるでしょうからね…単純作業でもありますし、ぴったりかも。

1機能の作成がしんどくなる

Clean Architectureを本気で実践してしまうと、1機能作るだけで下記のコードを生み出さないといけなくなります…:

  • Controller
  • Input Data
  • Input Boundary
  • Use Case Interactor
    • Entities
  • Output Data
  • Output Boundary
  • Presenter
  • View Model

…うん、しんどいですね。

幾つかのコードは自動生成に頼ってできるかもですが…。
使用言語やフレームワークによっては、自動生成にこぎつけるまでに多大な労力がいるものもあるでしょうし。

練習がわりの簡単なTODOアプリ等に使用するアーキテクチャではない様に思えました。
ただ、「今後言語やフレームワークを変更するレベルのスケールが見込める大型プロジェクト」だったり、「今度成長する可能性の高いプロジェクト」であれば利用する価値は大いにあるかと。
分業化もしやすいので、人が大量にアサインされるプロジェクトでも向いてるかもですね。

おわりに

結構長々とまとめちゃいましたね…。
動画1本でここまでの記事を書くとは正直驚きです。
でも、それだけ密度の高い動画だったのかなと…改めて動画投稿主に感謝です(´;ω;`)

おまけとして、記事最後に「動画内容から抜粋した、アーキテクトという役割について」のメモ書きをまとめてみました。
ほぼ自分用のメモですので見るときはご注意を。

次回記事では、Clean Architecture本を実際に読んでみた感想等を書いていければと思います。
今の知識から、どれだけ自分が成長できるか楽しみですね!
それでは|д゚*)

アーキテクトとして ~動画内容から抜粋~

アーキテクトは「様々なデザインパターンから、状況にあった物を選定する」お仕事。
ただ、デザインパターンを丸ごと当て込められる機会はほぼない…。

そういう時は「異なるデザインパターンを組み合わせる」ことが必要となる。
アーキテクトの腕の見せ所となるのだ!

プログラミングを作る時は自由だけど、自由にしちゃうと皆がバラバラな方向に行き、険しい探検の様にもなる。
アーキテクトは、そこに線路を敷いてあげる役割。
線路を敷くことで、探検ではなく快適な旅の様になる。
開発メンバーがいかに快適に旅ができるかをサポートする役目がアーキテクト。

なお、あくまでアーキテクトは使う物であって利益や何かを成し遂げるものを生み出すものではない。
利益を出したり、何かを成し遂げるものはビジネスなのだ。