エンタープライズアプリケーションアーキテクチャパターンを読む: 1.概要

morimorihoge です。
いつのまにか12月ということで、今年も弊社BPSのアドベントカレンダーをやることにしました。普段あまり記事を書かないメンバも表に出るきっかけになると良いと思います(僕自身ももっと書かねば)。

突然ですが、社内勉強会で エンタープライズアプリケーションアーキテクチャパターン を何回かに分けて解説することにしました。
この本は以前から積み本リストとして翔泳社Kindle投げ売りセールの時に買ってあったのですが、今ひとつAmazonレビューが奮わない感じだったので後回しになっていた本の一つです。

しかし、いざ読み始めてみると内容はとても良いもので、これは業務Webアプリを書いている職業エンジニアにはとてもとてもためになりそうな内容でした。
いくつかの理由(後述します)から、この書籍は一人で読んで理解するのは難しいため、本を買って配るよりは勉強会の中で案件事例などを取り上げながら説明するのが良いな、と思った次第です。

※流石に具体的な案件やソースコードに関する部分はNDAの都合上TechRachoでは公開できませんのでご了承下さい

TechRachoでは勉強会の内容から要点をピックアップして解説していこうと思います。勉強会スライドも本記事末尾に公開しておきますが、スライドだけだとそこまで深い具体的な内容は見えてこないと思います。

本書について

著者はMartin Fowler 氏で、ソフトウェアアーキテクチャ関連の大家です。
最近はマイクロサービスのアーキテクチャなんかにも言及していたりするので、Web開発界隈の人であれば一度は著書や記事を読んだことがあるのではないでしょうか。
本書はPatterns of Enterprise Application Architecture として2002年に発表された書籍の日本語訳版で、2005年に発売されています。

本書の問題点とそれを克服する読み方について

本書はAmazonレビューで「内容は良いが翻訳が駄目」と酷評されており、それが低いレビュー評価の原因になっています。
この点については実際に内容を読んだ僕も否定しません。どのような問題があるかというと、

  • 抽象的なカタカナ語が多く、訳さなくても良い語を訳してしまっていたりするケースがある
  • 意味が通らないレベルの誤訳がそこそこある
    • ※翔泳社HPにて本書の正誤表が出ていますが、こんなレベルではないです。

という感じです。Amazonレビューでは「はじめから原著を読んだ方が良い」という話も出ていますが、流石に560ページの原著を全て英語で読むのは骨が折れます。
ボロクソに酷評されている翻訳版ですが、文章単位レベルでできるだけ原著に忠実に翻訳しようとしているという良い点があります。そのため、誤訳が疑われる文を見つけたら原著の当該文を見つけてそちらを参照するという読み方で読めます。
本当にひどい翻訳本は訳者が意訳してしまって意味が変わってしまっているようなものもありますが、本書はそこまでは行っていません。

というわけで、基本的には日本語で読みつつ、おかしいと思った部分や重要な部分は原著と照らし合わせて読むのをオススメします。
Kindleアプリは2つの書籍を同時に開けませんが、Kindle Cloud Reader は対応書籍であればブラウザで見られるので、以下スクリーンショットのような感じで読んでいきます(左がChrome、右がKindleアプリ)。

英語を読むのが苦でない人は原著を直接読めば良いのですが、分からない単語を調べたり、英文の内容をそのまま頭に入れられないので脳内で和訳する必要があるレベルの英語力の人であれば、完全ではないとはいえ翻訳版があるのは読む速度アップに役に立ちます。

そんなわけで、2冊合わせるとKindle版ですら1万円近くになってしまいますが、大学図書館や会社のお金で本が買える方はぜひ検討してみると良いと思います。

対象読者

プログラミング・ソフトウェア開発初心者向けの本ではないので、ある程度業務アプリケーション開発の経験がある、できればアーキテクチャレベルでの設計の経験があると響くところが多くなります。
また、昨今のWebアプリケーションはRailsをはじめフレームワークを使った開発が主流ですが、フレームワークの内部設計や中の仕組みを学習したことがなく、単に利用者としてのみWebアプリケーションフレームワークを使っているだけの人にはよく分からない部分が多いかもしれません。

