言葉とコード

システム開発における言語的要素の重要性について、書籍を参照しつつ私見を整理する。

導入

世の中には「文系プログラマ」という表現がありますが、私もそのカテゴリに入る人間です。それも文系度はかなり高く、文学部でいわゆる思想史的なことを勉強していたんですね。文系の思想研究とソフトウェア開発との間には、かなり深い溝が横たわっていると思う人が多いですし、私自身も当初はそう思っていたのですが、時間が経つにつれて両者の間には相通じるものが確かにあると考えるようになってきました。それはどちらも本質的には「言葉」を扱うものだということです。特定の処理はどう実現するかよりはむしろ、どう表現するかという問題であるということですね。より正確に言うならば、この実現手段と言語的表現を限りなく近づけることができるパラダイムオブジェクト指向である、ということなのかもしれません。


特定の抽象度からある概念を捉えること。その概念に名前を付けること。ある概念と別の概念との間に関連を見いだすこと。見いだした関連に名前を付けること。レベルの異なる抽象度の間を自由に往復すること。こうしたことはオブジェクト指向的な思考にとっての基礎であると同時に重要な本質でもあるのです。

DDDとユビキタス言語

ソフトウェアにおける複雑さは、実は対象とする領域(ドメイン)自体が持つ複雑さであるということは、Frederic P. Brooks, Jr.氏の「The Mythical Man-Month」をはじめとして、様々な所で言明されてきました。これに対して、この複雑なドメインを表現するモデルを作り、それに基づいて設計を行うべきだという観点から書かれているのが、Eric Evans氏の「Domain-Driven Design」です。この本にはドメインを表現したモデルをソースコードに落とすためのパターンが数多く収録されているため、オブジェクト指向のパターン集の1つとして読むこともできます。しかし、この本から読み取ることができる重要なメッセージはそれだけではありません。「言葉」に注目する場合に重要になってくるのは、ユビキタス言語深化したモデルです。

ユビキタス言語

ドメインを表現するモデルについて、Evans氏は次のように語っています。

A domain model is not a particular diagram; it is the idea that the diagram is intended to convey. It is not just the knowledge in a domain expert's head; it is a regorously organized and selective abstraction of that knowledge. A diagram can represent and communicate a model, as can carefully written code, as can an English sentence.


ドメインモデルは特定の図ではありません。図が伝えようとする観念そのものなのです。ドメインエキスパートの頭の中にあるだけの知識ではなくて、その知識が厳格に組織され、選択的に抽象化されたものなのです。図はモデルを表現することもできますし、それについてコミュニケーションすることもできます。丁寧に書かれたコードがそうであるように、そして英語の文章がそうであるように。
DDD, p.3

そして、重要なことですが、このモデルを織りなすものは「言語」であるとEvans氏は考えています。モデルを構成する言葉をあらゆる場所で使う、それがユビキタス言語("Ubiquitous Language")の考え方です。ユビキタス言語によって、ドメインモデルは特別な地位を与えられることになります。

With a UBIQUITOUS LANGUAGE, the models is not just a design artifact. It becomes integral to everything the developers and domain experts do together. The LANGUAGE carries knowledge in a dynamic form. Discussion in the LANGUAGE brings to life the meaning behind the diagrams and code.


ユビキタス言語によって、モデルは単なる設計成果物ではなく、開発者とドメインエキスパートが協力して行うもの全ての総体となります。この言語は知識をダイナミックな形式で伝えるのであり、この言語で議論することによって、図やコードの背後にある意味に命が吹き込まれるのです。
DDD, p.27

このようにソフトウェアの中核におかれるモデルは、しかし、一度限りのモデリングで完成するものではありません。知識を丁寧に咀嚼する作業を繰り返すことで、徐々に現れてくるものなのです。

深化したモデル

Evans氏はリファクタリングのレベルをいくつかに分けた上で、次のように語ります。

The refactorings that have the greatest impact on the viability of the system are those motivated by new insights into the domain or those that clarify the models expression through the code. This type of refactoring does not in any way replace the refactorings to design patterns or the micro-refactorings, which should proceed continuously. It superimposes another level: refactoring to a deeper model.


