Railsで学ぶSOLID(5)依存関係逆転の原則(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。原著者の許諾を得て翻訳・公開いたします。「SOLIDの原則シリーズ」へようこそ。このシリーズ記事では、SOLIDの原則をひとつずつ詳しく説明し、分析します。シリーズの最後にはいくつかのヒントや考察を含む総括記事をお送りしますのでどうぞご期待ください。それでは始めましょう。「SOLIDの原則」とはそもそも何なのでしょうか?SOLIDとは、オブジェクト指向プログラミング設計における一般的な原則であり、ソフトウェアをより理解しやすくし、拡張性やメンテナンス性やテストのしやすさを向上させることを目的としています。Principle)(本記事)今回は、5番目の「依存関係逆転の原則」を見ていきましょう。依存関係逆転の原則(DIP)この原則は2文からなります。高レベルのモジュールは低レベルのモジュールに依存すべきではない。両者とも抽象に依存すべきである。抽象は(実装の)詳細に依存すべきではない。逆に詳細は抽象に依存すべきである。この原則については、素直に例で考えるのがベストだと思います。以下のコードは、DIP違反の例です(Gist[solid-5-violation.rb))。endendこのコードのどこがまずいのでしょうか?まず、ReportGenaratorManageという高レベルのクラスと、XmlReportGeneratorという低レベルのクラスが癒着しています。次に、別の種類のレポートジェネレータを追加する必要が生じた場合に、高レベルのクラスの修正も要求されます。低レベルのクラスが変更されることで高レベルのクラスまで修正を余儀なくされるということです。ここでは、依存関係を逆転させるのが正解です。詳細は、個別の実装にではなく抽象に依存させます。Rubyは動的型付け言語なので、ダックタイピングの手法を使えます。Ruby世界には「抽象クラス」も「抽象インターフェイス」もないので、そうしたものを作成する必要はありません。Injection)パターンを使って実現する方法もありますが、その場合1つ注意しなければならない点があります。DIDIは、単に依存関係逆転の原則を満たすのに使えるテクニックであり、原則そのものではありません(Gist)。endend上のコードでは、特定のジェネレータクラスをこのマネージャにコンストラクタ経由で注入できるようになりました(かつデフォルトのジェネレータも提供しています)。これで、この高レベルクラスの操作は、具体的なジェネレータクラスすべてに共通する一般的なインターフェイスでのみ行われるようになります。実装クラスの差し替えは簡単です(ReportGeneratorManagerクラスを別の場所にある異なる実装で使うなど)。上述のソリューションは柔軟性が遥かに高まり、テストもずっと容易になります。単体テスト上述のソリューションでの単体テストは、簡単かつ快適です。依存をコンストラクタで注入するようになっているので、doubleへの依存を作成して実物の代わりに注入するのも簡単です(Gist)。次のようなことをする必要はありません。ClassToMock.new.stub(:method_to_stub)この方法は一部で「ダメなテスト」と呼ばれています。これは、まさに単体テストの主要な目的です。一切の依存性を考慮する必要のない、独立した単独のユニットをテストすることです。上のソリューションを使うことで、この目的を容易に達成できます。ここからさらに一歩進めると、クラスの依存性をモック化しづらい場合、融通の利かない依存性がそこに頑固にこびりついていると言えます。これに限らず、テストを書くことで「コードの臭い」を見つけたり、何かが複雑になりすぎていることがわかるようになります。Injection)」を混ぜこぜにしないようにすべきです。前述の2つと紛らわしい用語がもうひとつあります。Control)」と呼ばれているものです。Wildという良記事のリンクをご紹介するにとどめます。その要点が1行にまとまったものを以下に引用します。Fowler全シリーズのまとめこれまでのシリーズのどこかで申し上げたように、これらの原則(に限らずあらゆるパターン)は、そこにメリットがあるから適用するのであり、「プロならそうする」とばかりに単純に適用するものではありません。目に見えるはっきりしたメリットがなければ、時間の無駄でしかありません。原則を満たすだけのためにルールなりパターンなりを適用すると、ほとんどの場合さまざまな問題を誘発し、コードベースが手に負えないほど複雑になるという無残な結果に終わります。これらの原則は皆さんを手助けする(コードを改善する)ために書かれたものであることを肝に銘じ、必要以上にコードを複雑にしないよう心がけましょう。銀の弾丸はないのです。あらゆる作業において常識を働かせましょう。これらの原則の本来の意図を常に思い出し、よいガイダンスとして扱うことです。最後に率直に申し上げておきたいことがあります。さまざまな規則、原則、パターンをすべて読みとおすだけでその日から完璧なコードが書ける、ということはありえません。コードの改善は終わりのないプロセスであり、必要なのはコードを書いて書いて書きまくることです。コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。enno.jpを運営。実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。