OOPでグローバルが悪である理由はたくさんあります。
共有を必要とするオブジェクトの数またはサイズが大きすぎて関数パラメーターで効率的に渡されない場合、通常はグローバルオブジェクトではなく依存性注入をお勧めします。
しかし、ほとんどすべての人が特定のデータ構造について知る必要がある場合、なぜ依存性注入がグローバルオブジェクトよりも優れているのでしょうか?
例(特定のアプリケーションを深く掘り下げることなく、ポイントを一般的に示すための簡略化されたもの)
種類、名前、色、速度、位置など、膨大な数のプロパティと状態を持つ仮想車両が多数あります。多数のユーザーがそれらをリモートコントロールでき、膨大な数のイベント(両方ともユーザー、開始および自動)は、多くの状態またはプロパティを変更できます。
素朴な解決策は、それらのグローバルコンテナを作成することです。
vector<Vehicle> vehicles;
どこからでもアクセスできます。
よりOOPに適したソリューションは、コンテナーをメインイベントループを処理するクラスのメンバーにし、コンストラクターでインスタンス化することです。それを必要とし、メインスレッドのメンバーであるすべてのクラスには、コンストラクターのポインターを介してコンテナーへのアクセスが許可されます。たとえば、外部メッセージがネットワーク接続を介して着信した場合、解析を処理するクラス(接続ごとに1つ)が引き継ぎ、パーサーはポインターまたは参照を介してコンテナーにアクセスできます。解析されたメッセージの結果、コンテナの要素が変更された場合、またはアクションを実行するためにそこからデータが必要な場合、信号やスロットを介して数千の変数を投げる必要なく処理できます(または、それらをパーサーに保存して、パーサーを呼び出した人が後で取得できるようにします)。もちろん、依存性注入を介してコンテナへのアクセスを受け取るすべてのクラスは、同じスレッドの一部です。異なるスレッドは直接アクセスしませんが、ジョブを実行してからメインスレッドに信号を送信すると、メインスレッドのスロットがコンテナを更新します。
ただし、クラスの大部分がコンテナにアクセスできるようになった場合、グローバルとはどう違うのでしょうか?非常に多くのクラスがコンテナ内のデータを必要とする場合、「依存性注入方法」は単なる偽装グローバルではありませんか?
答えの1つはスレッドセーフです。グローバルコンテナを乱用しないように注意を払っていますが、近い将来、他の開発者が近い締め切りの圧力の下で、すべてを気にせずに別のスレッドでグローバルコンテナを使用する可能性があります衝突の場合。ただし、依存性注入の場合でも、別のスレッドで実行されている誰かにポインターを与えると、同じ問題が発生する可能性があります。