「設計とは何か」についてちょっと時間をかけて考えてみた

# この記事はなに？
「設計」という言葉について、概念的に自分の中で安心感を覚えるために行った調べ物と思考プロセスを記した記事です。

ソフトウェアエンジニアをやっていると、「設計」という言葉と無関係ではいられません。
私も例に漏れることなく、ほぼ毎日この言葉にふれながら業務にあたっています。

しかしながら、「設計」という言葉に対して何かぼんやりというか、不安定な感じを覚えるというか、そういった感情がつきまとっていました。
基本設計やら外部設計やら概要設計やらといった言葉が飛び交い、人それぞれが「設計」の捉え方も違う。
自分が普段行っている活動は「設計」なのかどうなのかも怪しい。

こうした状態の中、「設計」という言葉を咀嚼し、腑に落ちるような形で他の言葉で置き換えたい、と思った次第です。

# 偉人たちは「設計」についてなんと言っているか？
設計に対する不安感を取り除くために、知の巨匠たちは設計とは何であると言っているかを調べてみました。
そうすると、一番初めにたどり着いたのがスティーブ・ジョブズの以下の言葉です。

>Design is not just what it looks like and feels like. Design is how it works.
>
>デザインとは、単なる視覚や感覚のことではない。デザインとは、どう機能させるかだ。

ほぼ同じ意味でこうも言っていました。

>Design is a funny word. Some people think design means how it looks. But of course, if you dig deeper, it’s really how it works.
>
>デザインとは面白い言葉だ。デザインは「物がどのような形に見えるか」ということだと思うひとがいるが、しかし、深く掘りさげると、デザインとは「物がどのように機能するか」という意味になる。

ジョブズ以外の偉人が「設計」に対してどのように言っているかも調べたのですが、「設計はこのようにすべきだ」というものが多く、「設計とは」という部分を説明しているものは見つけられませんでした。
もしよろしければ、コメントにてお教えいただければと思います。

