「安定したシステム」をPHPで作るために 第02回 17年11月 / 最終更新:2017.11.20

前回のお話からの続きになりますが。
Webアプリケーション(に限らないと思うのですが)を運営していると、どうしても「プログラムに修正を入れたい」ような事柄に出会う事が、低頻度とは言えない程度の頻度で発生するかと思います。
それはたとえば前回に書いたあたりですと「実はセキュリティ上問題がある状況が発覚した」であったり、或いはそれ以外に「現在の機能を修正したい」や「新規機能を追加したい」であったり、「性能的に改良が必要」であったり。
或いはごくまれには「法律上、対応をしなければならなくなった(例:法改正)」といった状況もあるか、と思います。
そうして、そういった時にどうするのか、というお話が今回の発端となります。
もちろん経営レイヤーとしては「プログラムに修正を加えろ」となるのですが、現場レベルで考えますと、コードの状態によって「気軽に作業が出来るもの」から「奇跡に近い何かを祈りながら作業をするか」まで、幾分のグラデーションがあるように見受けられます。

ちなみに。
個人的にですが、後者のような「修正が難しい」コードを、時々「ジェンガのようだ」と呼称します。
ジェンガのようなコードは、「初めの頃はそれでもまだ修正が可能」なのですが、場当たりな修正を繰り返していくうちに「どうやっても崩れ落ちる」ような状態に悪化していくのが、大変にジェンガと似通っているように思われます。
そういった「触るのがためらわれるようなコード」ですと、それが傍目には「ちょっとした修正であるように思われる」変更においてでさえ「拒否する」「法外ともいえるコスト(時間や費用)を要求してくる」といった状況が発生し、現場層と経営層の間で、大きな齟齬と乖離を生む原因になるのではないか、と思われます。

ちなみに、ジェンガをご存じない方は、是非一度ネットで調べてみてください。
ゲームとしては大変に「楽しい」ゲームですので。

さて、お話を戻しまして。
プログラムは、完成時に「どのような品質やクォリティであったか」も大切ではあるのですが。
上述のような「のちに出てくる要望に如何に答えるか/答えられるか」という側面も、ビジネス上大変に重要になります。

一つには「全ての"後から出てくる要望"に応えられるような完全なシステムを組む」という方向性が、理論的には一応あるのですが。
将棋に例えますと「一手目で詰みまで読む事ができますか?」といった類の質問になりますので、端的には「事実上、無理」なお話、になります。

また、別解として「変更しない」という選択肢も、選択肢としては一応存在するのですが。
それは「ビジネスを死に体(レイムダック)にする」のと同意になりますので、選択肢としてはあまり選びうるものでもないか、と思います。
このあたりは、無常、という言葉をかみしめると、大変に味わい深いものがあるかと思います。

さて、上述を踏まえまして。
「変化は不可避」かつ「はじめから"全ての変化を考慮する"も無理」だとすると、では「どのようにシステムを組んだらよいのだろう?」となります。
それが、今回扱う「変更容易性」となります。
変更容易性は、RASISの中のServiceability(保守性)に相当する概念になるか、と思います。
ただ、変更容易性によって「セキュリティ上の問題が速やかに解決できる」場合、合わせてSecurity(機密性)にも絡んできますので、相応に重要な考え方なのではないか、と思います。

では「どのようにして変更容易性を持ったプログラムにするか」或いは「どのようにして変更容易性を持ったプログラムであるかを判断するか」ですが。
これは、なかなかに難しい問題ではあります。
しかし、それでもいくつか指針になりうるものはありますので。
まず今回は、些か簡単に、その指針についてお話をさせていただきたい、と思います。

一つには、些か古典に近いものですが「循環的複雑度」という概念があります。
ものすごく端的に要約しますと「プログラムがどれくらい複雑な構造をしているか?」を計測する指針のようなものになります。
基本的に、人間は「簡単なものは(ケアレスミスを除いて)比較的問題を起こしにくく、問題が起きても対処しやすい」「複雑なものは、比較的問題が起こりやすく、起きた問題に対して対処しにくい」ものですので、こういった指針が、ある程度ですが有益になります。
大抵のプログラム言語には循環的複雑度を計測する方法があり、PHPにも存在しますので。
一つの「参考的指針」として、数値が出せるのは、便利なシーンも多いかと思います。「参考程度」ではあるのですが、「何もない状況」というのは些か不安を生むものか、と思いますので。

また、こちらは計測が些か難しい指針になるのですが。
端的には「変数や処理のスコープが狭ければ変更容易性が高い可能性があり」「変数や処理のスコープが広ければ変更容易性が高い可能性がある」もの、になります。
幾分具体的には。
「ソースコードがすべてグローバルに書かれていて、変数もすべてglobal」であればスコープが広いために(特に大規模なプログラムだと)変更が困難になりやすく。
「全体的に"責務単位等で"クラスに適切に分かれていて、クラスがそれぞれ疎結合になっていれば」個々のスコープが狭いため、大規模なプログラムであっても変更が容易になりやすい、可能性が高まります。

このあたりの確認の間接的な一端としては「ユニットテストがある程度記述されているか」という判断指針が役に立ちます。
ユニットテストも「度を過ぎて書きすぎる」と「ユニットテストコード自体のメンテナンスでコストが食われる」ので本末転倒ですが、「ユニットテストを記述できない程度に密結合」な状態は、どうしても「ジェンガなコード」に近しくなる可能性が増してきます。
また「修正した後、確認が可能なテストコードがしっかり書かれている」と、「変更して問題が起きた時に速やかに気づける」ので、変更に対する心理的ハードル等が下がる事から、結果的に「変更容易性」が担保されやすい、と考えられます。

「ソースコードが適切にバージョン管理されている」「デプロイが簡単(自動化されている)」といった状況も、間接的にですが、変更容易性にかかわる事象であるように思われます。

さて。上述から、1例を取り出して少し突っ込んで言及をしてみましょう。
次回は「大量アクセス」について、今回の「変更容易性」を踏まえつつ、考えてみたいと思います。