1. 会社沿革

OOP が大規模システムの複雑さとの戦いにどのように役立つかを示す話をしたいと思います。これはOOPの目的を理解するために必要です。

昔々、銀河間輸送サービスを提供する小さな会社がありました...

ギャラクシーラッシュと名付けましょう。従業員は5名でした。1 人は金融で働き、2 人は倉庫で働き、3 人は配達を担当し、4 人は広告を担当し、5 人は企業全体を管理しました。

彼らはとても働き者で、何事においても成功しました。その会社は評判が良く、たくさんのお金を稼ぎました。しかし、年々注文が増えたため、上司は追加の従業員を雇わなければなりませんでした。倉庫に数名、配送に数名、財務にもう 1 名、そして会社の市場シェアを拡大​​するために広告の専門家を追加しました。

そしてそのときから問題が始まりました。人が増えて、お互いの邪魔をし始めました。

マーケティング担当者は新しい広告キャンペーンに支出して銀行口座を使い果たし、緊急に出荷する必要がある製品を購入するお金がありません。

倉庫には 10 台の新品のハイパー ドライブがあり、月に 1 回顧客に出荷されます。ある宅配業者が飛んできて、別の顧客のハイパー ドライブを持ち去ったため、10 台のハイパー ドライブの定期注文が 1 か月遅れました。最初の配達員は、2 番目の配達員が他の注文に対応していることを単に知らなかったのです。

新しいアシスタントマネージャーは、より多くの商品を購入するために配達員を宇宙船で送り出します。その間、他の全員は利用可能な宇宙船が現れるのを待っています。緊急の配達がたくさんありますが、このアシスタントは調達を監督するだけで、自分の仕事をうまくやろうとしています。 従業員が職務を遂行すればするほど、他の従業員の仕事に干渉するようになります。

状況を分析した上司は、宇宙船、現金、製品などの重要なリソースが最適に使用されていないことに気づきました。代わりに、「居眠りしたら負け」というルールが適用されます。どの従業員も、他の従業員が自分の仕事に必要としているリソースを奪う可能性があり、その結果、他の従業員や会社全体が危険にさらされることになります。

何かをしなければならなかったので、上司は一枚岩の会社をいくつかの部門に分割することに決めました。彼は出荷部門、マーケティング部門、調達部門、財務部門、在庫部門を創設しました。もはや誰も宇宙船に簡単に乗ることができなくなりました。出荷部門の責任者は配送に関するすべての情報を受け取り、最も収益性の高い注文をした配送業者に船を発送しました。さらに、この倉庫では、宅配業者が希望する商品をそのまま受け取ることはできませんでした。代わりに、倉庫からの製品のピッキングは管理されたプロセスになりました。財務部門は、近いうちに買収が行われるとわかっていれば、マーケティング キャンペーンに資金を投入することはありません。各部門には部門長という公の顔が 1 つありました。各部門の内部構造は独自の業務でした。配達員が商品を受け取りたい場合は、倉庫ではなく倉庫管理者に行きました。新しい注文が入った場合、それは宅配便 ( public-facing representative) ではなく、出荷部門の責任者 ( someone not authorized to interact with the other departments) が受け取りました。

言い換えれば、上司はリソースとリソースに関係する行動をグループ(部門)に統合しまた他の人が部門の内部構造に干渉することを禁止しました。 部門間のやり取りは特定の人物を介する必要がありました。

OOPの観点から見ると、これはプログラムをオブジェクトに分割することに他なりません。メソッドと変数のモノリシック プログラムは、オブジェクトで構成されるプログラムになります。そしてオブジェクトには変数とメソッドがあります。

問題は、従業員が監視や制御なしに、あらゆるリソースを操作し、他の従業員に指示を与えることができるということでした。小さな制限を課しましたが、より多くの秩序を達成しました。そして、すべてをより適切に制御することもできました。

これは最も純粋な形での分割統治です。


2. プログラムの作り方

