20年でソフトウェア開発の景色はどのぐらい変わったのか？

PySpa統合思念体です。

某チャットで、「今時のOSSのプロジェクト管理とかのベストプラクティスが書いてある本ないかな、陳腐化早そうだしないか」みたいな話題が投入されました。その中で、エキスパートPythonプログラミングとか、Pythonプロフェッショナルプログラミングとかは思い出して紹介したけど、他の人からはShip It、Manage It、Release It三部作とか、達人プログラマーとかも出てきました。

このあたりの源流を辿ると、そういえば今流行ってる開発の源流としてはエクストリームプログラミングの開発系のプラクティスの遺伝子を受け継いでいるのが多いよな、そういえば当時から見て今ってどう変わっているのかな、という話題に。せっかくなので20年前を思い出しつつ、当時と今でどういう風に変わってきたのか適当にまとめてみます。

# 20年前の状況

XP白本こと、eXtreme Programming Explainedが出版されて、みんなでワイワイ読んだりメーリングリストでワイワイ議論していた時代です。

* Java: JDK 1.2 (HotSpot VMが初搭載）
* C++: C++98だけど、Visual C++ 6.0とかEGCSが統合されたGCC 2.95が出てた頃。C++ Builder 3とか、Borland C++ 5とか。
* Python: 1.5
* Ruby: 1.3
* ブラウザ: Internet Explorer 5, Netscape Navigator 4.5。IEの方が安定していたかな？

# 各領域ごとの変化

## プログラミング

### デザインパターン

当時はGoFのデザインパターンがイケイケで、これを学ぶことは言語によらない設計能力を身に着けた証、みたいな中２感がありました。

ただ、リファクタリングのようにデザインパターンに近づけるための方法論として提唱されているものがあったり、◯◯パターンみたいなのは大量に発生して、他の領域に応用しようみたいなムーブメントが起きたりはしましたが、このプログラミングのコアの領域ではNullObjectパターンとか、fluentインタフェース、mvvm、最近になってflux、クリーンアーキテクチャとかオニオンアーキテクチャあたりが言葉として普及したぐらいで、デザインパターンそのものが大きく発展することはなかったように思います。

その一方で最近もてはやされているのが関数型プログラミングのエッセンスを取り入れるやつですね。forEach/map/filter/reduceあたりを備えている言語は多いです。これらは実際の処理部分は関数として受け付けるので、必然的に高階関数です。これらを使ってリスト処理をするとかもですね。あとは、状態を持たずにimmutableに処理をする（値を変更するのではなく、変更前の世界から、変更後の世界を別途作る）とかも広まっています。一方、プログラミング言語のサポートがないとできない末尾再帰とか、パターンマッチはまだまだ、という感じです。

### 型

当時は完全に二択でした。

* 型を書く：コンパイルでチェックされるがだるいしコンパイル遅い
* 型を書かない：コンパイルなくてこまめに実行できるが、チェックが何もないのでテストを余計に書かないといけない

今は型推論がいろいろな言語に入ってきて、型を書く回数を減らしつつチェックもされるというのが増えて便利になりました。開発環境もだいぶ賢くなってPCの性能向上とともにリアルタイムチェックも実用的になりました。

* JavaScriptもTypeScript/flowtypeで型を使うブーム。Pythonもmypy導入。Rubyも導入を検討
* JavaもC++も、右辺で型が決まるならvar/autoで省略できるようになってだいぶ楽に

### エコシステム

昔は依存ライブラリを一つずつダウンロードしてmakeしてインストールするとか、そういう感じだった気がするけど、パッケージリポジトリからまとめてダウンロードして一括で入れたりも楽になりました。アップロードもしやすく自由になりました。まあコレ自体はCTAN（TeX用）がリリースされ、その後CPAN（Perl用）がそれを真似して・・・みたいな感じで言語によっては20年前にはすでにありましたが、それがだいぶ他の言語にも普及しました。

その中で少しみられたのが、言語を選ぶ→エコシステムを選ぶ→言語を選ぶに揺り戻しが、という流れですね。言語がはやる→ライブラリが充実する→そのライブラリを使いたいけどその言語使いたくないからそのエコシステムを使う言語が作られる→元の言語が釣られて発展する→元の言語に収斂されていく・・・的な。

Javaが流行ったらJVM言語としてGroovyとか、Jython、JRubyとかいろいろ出てきたけど、Java本体がいろいろ取り込んで強くなったりして結局Javaでいいじゃん、サンプルも多いし、みたいな雰囲気を感じます。Kotlinは別の政治的なところがあるのでおいといて。JavaScriptも、JSX(DeNAの)とかCoffeeScriptから、JavaScript (+TypeScript）に。Silverlightみたいなプログラミングの自由よりはstack overflow-bilityというか、コピペビリティが勝った？

### アプリケーションの形態

昔はデスクトップが多かったです。ウェブも出始めていたけども、CGIが中心だったのと、J2EEがこれから出ていくぞ、というタイミング。LAMPスタック（Linux、Apache、MySQL、PHP）という言葉も聞かれました。

今はほぼウェブ＋モバイルですね。デスクトップは昔のものがしぶとく残っているぐらい。

## ユニットテスト

* 各フレームワークの使い勝手はだいぶ良くなったように感じるが、基本的にはそこまで変わっていない。
* ビヘイビア駆動開発の流れを受けたフレームワークは増えた。RSpecとかJS系とかで特に。
* 外部I/Oのライブラリが自らモック用のクラスを準備してくれたりとか、ライブラリの補助は増えている。
* テストの基本の書き方は特に変化はないが、テーブルベーステストがGoとかPythonとかJavaScriptとかいろいろ広がっているのを感じる。
* プロパティベーステストが次の流れに乗れるかどうか。
* 当時はt-wadaさんはDBの人というイメージで、まだテストの人というイメージではなかった。

## 受入テスト(E2Eテスト)

* デスクトップが主体だった。
    * 昔は話題に上がるのはFitnesse(Java)ぐらい
    * QtはFrogLogic社のツールとかは昔からあったきがするけどめちゃ高かった
    * 構造的にGUIのメッセージ処理とかに食い込む機構だったのでフレームワークごとに固有のツール。
    * とはいえ、このあたりの取り組みが今のRPAにつながっている気がしないでもない
* 今はウェブとモバイル
    * Seleniumから出発し、Appiumとかいろいろある。
    * モバイルは最初からこのあたりに取り組む人が増えてきた
    * Chrome自身もHeadlessとかCDPとかいろいろ装備してプログラマブルに利用することができるように

## 継続的結合（CI）

当時はHudson(Jenkins)とかbuildout。金がある、スポンサーがいるところはオンプレでサーバーをたくさんならべて、Windows/Linux/FreeBSD/Solaris/HP-UXとか並列ビルドしてかっこよかった

最近はSaaSのサービスがいろいろ出てきて敷居がだいぶ下がりました。OSS開発サポート無料プランも出て来て、多くの人にとって普通に使える選択肢になりました。

* 各言語が提供するビルドツールとかもだいぶ使い勝手が良くなってきました。
* Dockerコンテナも出てきてブームに。アプリケーション作るだけではなく、Dockerfileビルド時間短縮芸とか、イメージサイズ縮小eスポーツが流行っています。
* 大規模インフラ構築はopenStackで新たな市場ができあがり、K8sが今後は普及の兆しだけど、今も昔も、みんな難しい・・・と言っている。

## コード共同所有

ここが一番大きく変わったところな気がします。

当時主流はCVS・VSS。

* VSSはWindowsのフォルダ共有で運用できたので敷居は低かったし、Visual Studioの有料版にはバンドルされていたので、新規投資なしで使えた（はず）
* OSSでは、SourceForge.net(日本ではなくて）にアカウントがあって、CVSを扱うのがステータス。
* この時点ではまだ流行っていなかったのがSVN。2002年リリースのTortiseSVNは使いやすいしわかりやすい。変更の多いバイナリを扱う場合だと未だにGitよりも良いこともある。
* ブランチなにそれ？

今はGit一強。

* GitHubとかGitLabとかSaaSサービスが大きく普及し、気軽に使えるように。GitHub採用なる言葉も
* 社内でもGitHub Enterprise ServerとかGitLab Communityを運用する会社も増えた
* ブランチを使った運用、Pull Requestを使った運用とか。当たり前のようにフォークして、Pull Requestを出して、それがGitHub上でCIが走ってチェックされて、diffをわかりやすい画面で見てブラウザでマージ。
* GoとかNode.jsとかGit上のパッケージを直接取得してくる言語とかも後押し
* MercurialとBazaarにはもう少し頑張って欲しかった。

あと、コード共同所有に範疇かわからないけど、docker-compose.ymlファイルで開発環境一発起動とか、開発環境情報の共同所有みたいなのもだいぶ便利に。VMWare、openStack、Docker、Ansibleとかいろいろな取り組みのおかげでかなり便利。インフラがクラウドになって、IaCで環境もコードになったり、べき等とか言われるようになったり。このあたりの形式もだいぶ変わりました。

今、アジャイルのプラクティスが作られるならこのインフラ周りの話は絶対入りそう。

## リファクタリング

* もちろん本来はテストを書いてからがんばって実行しましょうなんだけど、モリッとやってくれるIDEの機能もだいぶ便利に。
* デザインパターンの議論があまり行われなくなって、それにともなって新しいムーブメントがなくて寂しいと感じる。

## コーディング標準

* 昔はコーディング規約を決めて、各自頑張ってそれを守ろう、という感じでした。
* Eclipseみたいな気の利いたツールがフォーマッターを内蔵しはじめました
* 今やフォーマットは自動で修正すべき、みたいになってきている。便利なツールが増えた（go fmt/prettier/black etc)
* コード共同所有＋SaaSのリポジトリの普及で、diffを見てPRをマージみたいなのが主流になってきたり、余計なdiffを減らして見やすくするという必然性が高まったのかもしれません。

## ドキュメント

* JavaDocとかDoxygenを一生懸命書いてHTMLやらWindowsヘルプを生成みたいな感じでした。
    * JavaDocの普及により、ソースコード内に決まった文法で書いてドキュメント生成は市民権を得ました。
* ウェブサイトに公開する目的では今もあるが、ローカルはエディタがポップアップで出してくれるのが多くて、手元でビルドして使う人はあまりいないのでは？
* 当時はWikiブームみたいなのが少しきていた。文法は増え続け、収束することはなかった。n種類あるWiki文法を統一させよう！という意欲的なCreoleという文法が出てきたけど、n+1種類になっただけであった。
* みんなMarkdown書くようになった。方言は増え続け、収束させようと努力する人はいるものの、収束する雰囲気はない。
* モデル駆動開発とか、CASEツールとかは当時は夢があったけど最近は話をしている人はいない。Rational Rose欲しかったんだよな。昔。
* UML！！UML！！という感じもなくなった。

## ロギング

* DEBUG/INFO/WARN/ERROR/FATALみたいなのは変わっていない
* ウェブサービスの入り口では全部ログを出しておけ、Hadoopで分析だ、みたいなのはソシャゲブーム前後でだいぶ流行った。今はBigQueryとか集約側はSaaSとかがいろいろ便利に。いわゆるビッグデータブーム。
* syslogとかでローカルに→fluentdとかのログコレクターを使う方法が一般化→それはコンテナのサイドカーでやるからアプリは標準出力に出しておけ、みたいな寄り戻しが来ている雰囲気。
* これとは別に、オブザーバビリティ（分散トレースとかメトリックスのモニタリング）は当時はなかったが、最近は少しずつ名前を聞くようになってきた（個人的にはCouchDB使って分散トレースはやっていたけども）。
* ビッグデータは運用改善とかA/Bテストとかお金の匂いがする感じであったけど、オブザーバビリティは純粋に開発とか運用改善みたいな雰囲気。オブザーバビリティは今後の基礎教養になりそう。

## データベース

* 当時はRDBがコア。RDBの入出力をJavaなどで書くのがメイン。
    * OSSのDBはまだあまり第一線で使われることはなく、Oracle/DB2/SQL Server/Interbase(Firebird)などが広く使われていた。
    * Oracleも1コアならライセンス料が安い！
* 最初はNoSQLという名前で話題になった非RDB群も、現在では用途別に少しずつ普及してきた。
    * memcached、Redisなど、特定用途特化のキャッシュとかランキングとかのKVSが使われるように
    * 検索エンジンとしてElasticsearchを一緒に使うようになってきた
    * 日本では流行ってないけど、リレーションまでは不要で親子関係でJSONで表現できる範囲（プレイヤーのアイテムプロパティにアイテムが3個入って・・・とか）であればMongoDBは海外では流行っている。
    * Dynamo, BigTableも用途によっては使われるが、消えたら困るようなメインのDBは日本ではまだまだRDBが強い。
    * NoSQLといっても、主キーで値をとってくる以上の機能を備えたものは独自の記述力の高いクエリー言語を持っていたり（MongoDBのJSONのクエリー、CassandraのCQL）するし、それをもうSQLにしちゃえばよくね？（Spanner、CockroachDB）みたいなのも出てきて、NoSQLという言葉自体が使われなくなってきてる？
    * クラウドパワーで、Kafkaをそのままストレージに使うLinkedInみたいな変態アーキテクチャも
* RDBもだいぶ世界が変わって来た
    * 現在はOSSのRDBMS（というかPostgreSQLとMySQL）がかなり使われるようになってきた
    * RDBもクラウドのパワーを得た
        * MySQL/PostgreSQLのエンジンが切り替えられるクラウドサービスを各クラウドベンダーが提供
        * スケーラビリティが重視される場合はAurora、Spanner、CosmosDBなどの分散するRDBも人気
        * とはいえ、エクサデータは相変わらずすごい。札束ですべてが解決する。マネーイズパワー。


# まとめ

基本的なベクトルは大きくは変わらないものの、ツールの使い勝手とかカバレッジが大幅に強まったのと、誰でも使いやすいように整備が極めて簡単になったりして、「エンジニアリングリソースが潤沢で儲かっているIBMとかMicrosoftとか一部の会社の事例を見て指をくわえていた」のが、気軽に使えるようになってきたところは大きく変わってきていますね。

あとはやはり分散リポジトリのGitの普及とその周辺エコシステムの変化は開発の体験が大きく変わったと感じます。