Sehr kurz, es macht den Programmstatus unvorhersehbar.
Stellen Sie sich vor, Sie haben ein paar Objekte, die beide dieselbe globale Variable verwenden. Angenommen, Sie verwenden in keinem Modul eine Zufallsquelle, kann die Ausgabe einer bestimmten Methode vorhergesagt (und daher getestet) werden, wenn der Systemstatus bekannt ist, bevor Sie die Methode ausführen.
Wenn jedoch eine Methode in einem der Objekte einen Nebeneffekt auslöst, der den Wert des gemeinsam genutzten globalen Status ändert, wissen Sie nicht mehr, wie der Ausgangsstatus lautet, wenn Sie eine Methode im anderen Objekt ausführen. Sie können jetzt nicht mehr vorhersagen, welche Ausgabe Sie erhalten, wenn Sie die Methode ausführen, und können sie daher nicht testen.
Auf akademischer Ebene mag dies nicht sehr ernst klingen, aber die Fähigkeit, Code als Einheit zu testen, ist ein wichtiger Schritt bei der Überprüfung seiner Richtigkeit (oder zumindest seiner Eignung für den Zweck).
In der realen Welt kann dies schwerwiegende Folgen haben. Angenommen, Sie haben eine Klasse, die eine globale Datenstruktur auffüllt, und eine andere Klasse, die die Daten in dieser Datenstruktur verarbeitet, ihren Status ändert oder sie dabei zerstört. Wenn die Prozessorklasse eine Methode ausführt, bevor die Populatorklasse fertig ist, ist das Ergebnis, dass die Prozessorklasse wahrscheinlich unvollständige Daten zu verarbeiten hat und die Datenstruktur, an der die Populatorklasse gearbeitet hat, beschädigt oder zerstört werden könnte. Das Programmverhalten wird unter diesen Umständen völlig unvorhersehbar und wird wahrscheinlich zu einem epischen Verlust führen.
Darüber hinaus beeinträchtigt der globale Status die Lesbarkeit Ihres Codes. Wenn Ihr Code eine externe Abhängigkeit hat, die nicht explizit in den Code aufgenommen wurde, muss jeder, der die Pflege Ihres Codes übernimmt, danach suchen, um herauszufinden, woher er stammt.
Was Alternativen angeht, so ist es unmöglich, überhaupt keinen globalen Status zu haben, aber in der Praxis ist es normalerweise möglich, den globalen Status auf ein einzelnes Objekt zu beschränken, das alle anderen Objekte einschließt und auf das niemals unter Berufung auf die Gültigkeitsregeln verwiesen werden darf der Sprache, die Sie verwenden. Wenn ein bestimmtes Objekt einen bestimmten Zustand benötigt, sollte es explizit danach fragen, indem es als Argument an seinen Konstruktor oder durch eine Setter-Methode übergeben wird. Dies wird als Abhängigkeitsinjektion bezeichnet.
Es mag albern erscheinen, einen Status zu übergeben, auf den Sie aufgrund der Gültigkeitsregeln der von Ihnen verwendeten Sprache bereits zugreifen können, aber die Vorteile sind enorm. Wenn jemand den Code isoliert betrachtet, ist klar, welchen Status er benötigt und woher er kommt. Es hat auch enorme Vorteile in Bezug auf die Flexibilität Ihres Codemoduls und damit die Möglichkeit, es in verschiedenen Kontexten wiederzuverwenden. Wenn der Status übergeben wird und Änderungen am Status für den Codeblock lokal sind, können Sie einen beliebigen Status übergeben (sofern es sich um den richtigen Datentyp handelt) und den Code von Ihrem Code verarbeiten lassen. Code, der in diesem Stil geschrieben wurde, sieht in der Regel wie eine Sammlung lose zugeordneter Komponenten aus, die leicht ausgetauscht werden können. Dem Code eines Moduls sollte es egal sein, woher der Status kommt, nur wie er verarbeitet wird.
Es gibt viele andere Gründe, warum die Weitergabe des Staates der Nutzung des globalen Staates weit überlegen ist. Diese Antwort ist keineswegs umfassend. Sie könnten wahrscheinlich ein ganzes Buch darüber schreiben, warum der globale Zustand schlecht ist.