Projektarchitektur & globale Variabeln

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

bmurray

Betreff: Projektarchitektur & globale Variabeln

BeitragDo, Dez 31, 2020 21:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich steige gerade auf Python um, also eigentlich ist das eine schlechte Frage für ein Blitz Forum, aber da ich bisher nur in BlitzMax gecoded hab, ist die Frage vielleicht doch nicht so verkehrt. Ich habe echt noch Probleme mit den Variabeln bei Python. Diese müssen ja nicht deklariert werden und globale Variabeln gibt es zwar, sind aber wohl sehr verpönt.

Kurz gesagt: Wie programmiert man ohne globale Variabeln? zB Einstellungen. Ich hatte in BM ein Type mit dem Namen tEinstellungen angelegt und eine einzige Instanz erstellt: "einstellungen", die ich global im selben Type deklariert habe, also zB für ein Datumsformat sieht das dann so aus: "tEinstellungen.einstellungen.datumsformat". In einer Funktion wird nun das Datum ausgegeben, und zwar abhängig von der gewählten Einstellung, etwa 13.02.2018 (TTMMJJ) oder 11.23.2020 (MMTTJJ). In der Funktion wird dann einfach das Datumsformat gecheckt, und entsprechend verfahren.

Jetzt bin ich wirklich überfragt, wie man dies ohne globale Variablen machen kann. Eine Datumsanzeige kommt in meinem Spiel fast überall vor. Generell verstehe ich nicht, was an globalen Variabeln so schlimm ist, die werden doch überall benötigt. Mir ist schon klar, dass dies die Fehleranfälligkeit erhöht, aber so ganz ohne, scheint es doch nicht zu gehen, oder?

Xeres

Moderator

BeitragFr, Jan 01, 2021 1:50
Antworten mit Zitat
Benutzer-Profile anzeigen
In der Realität kommt man um ein paar globale Variablen meistens nicht herum. Man sollte halt versuchen die Verwendung zu minimieren. Je größer und komplexer ein Projekt ist, desto weniger will man irgendwelche Seiteneffekte auslösen können. Eine Funktion mit definierten Parametern sollte deterministisch das selbe Ergebnis erzeugen - nur so kann man seinen Code testen und Bugs finden.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

bmurray

BeitragFr, Jan 01, 2021 15:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie kann man denn eine solche Programmierweise erlernen? Gibt es da ein allgemeines Stichwort zu, vielleicht so etwas wie "Programmstruktur" oder so? Die ganzen Python-Tutorials gehen immer nur explizit auf eine Sache ein, zB Klassen, Variablen, Module oder ähnliches, aber nie auf das "große Ganze". Hast du da einen Tipp, gerne auch Literatur?
 

ohaz

BeitragFr, Jan 01, 2021 17:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn du allgemein sowas lernen willst, google nach Clean Code. Gibt auch ein ziemlich bekanntes Buch von Robert C. Martin dazu.

Wenn du speziell globale Variablen verhindern willst (sehr gut!), dann nutze Dependency Injection

Xeres

Moderator

BeitragFr, Jan 01, 2021 20:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine schöne Übersicht über diverse Design Patterns gibt's da: https://refactoring.guru/design-patterns/python

Am einfachsten zum eingewöhnen ist es sicherlich, wenn man mit einem Framework arbeitet, was diese Patterns bereits einsetzt. Wenn man damit arbeiten muss, wird einem der Wert weit besser bewusst als wenn man versucht auf grüner Wiese zu starten.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

DAK

BeitragSo, Jan 03, 2021 23:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Dependency Injection mag für den Anfang etwas groß sein.

Was du z.B. machen kannst, ist benötigte Variablen über Funktionsparameter übergeben und als Return-Werte wieder rausholen.

In Python kann man z.B. Variablen in Objekte, Dicts oder Lists zusammenfassen um weniger Variablen übergeben zu müssen. Man kann auch bei Return mehr als eine Variable auf ein Mal hergeben:

Code: [AUSKLAPPEN]

def f():
    return (1, 2, 3, 4)

a,b,c,d = f()
# a==1, b==2, c==3, d==4


Als Weiteres wird alles by reference übergeben. Das heißt, sofern man das Objekt verändert wird auch das gleiche Objekt in der aufrufenden Funktion verändert:

Code: [AUSKLAPPEN]

def f(l):
    l.append("B")

liste = ["A"]
f(liste)
# liste == ["A", "B"]


Bedenke, das funktioniert nur, wenn das Objekt verändert wird, nicht wenn der Variable ein neues Objekt zugewiesen wird:

Code: [AUSKLAPPEN]

def f(i):
    i = 2

integer = 1
f(integer)
# integer == 1


Mit dem solltest du schon etwas weiter kommen.


Globale Variablen solltest du hauptsächlich aus einem Grund vermeiden:
Sie sind von überall aus einseh- und veränderbar.

Das ist ziemlich doof, weil es dafür sorgt, dass man eine hohe Kopplung bekommt. Das heißt, dass man schnell dazu tendiert, eine globale Variable von irgendwo aus zu ändern, statt saubere Schnittstellen zu verwenden. Das heißt aber, wenn man irgendwas mit dieser Variable umbauen will, muss man durch das ganze Projekt durch und alle Dateien und Funktionen checken um rauszufinden, wo man diese Variable schon mal verwendet hat.
Gewinner der 6. und der 68. BlitzCodeCompo

bmurray

BeitragDi, Jan 05, 2021 0:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich danke euch allen sehr! Ich möchte ja globale Variablen vermeiden, aber irgendwie fehlt mir noch der "Switch" in meinem Kopf. Wenn ich noch mal mein Einstellungen-Beispiel nehme. Ich brauche diese Instanz "einstellungen" so gut wie überall in meinem Spiel. Soll ich dann immer die ganze Instanz "einstellungen" von der Klasse "klasseEinstellungen" jeder Funktion übergeben, die irgendetwas mit Einstellungen zu tun hat?

in Blitzmax hatte ich einfach:
Code: [AUSKLAPPEN]
Type tEinstellungen

Field sprache:Int
Field waehrung:Int
Field datumsformat:Int

global einstellungen:tEinstellungen


Dann konnte ich mit

Zitat:
tEinstellungen.einstellungen.datumsformat


in jeder Funktion, die das Datumsformat benötigt, darauf zugreifen.

Wenn ich keine globale Instanz "einstellungen" habe, frage ich mich, wo ich im Programm diese Instanz speichern soll. Die MUSS doch global sein.

Verzeiht mir meine Begriffsstutzigkeit, das kommt wahrscheinlich noch, im Moment tue ich mich aber sehr schwer mit diesem Switch

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group