ちょうぜつ設計概要
ちょうぜつ設計とは、自分の手でプログラムを書かない人たちの思い込みに反して、一見不思議に見えるけれど、普通の現役エンジニアが当たり前に備えている、暗黙的なソフトウェア設計センスの常識のことである。クリーンアーキテクチャとアーキテクチャ実体のメタ関係と構造的に同じになる。
なぜ変更しやすく作るのか
ちょうぜつ設計の目的は変更容易性である。変更が容易なソフトウェアでなければ、反復的な開発に耐えることはできない。
使い捨ての簡単なソフトウェアはウォーターフォールで作ることができる。ウォーターフォールに変更容易性を求めるのは、技術者の自己満足にしかならない。反復的な開発において、以前開発した箇所を調整する、あるいは、運用を続けているサービスを壊さずに機能拡張する、といった目的がなければ、変更容易性は不要である。現代のソフトウェアの主流は当然後者である。
変更容易性は、結果得られる特性でしかない。可読性が寄与することもあれば、疎結合性が寄与することもある。
しかし、可読性を単純に「コードの書き換えやすさ」と同義と考えてしまうと、変更容易性は失われる。気軽にあちこちを書き換えやすくすることは、結果として長期的に正しさを保証し続けることを困難にするためである。安易にあらゆる結合を間接的にするだけのアプローチもまた、変更を困難にする。大きな構造を実際に結合しなければ正しさを確認できないものは、そもそも変更を躊躇させるからである。
ちょうぜつ設計は、安定度分布のバランスを重視する。明確な尺度はない。大域に影響する安定したものを変更する必要がなく、独立性の高い不安定なものを閉じて変更できることが、結果として変更容易性に現れることを評価する。何が安定なのかは、反復的な開発の中で実際に起きた変更のフィードバックを受けて決まる。
設計はプログラミングと同時に得る
ちょうぜつ設計では、事前に考えたアイデアをドキュメント化しない。プログラミングと同時に得られた気づきを物語るコードを書く。コードに結果安定度が得られた場合のみ、そのコンセプトをドキュメント化する。事前に考えた設計は必ず、反復的な開発におけるコーディング中に変わるからである。ドキュメントは本質的に、実在する設計に依存する、不安定な存在である。
ドキュメント化されていない設計をプログラミングと同時に得るには、テスト駆動開発が最適である。テスト駆動開発は、動作をテストする技法ではない。ソフトウェアから重要な部分を分離し、それを他の部分の影響から独立させて、アイデアを洗練させる行為を「支援する」技法である。洗練そのものではなく、支援する技法であることが重要だ。洗練そのものは、ソフトウェアがそれぞれ固有に持つ問題をもっとも理解した、現場のプログラマーが行うことである。
これは誰でもできることではない。能力が高いか低いかという意味ではない。いくら知識が豊富なプログラマーといえど、目の前の問題を真摯に考えている現場のプログラマーの前では、ソフトウェア固有の問題に関しては初心者同然だという意味である。実際に問題をプログラミングした経験のある者だけが、最適な設計を得ることができる。これは、ドメインモデリングに関しても、アーキテクチャに関しても言える。
オブジェクト指向を取り違えない
オブジェクト指向を目的化してはいけない。オブジェクト指向がソフトウェアの本質であると言えるのは、プログラミング言語を開発する場合に限られる。それぞれのプロダクトはそれぞれの本質を持つ。ほとんどのソフトウェアは、オブジェクト指向などの各種パラダイムを、活用できるところに都合よく活用するべきである。不適切なパラダイムを先に選択してはいけない。意思決定の最上位には、つねにそれぞれのソフトウェアがある。
オブジェクト指向 (Smalltalk に憧れた C++ ユーザーが Java で開花させた方法論の方) は、安定度の分布バランスが取れたアーキテクチャを作るのに活用できる。関数型の思想は、中間状態を持たないことで、プログラミングを堅実にしてくれる。それぞれは目的が異なる。
オブジェクト指向を「データが振る舞いを持つプログラミングの記法」と考えるのは誤りである。この考え方は凝集度を低下させる原因になる。
例を示そう。新聞記事データに「購読」と「出版」の両方の振る舞いを持つと何が起こるだろうか。同じスコープの変数を共有する 2 つの振る舞いは、安定している期間と不安定な期間が相反する。変更影響を与えたくない振る舞いにバグを仕込むリスクを抱える。片方の機能拡張を行っているとき、もう片方が壊れていないかにあまり注目されないことは、このリスクを増大させる。
オブジェクト指向を使う目的は、物に喩えて目的を表現することで、ソフトウェア構成を容易に行うためのコンポーネント粒度を発見することにある。つまり「新聞配達」と「記者デスク」の 2 つがオブジェクトになる。分離されたオブジェクトは、別の名前空間に置くことができ、不用意なアクセスによる変更影響の可能性をきわめて低下させる。これはオブジェクト指向の原則 SOLID の最初に登場する「単一責任原則」にあたる。
変更させないことが変更容易性になる
変更影響によるコードの不安定さを取り除く最良の方法は、変更しなくてもよい/変更すべきでない領域を確保することである。それが、不思議なことに、結果としての変更容易性につながる。
SOLID の二番目は「開放閉鎖原則」だ。拡張を受け入れ、同時に、変更を受け入れないという方針である。変更されない領域が明確であればあるほど、他の機能への変更影響を意識する量が減り、目の前にあるひとつの問題とそのための機能拡張に安心して集中できる。つまり変更は容易になる。
ソフトウェアの拡張作業はつねに、より安定したコードに依存する。依存されたものは利用者を不安定にさせてはいけない責任を負うため、変更が困難になる。
(途中は割愛するが) SOLID の最後は「依存性逆転原則」である。各ソフトウェアの事情ごとに、安定と不安定は異なる。安定度の分布をコントロールするには、意図的に依存の向きを逆転させるのだ。これが、ちょうぜつ設計におけるオブジェクト指向のもっとも基本的な価値となる。
ネタです
である調で書くといかついですね。そんなたいそうなことじゃないんですよ。こんなの、現場でしっかりやってるプログラマーにとっては、なんてことはない感覚なんです。ちょうぜつ設計なんて呼び名には何の意味もありません。それはドメイン駆動設計もアジャイル開発もオブジェクト指向も、みんな同じです。腑に落ちてしまえばブランドネームなんてどうでもいいんです。
でも、世の中にはいろんな方法論がバラバラの本に書いてあったり、本によって言ってることが違ったりして、こういう通しの考え方がなかなか腑に落ちない人が多いんじゃないかと思います。この記事で説明したことを、なんとたった 300 ページほどで詳しく理解できる本が、この冬 12/10 に発売されました。順を追って楽しく読める読み物調で、かわいいキャラのマンガも入っていて、オススメの本です。
大事なことを忘れていました! この本は(カラーページの一部を除く)全てのサンプルコードが PHP で書かれています。パーソナルホームページのプログラミング言語だったあの PHP でも、いまやこんな考え方が普通に説明できる時代です。トップエンジニアのたいそうな話は大衆的になり、大衆向けの PHP はそんなニーズにも十分に応えられる言語になっています。むしろ「PHP でも」ではなく、説明に最適な言語として他にありません。
「ちょうぜつ」は、「不思議に見えるけどエンジニアにとっては普通のこと」なのです!!