グローバル変数を使用してもよい場合


22

さて、これは本当に悪魔の擁護者の質問です。

グローバル変数はいつ大丈夫ですか、もしそうでなければ、代替として何を使用しますか?

この質問に対する興味深いサイドケース、パブリック静的クラスフィールドはグローバルとどう違うのですか?


5
コード完了、第2版、§13.3。
ジェリーコフィン

1
マルチスレッドアプリケーションは、グローバル変数をほとんど必要とします。
アクア


4
@aquaマルチスレッドアプリケーションは、グローバル変数が最も損害を与える可能性がある場所です。誰もが複雑なロックロジックを嫌います。
ルイスキューバル

1
@JerryCoffin関連するパッセージを引用せずにリンクを回答として投稿するのが悪い習慣である場合、関連するパッセージを引用せずに本のセクションを引用することも同様です。特に、ウェブページのように本は自由にそして簡単に入手できるわけではないので。
ブレーデンベスト

回答:


18

私の知る限り、パブリック静的フィールドは、名前空間を詰まらせないことを除いてどこからでも呼び出すことができることを考えると、基本的にグローバルです。

コードで個人的に「グローバル」変数を使用するのは、不変のパブリックスタティックフィールドの形式のみです。この場合、プログラムの他の部分によって値がめちゃくちゃになるのを心配する必要はありません。もちろん、各クラスで同じ永続的な値を持つ12個の変数を持つよりもはるかに優れています。


2
不変のフィールドを定数と呼びます。
aioobe

14

個人的に、私はランタイム構成にグローバルを使用します-アプリケーションの起動時に構成プロパティがロードされ、まれに(そして1箇所からのみ)変更される場合、使用する必要があるすべてのメソッドにそれを渡すのはひどくエラーが発生しやすいですある時点でそれ。メソッドシグネチャや呼び出しサイトを混乱させたり、隠したりしないため、使用する必要のある場所からスコープ内に持ち込むことができるものを使用することをお勧めします。


これに純粋なグローバルを使用しますか、それともパブリックな静的/シングルトンを使用しますか?
オコド

1
@Slomojo:間違いなくシングルトンではありません。状況に応じて、構成クラスの静的変数、CONFIG_またはCFG_接頭辞付きの単純なグローバル変数のいずれか。
アノン。

+1私が提案する1つの変更は、「...エラーが発生しやすく、他のすべてのクラスの他のすべてのメソッドに渡される」ということです。それ以外の場合は、それを提供するものでクラスにスコープすることができます-私はシングルトンだと思います。
マイケルデュラント

8

リアルタイム/組み込みシステムを除き、実際には定数値にのみグローバルを使用する必要があります。それらなしでは問題を解決できないと感じるなら、おそらく何か間違ったことをしているのでしょう。

また、Singletonパターンを調べてください。グローバルアクセスポイントが必要な場合に、このような状況でグローバルに適したソリューションを提供できます。


8
シングルトンを避けることをお勧めします。
オコド

シングルトンが優れていることを示唆しているわけではありませんが、それでもグローバル変数を大幅に上回ると思います。
DavorŽdralo

定数値は、関連する領域/モジュールでのみアクセス可能である必要があります。定数TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPは、「この特定のループ」が現れる1つのファイル/クラス/セクションにのみ関連します。
クトゥルフ

1
シングルトンのフィールドグローバル変数であるため、どのように違いがあるのか​​わかりません。
sleske

1
@Cthulhuは、「グローバルアクセスポイントを使用するために何かが必要な状況で」と自分に言い聞かせます。
DavorŽdralo

6

グローバル変数の問題は、コード内のあらゆる場所でそれらを認識する必要があることです。ただし、特定のグローバルについて知る必要があると判断した後は、それを多用することでそれ以上の損失はほとんどありません。したがって、私の意見では、グローバル変数はごくわずかである必要がありますが、ごく少数のグローバル変数を最大限に活用する必要があります。

このように感じる別の例として、Rubyでのミックスインの使用を見てください。


これらのグローバルの使用について、どのような使用例を提案しますか?
オコド

