こんにちは。
かつて Javaプログラミングを学ぶ過程でオブジェクト指向言語のデザインパターンという概念を知ることになりました。
この概念はそれ程新しいものではなく、最新のオブジェクト指向言語の実装において否定されているパターンも出てきているように絶対的なものでもないのですが、プログラミングに留まらずコンピューターシステムの在り方を考える上で非常に参考になったものでもありました。
「実装に対してプログラミングするのではなくインターフェイスに対してプログラミングする」という考え方なのですが、マイクロサービスを組み合わせて(インテグレーション)の実際のサービスを提供するという最近流行りのシステムデザインに現れている気がします。
この考え方がシステムデザインには全く無くてプログラミングの世界で初めて発生したという事ではないんでしょうけど、コンピューターハードウェアの発達の具合からみて、プログラミングの世界の方が先に実現できたのではないかと思います。
サーバーエンジニア各位も実際にシステム設計をしていて、モノシリック型のシステムからマイクロサービス集合型のシステムへの変化を見るようになるにつけ、薄々感じているところではないかと思います。
システムデザインでは
1つのシステムの影響をそのシステム内に収める設計
と言ってしまって構わないと思います。
このサイトでは「RabbitMQでメッセージを受け渡し」で書いていますが、複数のシステムを連携させている場合はそれぞれの結合度合いをなるべく(密に対して)疎にするようにした方が運用が楽なのです。
具体的に砕けた言葉でかけばこんな感じです。
- 障害時に連携先のシステムに迷惑をかけたくない(≒怒られたくない)
- システム変更時に連携先システムと調整するの面倒(≒干渉されたくない)
- 連携の約束事(プロトコル)だけは永く使えるものを設計する(=システム連携の本質部分をなるべくシンプルに設計)
- 自分のところの自由度が上がる(=約束さえ守っていれば後は何してもOK)
実際に私が経験した事例ではこんなのがありました。
(適切な例か分かりませんが根は一緒かと思います)
・DNSに業務を表すマシン名を登録
クライアントサーバーシステムのクライアントプログラムでサーバーのホスト名を指定していました。
サーバーリプレースのサーバー切り替え当日作業として、クライアント全台でサーバーのホスト名を変えてもらう作業が必要になっていました。
DNSにホスト名の別名として業務を意味するもの(システムがいくら変わっても業務は変わらないから)を登録し、それをサーバーとして指定するようにしてもらいました。
以降のサーバーリプレース時は DNSの設定を変更するだけで良くなりました。
繋ぐ(結合する)時には具体的なもの同士で直接やらずに間に何か抽象的なものを挟む、という風に私は考えてやってきましたが、オブジェクト指向言語を勉強したときにそれが合理的な理屈として確立してるんだなって思いましたね。
この概念が腹落ちすると、例えばネットワークのお勉強で出てくる OSIの7階層や TCP/IPスタックが何故ああいう積層構造で作られているのかの理由も腹落ちします。
ネットワークのお勉強では参考書でいきなり OSIの7階層が出てきて「7階層に分かれているんです!(キリッ)」と書かれていて「そうなんだ…」としか思わないですよね。
だけどあれが「色々な仕組みをすげ替えたい」という要求があるからわざわざ分けているんだって事に思い至れば、合理的な仕組みなんだって事に気付きますから、理解の深さが変わるってものです。
(というかこの辺の説明が無いから理解できないんだって後日思いました)
そんなの当たり前じゃんと言うなかれで、ITエンジニアでも気付いているのか気付いていないのか、この点を意識している人は余り多くはないように見えます。
上に書いたオブジェクト指向言語の話で「インターフェイスに対して実装しろ」と言われているのは、そうしてないプログラマが多かったからかも知れませんね。
この概念を意識しながら仕事をするに、本当に色々なところで使われているのに気付きます。
パブリッククラウドのサービスを見たりすると、その設計思想に触れる想いがします。
そんなに難しい考え方ではありませんので、ちょっとこれを意識して見るようにしてもらえば、これまでとは違ったものが見えてくるかも知れませんよ。
これ、本当に良い本で、そのせいか小さいサイズで再販されましたね。