OOPのもう 1 つの利点を明らかにする、もう 1 つの重要な点について触れたいと思います。プログラムは建物というより動物に似ていることがわかりますか? それらは構築されていません。彼らは成長しました。開発とは常に変化することです。建設では、適切な計画を立て、それに正確に従うことができます。ソフトウェア開発の場合はそうではありません。

プログラミングでは、当初意図したとおりに何かを実行できず、何度もやり直す必要があることがよくあります。顧客の要件はさらに頻繁に変化します。

しかし、顧客が非常に正確な仕様を提供した場合はどうなるでしょうか? それが事態をさらに悪化させます。時間の経過とともに製品に何が起こるかを見てください。

製品が成功すると、顧客は新しいバージョンをリリースしたくなり、さらに次のバージョンをリリースするようになります。そしてもちろん、既存の製品に「小さな変更」を加えるだけで済みます。このように、製品開発は絶え間ない変化の連続であることがわかります。時間スケールが違うだけです。新しいバージョンは、1 週間に 1 回、1 か月に 1 回、または 6 か月に 1 回リリースできます。

これらすべてから、どのような結論が導き出せるでしょうか? 製品の内部構造は、大幅な (および軽微な) 変更を最小限の手戻りで行えるように維持する必要があります。

オブジェクトの凝集

しかし、それを実行することは、それを実行することを決定することよりも困難です。プログラムは相互に作用するオブジェクトで構成されているとすでに述べました。プログラムのすべてのオブジェクトをボード上に描画し、それらを点で表しましょう。そして、各オブジェクト (ポイント) から、それが相互作用する他のすべてのオブジェクト (ポイント) に矢印を描きましょう。

次に、オブジェクト (点) をグループに結合します。ポイント間の接続が他のポイントとの接続よりもはるかに強い場合、ポイントをグループ化する必要があります。ある点からの矢印のほとんどがそのグループ内の他の点に向かう場合、グループは正しく形成されています。グループ内のポイントの凝集性は高いが、異なるグループ内のポイントの凝集性は低いと言えます。

疎結合原理

「疎結合の原理」というものがあります。プログラムはいくつかの部分に分割されており、多くの場合、それらの部分は層になっています。これらの層/部分のロジックは、その内部構造と密接に結合されていますが、他の層/部分とは非常に緩やかに結合されています。通常、レイヤー間の相互作用は非常に規制されています。1 つの層が 2 番目の層を参照し、そのクラスの小さなサブセットのみを使用する場合があります。これは、先ほど見た「会社を部門に分割する」という原則ですが、より大きな規模のものです。

その結果、必要に応じて部門を再編成してその有効性を高めることができ、その部門にさらに多くの人員を雇用することができます。また、他の部門とのやり取りのプロトコルを変更しない限り、加えられたすべての変更は効果を発揮します。ローカルのままです。誰も何も学び直す必要はありません。システム全体を作り直す必要はありません。部門間の相互作用のメカニズムが適切に選択されていれば、各部門はこの種の内部最適化を行うことができます。

よく選ばれました。しかし、うまく選ばれなかったらどうなるでしょうか?そうなると、変更のキャパシティがすぐに枯渇してしまい、システム全体をやり直さなければならなくなります。これは時々行う必要があります。未来を予測することはできませんが、やり直しの回数を最小限に抑えることはできます。

抽象化の原理

部門の構造と部門間の相互作用の方法を選択することは、「抽象化の原則」です。プログラミングでは、プログラムを構成部分に分割する最適な方法と、それらの部分がどのように相互作用するかを決定するために使用されます。この原則を再適用して、プログラムを個々のクラスに分割するまで、結果の部分を複数の部分に分割することができます。

これらのパーツの内部構造を隠し、他のパーツとの相互作用を厳密に制限するのがカプセル化です。 カプセル化と抽象化はOOPの基礎です。優れたプログラムは、これら 2 つの原則に従わなければなりません。将来的には、残りの原則を検討し、それらがどのような利点をもたらすかを探っていきます。