1
@Slomojo:私が気にしないグローバルの例は、Perlで@ARGVと$ _を使用することです。私が気にする例は、サブルーチンに渡す安価なパラメーターにグローバルを使用することです。
btilly

5

名前空間がすべてです。

世界の誰もが同じ姓を持っているとちょっと想像してみてください。なんて混乱。

(インドでは、シーク教徒は同じ姓を持っています:シン-見てください)


6
これは、使用名前空間についてのすべてをすることが、今では、スレッドの安全性についてです。
dan04

6
@ dan04遠くに不気味なアクションを伴う恐ろしいデザインがないことです。
トムホーティン-タックライン

2
@Tom:たぶん、私たちはそれを呼び出すことができ、冗談、「量子プログラミング」
クリストファーマハン

4

ショートバージョン:プログラムについて推論するのが簡単になるとき。通常、ケースは、広く使用されている何らかのグローバルステートまたは静的リソースです。

ロングバージョン:トム・ホーティンは「遠くで不気味なアクションで」と言いました...それはまさにグローバルの問題です-それが使用されている場所と方法を知る必要があります、またはあなたはいくつかの本当に奇妙で追跡するのが難しいことがありますバグ。ローカルとは、プログラマーがプログラムについて推論するために理解する必要があるものの範囲を縮小する戦略にほかなりません。

それらが使用されている場所を知ることの問題のもう1つの側面は、重複したグローバルになる可能性があることです。その場合、ほとんどのプログラムはvar2を保持するために使用されている間にvar1を取得して設定するため、物事は本当に奇妙になる可能性があります同じ情報。特に、複数の人が同じコードで作業している場合。IDEは、使用法を見つけてグローバルのコストを削減するのに役立ちますが、重複に対しては何も行いません。

グローバルが多ければ多いほど、それらで起こっていることを追跡するのが難しくなります。それらは数が少なく、はるかに少ないはずです。


最終的に変更可能なグローバルを持つことは、かなり悪い考えです。唯一のまともな例外は、組み込みプログラミングなど、非常に狭いハードウェアフットプリントで作業する場合です。少なくとも、通常のプログラミングでのグローバルの候補は、クラスまたはモジュールの静的メンバーに分割する必要があります。また、マルチスレッド環境で作業する場合は、可変であるものも特殊なケースと見なす必要があります。ロック/先物/約束またはスレッド/トランザクションの安全性の他の方法を使用します。-誰も言及していないので、それは食事哲学者の問題を見る。
オコド

1
間違いなく、スレッドは可変グローバルの操作を難しくする可能性がありますが、イベントが原因で同じ基本的な問題が発生する可能性があります。私は、裾を静的メンバーとして配置するという提案に同意し、さらに先に進み、理想的にはプライベート静的メンバーであるべきだと言います。
jmoreno

3

グローバルとシングルトンの2つの落とし穴は、テスト容易性と展開可能性です。

テストについては、不十分に計画されたグローバルおよびシングルトンのライフタイムに対処するためだけに、過度に複雑なテストハーネスを見てきました。そのようなオブジェクトには、明確で単純な起動および破棄ルールがあることを確認してください。

デプロイ可能性に関しては、考慮すべき2つのケースがあります。まず、グローバルオブジェクトはどのように存続しますか?静的または動的ライブラリにありますか?そのグローバルオブジェクトがプラグインに再利用される場合、追加のコピーを取得しますか?次に、そのグローバルオブジェクトが並列アプリケーションにドロップされるとどうなりますか?スレッドセーフですか?

全体として、これらの理由は、グローバルとシングルトンが例外的にのみ使用されることを意味すると考えています。


2

通常、重要な組み込みシステムの開発には、グローバル変数の使用が伴います。

スタックサイズは小さく、すべてが静的に割り当てられ(malloc()禁止されています)、グローバル変数はそれらが属するライブラリの外部から隠されています。


0

明日がないようにグローバルを乱用する恐ろしいVB6コードベースでは、私は新しいものを導入することに罪を犯します。

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

グローバルオブジェクトの数少ない有効なユースケースの1つだと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.