システムの存続に最も大きな影響を与えるリファクタリングが、ドメインについての新しい洞察に導かれるものであり、コードを通じてモデルの表現を明確化するものです。このタイプのリファクタリングは、継続的に続けられるようなデザインパターンについてのリファクタリングやより細かいリファクタリングと置き換わるものではありません。これは別の次元に存在するものなのです。これがすなわち、深化したモデルへ向かうリファクタリングです。
DDD, p.189

このようなモデルの深化に対応するためには、当然システムは柔軟に設計されている必要があります。この点についての重要なパターンは、第10章のSupple Designなどで紹介されています。しかし、ここで重視したいのは、このリファクタリングを導くのも「言葉」である点です。ドメインモデルにおいて表現されていない概念を掘り起こすため方法のとして、まず提示されるのが、「言葉に耳を傾けること」です。

Listen to the language the domain experts use. Are there terms that succinctly state something complicated? Are they correcting your word choice (perhaps diplomatically)? Do the puzzled looks on their faces go away when you use particular phase? These are hints of a concept that might benefit the model.


ドメインエキスパートが使う言葉に耳を傾けなさい。何か複雑なものを簡潔に表現している用語はありませんか?あなたが行った用語の選択を(おそらくは遠回しに)修正していませんか?あなたが特定のフレーズを使ったときに、急にすっきりした顔になりませんか? こういったことがモデルにとってプラスになるかもしれない概念を示すヒントなのです。
DDD, p.206


ドメイン駆動設計の中核となるドメインモデルにとって、それを織りなす最も本質的なものが「言葉」であるということは、DDDのメッセージを理解する上で非常に重要な点だと言えます。

小さいメソッドと「名付けること」

業務が対象とする領域について考える際にそこで使われている言葉の重要性を認識しなければならないということは、特にドメイン駆動とは言えないソフトウェア開発においても十分に言えることだと思います。このような言葉の重要性は要件定義の時だけではなく、実装時でも変わりません。DDD自体はドメインモデルをオブジェクト指向パラダイムを用いて実装にまで落とし込むことを目論むものですが、そういうモデル駆動の実装ができない場合であっても、コードの中で言葉は大きな役割を果たします。


クリーンなコードを書くためのプラクティスとしてUncle Bobが示しているものに「関数は1つのことしかやってはいけない」というルールがあります*1。システムは明確に役割を与えられた小さなメソッドによって構成されるべきだということですね。ただし、ここでは同時に次のことを理解しておくべきです。

In order to make sure our functions are doing "one thing," we need to make sure that the statements within our function are all at the same level of abstraction.


関数に「1つのこと」 だけを確実に実行させるためには、関数内のステートメントをすべて同じレベルの抽象度にする必要があります。
Clean Code, p.36

しかし、あるレベルの抽象度を切り取るということは、ある概念を導入すること、つまり名前を与えることに他なりません。こうした小さい概念の集合として作られるソフトウェアが次のような性質を持つのは自然なことです。

Master programmer think of systems as stories to be told rather than programs to be written. They use the facilities of their chosen programming language to construct a much richer and more expressive language that can be used to tell that story.


熟練のプログラマはシステムのことを、書かれるプログラムではなく、語られる物語だと考えます。自分たちが選択したプログラミング言語の機能を使って、その物語を語るのに利用できる、より豊かで表現力のある言語を構築するのです。
Clean Code, p.49

まとめ

"Domain-Driven Design"と"Clean Code"を参照しつつ、ソフトウェア開発において言葉が果たす役割を見てきました。要件のモデリングからコードを書くところまで、言葉は常に中心的な役割を果たしています。普段何気なく行っていること、例えば「プライベートメソッドの中の変数の名前を考える」ということも、ソフトウェアを構成する1つの概念に名前を与えていることになるのです。こうしたことは意識しなければ正常に機能するソフトウェアが作れない、という類いのものではないため、どちらかといえば「こだわり」に属するものとらえられがちです。それでもやはり、こうした言葉、あるいは概念に対する繊細な感性を持ち続けることは、ソフトウェアを開発するうえでとても大切なことだと思うのです。



Domain-Driven Design: Tackling Complexity in the Heart of Software

Domain-Driven Design: Tackling Complexity in the Heart of Software

Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)

Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)

*1:Clean Code, p.35