Murga

個人的に言いたいコト・主張・気持ち。

プログラムはいつまで放置して運用できればいいのか

主に業務システムなんかの開発は、もちろん簡単なことではないので、「一度作ったモノをずっと放置して運用できれば楽だな」と誰もが考えるだろう (業務システムだけでなく、ウェブサービスだったり、ゲームのプログラムなんかもそうかもしれない)。

しかし、やれ Java の EOL が来るだの、新しい Angular は古い Node.js で動かなくなるだの、次のバージョンからは Windows8.1 のサポート止めますだの、周りの様々な環境に左右されて、一度作ったモノを放置しっぱなしにもできない。

そして、こうした基盤周りのバージョンアップに追随するための作業は、ワケの分からないエラーに悩まされ、ただ修正前と同じ動きをさせておきたいだけなのに、かなりの労力がかかる。

せっかく覚えかけてきた RxJS の API も、メジャーバージョンが変わると import の仕方が代わり、コレは廃止されたので代わりにコレを使ってくださいとか、この API は非推奨になりましたとか、設定ファイルをこう変えてくださいとか、よく分からない変更を反映していかないといけない。そうして苦労して修正したプログラムは、当然ながら元と同じ動きをしていることを要求される。あれやこれやと考えて手を動かしたのに、出来上がったモノに対する成果が薄く感じるのだ。利用者から見たら「前のバージョンと同じ挙動でしょ?何が変わったの?どうしてそんなにバージョンアップ対応に金がかかるの?」という感じ。


ならばと、イマドキの流行を追いかけるのは止めて、レガシーでも基盤がしっかりしていて、向こう10年くらいは実行基盤に破壊的な変更が発生しないだろう、というようなプログラミング言語・フレームワークを使ってみたりする。今でも VB が重宝されているのはこういうところだろう。Windows バッチやシェルスクリプトなら、今後も大抵の環境でそのまま動き続けるし、コマンドの挙動がある日突然変更される事態もほぼ考えられないだろう。

枯れた技術は確かに落ち着いているが、やはり枯れているモノ、負債は別のところにある。

1文字分でも情報量を削減したい、大昔に作られたシェルコマンドたちは、初学者にとってはさながら暗号のようだ。一つひとつのコマンドや API の由来を覚えて、理屈を勉強して、歴史的経緯を加味してじっくり読み込んでいけば、読めなくはないし、色々と自由に書けるようになる。

だが、逆にいうと、一つひとつのコマンドや API の由来を覚えて、理屈を勉強して、歴史的経緯を加味してじっくり読み込んでやらないと保守できない言語ともいえる。書いたり読んだりする人間に、事前に知っておいてもらうことを大量に要求するのだ。

プログラミング言語の発展は、これまでの言語にあった不満を解消し、今までより効率的・効果的に物事を成し遂げるための変化だ。それに対して枯れた技術は、時代も思考も止まったままだ。当時の人間と同じだけ勉強し、同じ苦労をさせるのだ。イマドキのライブラリであれば、自動的にセキュリティ対策などもなされていたりするが、シェルコマンドなんかを使う場合はそうした考慮は開発者がしないといけない。いつまで経っても、同じ課題を、どの開発者も、同じように考慮して実装するコストがかかることになる。

一度作ったものは確かに長持ちするかもしれないが、一度作り終えるまでの学習コストが物凄くかかるワケだ。より親切な高級言語が既に存在する中で、そんな不親切で低級な言語を積極的に選びたいな、とも思えない。


しかし、そんな親切な言語やフレームワークは、より親切になろうとするあまり、短期間で急激な変更をアナウンスしがちだ。

かつては「curl した結果をパイプで sed して sort してなんやかんや…」と苦労していた処理も、Angular は HttpModule#get() という API にまとめてくれていて、あぁこりゃ便利〜と思っていたのに、ある日突然「HttpModule は廃止です。代わりに HttpClientModule を使ってください」と云われるのだ。

じゃあ試しにこれらの基盤のバージョンアップに追随しないとどうなるか。シミュレーションしてみよう。

Angular フレームワークのバージョンアップに追随しないでいると、「新しい Angular は今までの Node.js じゃ動きません」と云われるようになり、それも無視していると今度は Node.js 側から「そのバージョンの Node.js はもうサポートしませんからね」と云われる。さすがに OS のバージョンアップは追随するか…と OS をアップデートしたら最後。アップデートした OS で 古い Node.js を引き続き使用しようとすると「このバージョンの Node.js はそんな新しい OS には対応していないよ」とか怒られて、仕方なく Node.js のバージョンを上げると「そんな新しい Node.js じゃこの Angular は動かないよ」なんて云われて、やっぱり Angular のバージョンを上げて自分が実装したコードを書き直すハメになる。

どのライブラリも、大きな混乱を引き起こさないよう、マイグレーションガイドを用意したり、段階的な変更をアナウンスしたりして配慮してはいるが、各ツールが別々のスケジュールを立てていて、追随する側はそれぞれのタイミングを見て考慮しないといけないので、やはり手がかかる。


