オペレーティングシステムは、複数のプロセスが1つのCPUを共有できるようにしなければなりません。そのため、割り込みを発生させ、その時のCPUやメモリの状態、つまり「コンテキスト」を、退避したり、復元したりします。これを「コンテキストスイッチ」と言います。これをいかに効率よく行うかは、オペレーティングシステムの腕の見せ所ですが、どうやってもオーバーヘッドは発生してしまいます。
プログラミングにおいても、同じような現象が発生します。
プログラマの頭には、現在取り組んでいる問題に関連するワーキングセットがロードされています。プログラミング中に割り込みを入れてしまうと、いったんこのワーキングセットを廃棄し、別のワーキングセットをロードすることになります。つまり、脳内でコンテキストスイッチが発生してしまうのです。
プログラミングにおける、割り込みによるコンテキストスイッチは、非常に性質の悪い、避けなければならない事象です。なぜなら、プログラマの理想は、プログラミング中に「フロー状態」になっていることだからです。
フロー状態とは、1つのことに没頭し、瞑想のような状態になることです。この状態に入ると、幸福感でいっぱいになり、時間に対する感覚がなくなります。「ついちょっと前、仕事に取り掛かったと思っていたのに、時計を見ると、もう3時間も経っている」というような感覚です。こうなると、プログラミング作業は、とてつもなく効率よく流れていきます。
プログラミングのように高度な知的作業では、「調子に乗る」ことはきわめて大切で、フロー状態は必要不可欠です。フロー状態になって、初めて仕事がうまく運ぶと言っても過言ではありません。
ただし、残念ながら、スイッチを入れたり切ったりするように、自分をフロー状態にすることはできません。フロー状態に入るため、また、それを維持するためには「連続した時間」が必要です。通常、15分以上の精神集中時間が必要です。
この連続した時間の確保を妨げるのが、職場で発生する様々な「割り込み」です。誰かに声をかけられたり、会議があったり、周りで議論が始まったり、電話が鳴ったり、メールの到着通知が表示されたり、職場には様々な割り込みが発生します。
フロー状態に入る過程の時間では、割り込みに非常に敏感です。したがって、騒々しい職場では、フロー状態になることは、ほぼ不可能です。
しかも、ようやくフロー状態になっても、割り込みで簡単に元の状態に戻ってしまいます。元の状態に戻ると、再びフロー状態に入るのにまた15分以上かかります。その間、実質的には、何も仕事をしていないことになります。
例えば、電話の応対に平均5分以上かかり、また仕事に集中するのに15分必要とすると、1回の電話につき、貴重な仕事時間が20分無駄になる計算です。1日に10回も電話がかかってくると、それだけで半日が過ぎてしまいます。さらにもう10回かかってくれば、丸1日つぶれる計算です。
そのため、そのような職場では、「定時内に、何のアウトプットもなかった。残業しよう」という日が大半を占めてきます。「コードは夜にできる」のです。もっとひどいと、「コードは自宅でできる」場合もあります。
また、さらに深刻なのは、仕事を邪魔されてイライラすることです。仕事に集中しようとしても、その度に邪魔されては、楽しいはずがありません。もう少しで仕事に没頭できるというところで、現実に引き戻されます。精神統一して自分の世界に入ろうとしても、重要度の低い割り込みによって、あっけなく失敗します。
このような状況が続くと、誰でも最後は嫌気が差して、職場に見切りを付けてしまいます。日々の作業の生産性への悪影響に加え、人材の流出にもつながりかねません。
しかし、マネジャーからすると、プログラマが精神集中できないでイライラしていても、「それがどうした?」と、あまり問題に感じません。なぜなら、マネジャーというものは、割り込みの連続の中で仕事をしていることが普通だからです。いわば、割り込みの対応が仕事です。プログラマの理想の状態を、なかなか理解できないのも無理ありません。
このような状況にあるなら、職場の意識改革、文化改革が必要です。何においても、プログラマの連続時間を大切に思うことです。そうすれば、自然に、プログラミング時間の確保を前提とした、プロジェクトの運用やタイムスケジュールが決まっていきます。そして、コンテキストスイッチを忌み嫌う文化が醸成されていくはずです。
システムとは、「相互に作用しあう要素(部分)の集まりであって、全体としての機能を持つもの」のことです。
単なる集まりではなく「全体としての機能を持つ集まり」という点が特に重要です。すべては互いにつながっています。物質の世界であれ、社会の仕組みであれ、人間の心の奥底の考えであれ、コンピュータのロジックであれ、すべてが1つの巨大な、相互につながった現実の組織を形作っているのです。
孤立した状態で存在しているものはありません。すべてが組織の一部であり、周囲の状況や文脈、つまりコンテキストの一部分です。
そのために、些細な物事が、意外に大きな影響を及ぼす場合があります。逆に一大事と思われていたことが、結果的にはそれほどの影響を及ぼさずに終わってしまうこともあります。入力に比例した形で出力が得られるとは限らない、「不釣り合いな影響」こそが、非線形なシステムの顕著な特徴です。
現実の世界は明らかに非線形です。なんであれ、単独で取り上げて見ようとしても、宇宙のほかの一切合切に結び付いていることがわかります。
例えば、木は目の前の地面に立っている、独立した1つの物体と見なすこともできます。しかし、実際には少なくとも2つの大きなシステム、つまり、「葉と空気」「根と土」という2つの処理サイクルをつなぐ存在です。不変でもなければ、独立した存在でもありません。
しかも、さらに面白いことに、あるシステムを観察している自分自身も、もはや単なる観察者ではありません。気付いているか否かに関わらず、観察者である自分自身も、そのシステムの一部分なのです。
システム・シンキングとは、物事を考察するにあたり、この「システム」という概念を用いて、対象全体を統一的・包括的に捉える思考法のことです。
システムには境界があり、その内部にある構造や機構から一部の要素を取り出してみても、全体が提供する機能や動作を理解することができません。そこで、システム・シンキングは、対象の全体性を認識するために、個々の構成要素だけではなく、その関連性にも注目します。
ソフトウェアで問題を真に解決するには、解法(アルゴリズム)に関する知識だけでなく、問題に対する正確な知識も必要です。問題を理解するためには、問題そのものだけを見るのではなく、問題を取り巻く領域を、コンテキストとして考察する、システム・シンキングが要請されます。
システム・シンキングの思考法を、ソフトウェア開発に活用するには、「ドメイン駆動設計」が有効です。ドメインとは、ユーザーが知識を持ち、影響を与え、活動する領域のことです。「業務領域」「事業対象」「問題領域」とも呼ばれます。要するに、ソフトウェアがそもそも解決しようとしている関心事を指している、「ソフトウェアのコンテキスト」です。
ドメイン駆動設計は、そのドメインをモデリングした成果である「ドメインモデル」を、ソフトウェア開発の中心に据えます。プログラマとドメインの専門家がチームとなり、「言語」「図」「コード」や、それらを使った「コミュニケーション」を、常に「ドメインモデル」と一体化させながら、「ドメインモデル」を反復的に深化させます。そうすることで、より価値の高いソフトウェアを生み出していこうとする設計思想です。
ソフトウェアがドメインから離れてしまったら、そのソフトウェアは、ドメインの問題を解決することができません。そもそもの存在意義がなくなってしまいます。それを避けるため、ドメインモデルの探求に全力を尽くし、できあがったドメインモデルからすべてを駆動していきます。そうすることで、ドメインを反映した、より価値の高いソフトウェアにすることができます。
ただし、1回きりの開発で完璧なドメインモデルは設計できません。優れたモデルは、何度かのリリースを繰り返す中でようやく得られるものです。その都度、ドメインの知識を深めながら、モデリングを反復して、モデルを深化させていきます。
アリストテレスは、「知識」を「エピステーメ」「テクネ」「フロネシス」の3つに分類しました。
「エピステーメ」は普遍の真理であり、普遍の正当性を持つ知識です。時間・空間によって左右されず、文脈独立的・客観的です。
ざっくり現代用語で言うと、科学(サイエンス)がこれにあたります。
「テクネ」は、実用的な知識やスキルを応用することで、何らかのものを生み出したり、作り出したりするノウハウです。エピステーメとは対照的に、文脈依存的な技術知です。
ざっくり現代用語で言うと、工学(エンジニアリング)がこれにあたります。
「フロネシス」は、エピステーメやテクネとは毛色が異なり、「知的美徳」と言うべきものです。つまり、知識というより、実践的な智慧と言うべきものです。「賢慮」「倫理」「実践的智慧」と言われる場合もあります。
フロネシスは、文脈や状況を考慮し、その都度の個別具体に対応し、プロセスの中で必要に応じて行動目標を変更する智慧です。つまり、それは実践の中から得られる質の高い暗黙知であり、価値や倫理についての思慮分別を持つことにより、時々刻々と変化するその都度の文脈や状況において、全体の善という目的を達成するために「最善の判断と行為」ができる能力です。
ソフトウェアの開発においても、個別具体的な状況の中で、自分たちの能力や価値観に基づき、ユーザーに対して価値を提供しなければなりません。フロネシスを使い、コンテキストを把握し、全体最適化を図る判断能力が必要です。
存在ということをどのように解釈するか、その思想を「存在観」といいます。
存在観について、西洋哲学的には、独立自存する「実体」なるものがまずあって、実体同士の間に、第2次的に「関係」が成立するものと考えられてきました。
これに対して、「関係」こそが第1次的な存在であり、いわゆる実体は「関係の結節」とも言うべきものにすぎない、と考える立場を、「関係主義」と言います。
関係主義は、仏教哲学の「縁起」など、むしろ西洋哲学より古くから存在していました。かつて、存在観については西洋哲学が中心でしたが、現代では関係主義も見直されています。
関係主義は、存在観がその由来ですが、要素と要素の関係性や影響に、しっかりと着目する「考え方」です。各部分を細かく見ることではなく、全体の現象をしっかりと捉えることを重視します。つまり、コンテキスト側に重きを置く思考法です。
この考え方は、プログラミングにおいて、特に、障害対応に役に立ちます。障害が発生した時、エラーが発生した部分のコードを中心に見てしまいがちです。しかし、根本原因は別のところにある場合が、意外に数多くあります。
したがって、コードのみに原因を求めるのではなく、ライブラリとの関係、実行環境との関係など、コンテキストに目を向けなければなりません。1つ1つが正しくても、関係性の部分に誤りがあり、全体として妥当でなくなるのです。
これを念頭に置いておくと、トラブルシュートの引き出しが格段に増えることになります。
出典書籍
『リファクタリング・ウェットウェア―達人プログラマーの思考法と学習法』Andy Hunt, オライリー・ジャパン(2009)
関連書籍
『システム・シンキング入門』西村行功, 日本経済新聞社(2004)
『ニコマコス倫理学』アリストテレス, 京都大学学術出版会(2002)
『入門哲学としての仏教』竹村牧男, 講談社(2009)
『フォーカス・リーディング「1冊10分」のスピードで、10倍の効果を出すいいとこどり読書術』寺田昌嗣, PHP研究所(2008)
『ピープルウエア第3版』トム・デマルコ他, 日経BP社(2013)
『エリック・エヴァンスのドメイン駆動設計』エリック・エヴァンス, 翔泳社(2011)
『プログラマが知るべき97のこと』和田卓人他, オライリー・ジャパン(2010)
プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則
上田勲著
秀和システム 2,200円
一通りプログラミングができるようになった。しかし、読みにくい、遅い、頻繁にエラーが発生する、書いたコードを修正すると動かなくなる等々、なかなか「よいコード」を書けないとお悩みではありませんか? 本書は、よいコードを書く上で指針となる前提・原則・思想、つまり「プリンシプル」を解説するプログラミングスキル改善書です。初心者向けの書籍では絶対に説明しない、古今東西のプログラマーの知恵をこの一冊に凝縮しました!
Copyright © ITmedia, Inc. All Rights Reserved.