# 辞書は「設計」を何と説明しているか？
[こちら](http://english.cheerup.jp/eedict/)の英英辞書サイトで調べてみました。
すると、いくつかの定義がある中で、次の3つの定義がIT業界で使われる「設計」のヒントになるように思われました。

> ５. an arrangement scheme
> 配置の計画

> ６. something intended as a guide for making something else
> 何か他の物を作るためのガイドとして意図された何か

> ７. an anticipated outcome that is intended or that guides your planned actions
> 意図している、または計画した行動を導く、予期された結果

また、これらの中で気になった「scheme」も調べてみると、次のように説明されていました。

> ５. a group of independent but interrelated elements comprising a unified whole
統一された全体を構成する、個々に独立しているが互いに関係を持っている要素のグループ

これらを組み合わせてみると、意訳も混ざってしまいますが、次のようになるのではないかと思います。

設計とは、
①独立しながらも互いに関係を持っている要素のグループを配置するものであり、
②作る際のガイドとなるものであり、
③期待した振る舞いを導くものである。
④そしてそれは（偶然の産物ではなく）意図して生み出されたものである。

言い回しを変えると、
①設計は、独立しながらも互いに関係を持っている要素のグループを配置するものである。
②設計は、作る際のガイドとなるものである。
③設計は、期待した振る舞いを導くものである。
④設計は、（偶然の産物ではなく）意図して生み出されたものである。

ということになりそうです。

④の意味を料理のレシピに当てはめてみると、食材や調味料の投入順は、あみだくじ等でランダムに決められたものではなく、帰納法やら演繹法やらなんでもいいので、「この順番ならうまくいく」というある一定の根拠や意図がなければ、それは設計とは呼べないということになります。

また、先のジョブズの提示した設計の定義は、①と③の定義に関係がありそうです。

# これらを踏まえた上で設計の定義はどうなる？
ジョブズの設計の定義、辞書での設計の定義、そしてソフトウェアエンジニアとして活動している私の知識と経験から、ソフトウェア業界における「設計」を以下のように私は言語化しました。

「設計（Design）とは、ある規則（Rule, Pattern, Principle）に基づいて、対象（Object）の複雑性を理解しやすい部品（Component）に分解し、部品ごとに最適な解決策（Solution）を選択して、全体として動く（Work）ように組み合わせること（Integration）」

この設計の定義は、個人的には非常に納得のいくものになっています。

ソフトウェア業界における設計者は、まずはデザインルール、デザインパターン、設計原則について知っておく必要があります。
そして状況に応じた適切な設計規則を選択し、複雑性を理解可能なコンポーネント単位に分解します。
さらに分解したコンポーネントごとに最適なソリューションを当てはめるために、技術要素やライブラリ等の知見も持ち合わせている必要があります。
そうして最後にコンポーネントを集結させて、システム全体として課題を解決できるものになっていることを確認します。

ここでいう「複雑性」とは、システムの複雑性であり、現実世界の複雑性であり、業務の複雑性であり、人間の認知活動の複雑性です。

またそもそもとして、「設計」を行う目的は、拡張性・頑健性・保守性・セキュリティ・モジュール性などが高いソフトウェアを構築することです。
こうしたソフトウェアを構築することは、価値を迅速（agility）かつ安定的（stability）に世に送り出すことにつながります。



この「分解し、部分ごとに検証し、再度組み合わせる」というのは、まさに「科学的手法」に他なりません。

# 最後に
私個人としては、

「設計（Design）とは、ある規則（Rule, Pattern, Principle）に基づいて、対象（Object）の複雑性を理解しやすい部品（Component）に分解し、部品ごとに最適な解決策（Solution）を選択して、全体として動く（Work）ように組み合わせること（Integration）」

という定義に今は非常に納得感を持っています。

しかしながら、あくまでも「私個人は」であり、「今は」です。
これ以上に「設計」をうまく表す言葉が見つかれば、私もそちらに乗り換えます。

したがいまして、もしよろしければ記事をご覧くださったみなさんが「設計」を言語化するとなればどのようになるか、コメントにてお教えいただければと思っております。
ジョブズの項でも記載しましたが、「この人は設計をこのように定義していた」というのも、ぜひご教授ください。

「設計」に対する多様な考えが集まれば集まるほど、弁証法でいうところのアウフヘーベンにより、さらなる高みへと進むことができるようになります。
西欧では議論の場で反対の意見がたくさん出てくることは、「議論が割れる」というふうにネガティブに捉えられるものではなく、アウフヘーベンにより高い段階へと進むことのできる「建設的な議論」の証だと捉えられているようです。

# 参考
* [非機能要求とアーキテクチャの関係分析の
事例研究結果のご紹介](https://www.ipa.go.jp/files/000004735.pdf)
* [「悪い設計」の定義について考えたことはあるか](https://qiita.com/little_hand_s/items/868bab9d8dc82ade859e)
* [ソフトウェア設計](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E8%A8%AD%E8%A8%88)
* [設計とは何か](https://qiita.com/netetahito/items/85a022e77cc48e7c3d35)
* [設計とは何だろうか](http://www.mechatroidea.com/design-theory/d001-sekkei.html)
* [大規模Webアプリケーションにおける複雑性とアーキテクチャ設計に関する一考察](https://qiita.com/tmknom/items/be5c4b350f561991f2f5)
* [Webアプリケーションフレームワーク導入時に考慮すべき22の観点](https://qiita.com/tmknom/items/08b69594e32a92bccee5)
* 『エリック・エヴァンスのドメイン駆動設計 ソフトウェアの核心にある複雑さに立ち向かう』
* 『実践ドメイン駆動設計 エリック・エヴァンスが確立した理論を実際の設計に応用する』
* 『Clean Architecture 達人に学ぶソフトウェアの構造と設計』
* 『プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則』