本書で紹介されているパターンのいくつかはWebアプリケーションフレームワークの提供する機能として既に無意識に使っているものがありますので、そういった点ではフレームワークの内部設計思想を追いかける助けにもなるのではないかと思います。
僕のようにフレームワーク黎明期の経験者でオレオレフレームワークを作ったことのある人なんかは「あー、やったやった!これ実装したわ!」といった気づきを得られると思います。

本書を学習することのメリット

一つはGoFのデザインパターンなんかもそうですが、普段開発していてよくある問題とその解決方法に対して一意性のある名前がつけられることでしょう。
アプリケーションのアーキテクチャ設計をしているタイミングでは、色々な言葉や図(UMLなど)を尽くして議論するかと思いますが、色々頑張ってもいまいち伝わり切れているか不安に思うことがあります。
そんなときにパターン名を使って議論することで、少なくともエンジニア間では間違いなく設計面の議論を進めることができるでしょう。

もう一つは問題を解決するときの選択肢を増やせるという点になると思います。開発初期の設計段階でのアーキテクチャ決定は重要なディレクションですが、それが正解だったかどうかはプロジェクトが進んでみないと分からない要素もあるため「他にもっと良いやり方があるかも・・・」と不安になりがちです。
そんなとき、本書の各アーキテクチャパターンの索引を引くことで、同じような問題を解決するときの他の選択肢と比較することができるようになります。
「Aというやり方が良いか?」という議論は結論を出すのが難しいですが「AとBのやり方のどちらが良いか?」という形になることで、よりメリットデメリットを含めた議論がしやすくなるという点で、とても有用でしょう。

ただ、本書の中でMartin氏も書いていますが、ソフトウェアの世界は常に進化しているので本書に挙げられたパターンがアーキテクチャパターンの全てではありません。
例えば今ならマイクロサービスアーキテクチャもエンタープライズ用途の選択肢として充分にあり得ると思いますが、本書の時代ではまだマイクロサービスという言葉はありませんでした。

本書はあくまで自分の中にある問題解決パターンの辞書を広げるという感覚に留めるのが良いと思います。

※以降は本書における「まえがき」部分の解説を僕なりに解釈した抜粋になります。僕の解釈が入っているので正しく参照したい場合は原著を参照して下さい 🙇 。

本書における「エンタープライズアプリケーション」とは?

「エンタープライズアプリケーション」と言うとJ2EEとかで作られたとても大規模なシステムを想像してしまうのですが、本書では

  • 複雑なデータ(単純な数値計算などではなく、RDBMSなら複数のテーブルなど)を扱う
  • 論理的とは限らないビジネスルールを扱う

という形で定義しています。具体的には給与計算・診療記録・出荷管理・コスト分析・信用調査・保険・会計・顧客サービス・外国為替取引などとされています
一方、エンタープライズアプリケーションではない例としては、装置制御プログラムやワープロ、OS、コンパイラやゲームが挙げられています。

そのため、システムの規模に関係なくビジネスルールやプロセスのような複雑なものを取り扱うものはエンタープライズアプリケーションとして、本書の興味範囲となります。

アーキテクチャの選択について

エンタープライズアプリケーションには様々な種類があり、その内容によって適切なアーキテクチャは都度異なります。
例えば、B2Bの小売りシステムとリース契約処理のシステムを考えたとき「もの(契約含む)を売る」という点では同じような問題を解決するように見えますが、

  • B2B小売りシステム
    • ユーザー数が膨大に増えてもなんとかできるようにするための拡張性が必要
    • 顧客は必ず用意したカートシステムから決められた支払い方法で購入するので、アプリケーションドメインのロジックは単純
  • リース契約処理システム
    • 対法人とするならば、ユーザー数は数百も想定すれば充分過ぎるくらいなので、その点での拡張性は不要
    • アプリケーションロジックはとても複雑。月々のリース料計算と請求、期限前返品時の処理、予約時の与信チェックなどなど

と、実際にアプリケーションを作ろうと思うと問題になりそうな点が全然違うことが分かります。

そのため、あるアプリケーションでうまくいったアーキテクチャを他のアプリケーションに応用してもうまくメリットが得られないことが多々あります
それではリソースがもったいないので、といった思いで使い回ししやすいようにしようとして システムに柔軟性を加えても、柔軟性を持たせるために追加された複雑性によって実際には将来的にシステムを進化させることが難しくなるという問題に直面します。