常に進歩を目指して、急速に変化を続けるツールか、それとも、枯れて安定が見込める代わりに、古臭く覚えることが多い不親切なツールか…。


ところで、言語や実行環境など、ツールのサポート期限を考える前に、自分が作ったシステムの EOL や、変更が入る機会を、もう一度見直さないといけないのではないだろうか。

「大規模なバッチ処理をシェルスクリプトで書いた!シェルスクリプトなら向こう20年そのままでも動くぞ!」それは結構。でも、20年後もそのバッチ処理が、そのコードのまま必要とされているだろうか?

「Java バッチで作ったって?Java なんて今後は半年おきにバージョンアップするんだ、2年も放っておけないようなシステムはコストが掛かって仕方ないぞ!」そうかもしれない。でも、元号改元は来年必ず起こることで、開発言語が何であろうと結局手を入れることになるのでは?

システムの「保守」という言葉の定義というか、そこに割く工数をどう見ているかの違い、というか。

一般的にサポートと呼べるようなサポートがなされていない、枯れた技術、低級な言語の場合、コードで表現した対象の業務自体に変更が入らなければ、確かにそのコードはそのまま放置できる。イマドキのライブラリは、対象の業務が変わっていないのに、ツールだけがバージョンアップしていくので、それに追随するためのマイグレーションのコストはかかる。マイグレーションせずに放置したとしても、あとあとそのツケを払わされる機会がすぐ来る。対象業務が変わらない場合において、より長期間コードを放置できるのは、枯れた技術の方であることは確かだ。

だが実際は、比較的頻繁に業務の方が変わり、改修が必要になるものだ。扱う商品が変わったとか、帳票を廃止することにしたとか、社内の業務改善はもちろん、提携先の企業が変わった、銀行が合併した、連携しているシステムの仕様が変わった、法改正に対応する必要が出てきた、といった、自分の周りの環境も時間経過によって変わっていくのだ。

こうしたビジネスロジックの変更に追随しやすいのは、結果的に実装量、考慮すべき技術的な問題が少なく済む、イマドキのライブラリを使う方に軍配が上がるのではないだろうか。低級な言語は自分で考えないといけないこと、自分で実装しないといけないことがどうしても多くなる。対象の業務的な部分だけでなく、技術的な問題や課題との調整事も考慮する必要が出てくるので、余計にリソースをとられる。


ここからはより主観的・感覚的なものになるが、こうした様々な面でのコストを考えた時に、僕としてはマイグレーションのコストがあっても、多くの便利な機能、エコシステムが備わっている、新しい言語やフレームワークを使う方が良いと考えている。

  • :対応コストが少ないもの
  • ×:対応コストがかるもの
  • △:甲乙付け難いもの
事柄 イマドキの技術 枯れた技術 備考
初学者の学習コスト × イマドキの技術は何が自動化されているのか、裏側は知るべき
枯れた技術は全てを覚えないといけない
新規開発時の実装コスト × イマドキのライブラリは CLI ツールが備わっていることも多く、すぐに実装できる
セキュリティ面の対応コスト × イマドキの技術は最初からセキュリティ対策されていたりする
枯れた技術は自分で考慮しないといけない
バージョンアップ等の頻度・追随コスト × 枯れている方がマイグレーションの機会は当然少ない。その分放置できる
業務の変更の頻度 ビジネスロジックの変更が必要になる機会は、当然技術によらない
業務の変更による改修コスト × 枯れた技術の場合、自前で実装している量が多く、変更量も多くなりがち

多くの先人が頭を悩ませ、その知力を結集して問題を既に解決してあって、ツール内にベストプラクティスとして埋め込まれているような最新の技術に追随する方が、開発者としては楽だろう。

先人が学習してきたことと同等の量を学習しないと使いこなせないようなツールは、それと比べて劣っていると思う。

低級な言語の方が、コードと実行環境の間に介在するものがより少ないので、一般的により高速な動作を実現しやすい。イマドキのライブラリの場合は、物凄く単純化して表現すると「経由する関数呼び出しの数が多い」状態になるので、よほどチューニングしない限りは枯れた技術でチューニングした結果に辿り着けない。しかし、そうしたパフォーマンス面の話も、こんにちのハードウェアの性能からすれば微々たる差といえる。一般的な業務システムがそこまでの極端なチューニングを必要とすることは少ない。


イマドキの技術による頻繁なマイグレーションはなかなか達成感が少なく実りを感じにくい作業だし、枯れた技術は一度覚えたらしばらく勉強しなくても使い回しが利く側面もある。

だが、多くの先人の知恵の結集であり、自分一人では実現が難しかったことも容易に実現できるようになる、イマドキの技術に追随していく方が、結果的に様々な面でコストが掛からず、特に組織的には長期的な運用保守に向いているのではないかと考えている。

みんなが知っておくべき運用設計のノウハウ

みんなが知っておくべき運用設計のノウハウ