そんなわけで、エンタープライズアプリケーションにおいては全ての例にマッチするただ一つの最高のアーキテクチャというものは存在せず、アーキテクチャの選択時にはそれぞれのシステム固有の問題を理解した上で適切な設計を選択しないといけないということになります。

記事著者注:「どこかで作ったものをそのまま横展開」というのはそんなに簡単じゃないですよ、という話ですね。身に染みます。

パフォーマンスに関する考え

パフォーマンス問題というのは本来実際に動かして計測を行い、チューニングを行っていくことで最適化することが望ましい一方で、アーキテクチャの決定に起因するパフォーマンス問題というものも確かに存在し、そういったケースは後からの最適化ではどうにもならないという問題があります。
ただ、アーキテクチャ選定時にパフォーマンスを理由に採用・不採用を決めたが、実際に作ってみたら選定時に気にしていたような問題は考慮不要だった、というケースもよくあります。
そうした事情から、本書ではレスポンス時間といった内容も取り扱いはするが、パフォーマンス一般に関する銀の弾丸的なアドバイスはしない方針とのことです。

ただ、拡張性(本書での「拡張性」とは主にハードウェアの水平・垂直拡張により全体の処理量が向上するかの意味で使われる)はエンタープライズアプリケーションにおいては容量(capacity)や効率性(efficiency)より重視されることが多いです。
なぜなら、拡張性が確保されていればソフトウェアを改修するよりもハードウェアを拡張してしまった方が時間・コスト的に安上がりであることが多いためです。

記事著者注:この本は2002年の本ですが、それから15年経った今のクラウド全盛を見ていると、まさにこの方向に向かっていますね。

パターン

パターンとは「繰り返し発生する一つ以上の問題に対して、共通かつ効果的に対処するもの」。もともとは建築系の用語だそうです。
パターンは新しく発明するものではなくすでにある中から発見するものであるので、現実にある人の行動や物事の動きを注意深く観察することがパターンを発見・適用可能性を検討するのに必要になります。このプロセスは難しい作業ですが、パターンを見つけることはとても有用なので重要です。

各パターンについては

  • どんなパターンがあって
  • どんな問題を解決して
  • どうやって問題を解決するのか

さえ把握していれば、それぞれのパターンの詳細については全てを細かく覚える必要はなく、それこそ必要になったら本書を開いて読み込めば良いです。

また、観察対象の中にパターンを見つけても闇雲にパターンを適用するのはうまく行きません。パターンそのものはあくまで「生焼け(half baked)」であり、適用する際には自分のプロジェクトに合わせて焼き上げる必要があります。

記事著者注: この辺はGoFのデザインパターンなんかにも言える話ですね。覚えたての時は無理矢理パターンを使ってみたくなりますが、後になってあれはやり過ぎたと反省する奴です。

社内勉強会スライド

まとめ

本記事では書籍:エンタプライズアプリケーションアーキテクチャパターンの勉強会第一回ということで、本書の読み方や概要と「はじめに」部分についての解説を行いました。
社内勉強会は毎週開催しているので、なんとかそれに合わせてTechRachoでも記事を公開していけるようにしようと思います。

内容についてのご意見・間違いの指摘などありましたらはてブコメントやTwitter(@morimorihoge)等で連絡頂けますと幸いです。

ではでは、今年も弊社BPSのアドベントカレンダーをお楽しみ下さい!

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

morimorihoge

高校卒業後,学生をやりながらずっとWebアプリ開発に携わってきました.2010くらいまではPHP/Symfonyプログラマでしたが,それ以降のWeb開発はRailsほぼ一本に宗旨替えしました.開発とは別にサーバ構築・運用も10年以上やってきているので,要件定義から設計・実装・環境構築・運用まで一通り何でもこなせます.開発以外では季節により大学でWebサービス開発やプログラミング関連の非常勤講師もしており,技術の啓蒙・教育にも積極的に関わっています.最近はPM的な仕事が増えていますが,現役開発者としていつでも動ける程度にはコードもサーバも弄る日々を送っています.AWS 認定ソリューションアーキテクト – アソシエイトレベル取りました

morimorihogeの書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