Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

21

16.08.2016, 16:09

Ich muss dot an der Stelle zustimmen, eine statische Klasse mit internem Zustand ist im Endeffekt genauso schlecht, wie ein Singleton.

@dot:
Unterschiedliche Sprachen, unterschiedliche Sitten. In C# gibt es statische Klassen (also Klassen, bei deren Definition zusätzlich das static Schlüsselwort verwendet wurde). Erforderlich sind diese bspw. für Erweiterungsmethoden, ansonsten zum Sammeln von Funktionalitäten, die nicht eindeutig einer Klasse und deren Membern zugeordnet werden können. Ein gutes Beispiel sind wohl die Funktionen unter System.Math.

Statische Konstruktoren gibt es aber in jeder vielen Sprache (und auch in Java, dort ist es aber nur ein Codeblock mit vorangestelltem static). Der Aufruf (zumindest in Java) findet grundsätzlich nach dem Laden der Klasse statt.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Sacaldur« (22.08.2016, 14:28)


Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

22

16.08.2016, 21:37

Zitat

Statische Konstruktoren gibt es aber in jeder Sprache

Um mal ein Gegenbeispiel zu bringen: Standard C ;)
Ein etwas moderneres Beispiel: Rust
Ich finde diese Entscheidung gut. Die Tatsache, das beliebiger Code noch vor main laufen kann, weil eine Bibliothek eingebunden wurde, finde ich gruselig und unsinnig. Man kann bestimmte Dinge ja bei der ersten Verwendung initialisieren. Andernfalls sind damit auch verschiedene Probleme verbunden, zB. die undefinierte Initialisierungsreihenfolge.

Veränderbare globale Variablen sind im Rust übrigens unsafe-Code vorbehalten.

EDIT:
Zur Diskussion stimme ich übrigens Dots Debunking voll zu.
Ich hab noch nie ein Singleton gebraucht. Globale Variablen sind auch nicht gut, aber in einigen Fällen (zB. wegen wenig durchdachter Abhänigkeiten in der Softwarearchitektur) eine Lösung (Notlösung).
Singletons hingegen verkomplizieren das nur ohne weiteren Grund.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (16.08.2016, 21:47)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

23

17.08.2016, 06:57

Wenn ich zum Beispiel Button/HUD-Texturen lade, die ich permanent und überall brauche, dann will ich die ja nicht mehrfach laden oder mehrere Instanzen haben, wo die immer gleichen Texturen drin liegen. Also gibt es es eine statische Klasse

Ich korrigiere mal: Also gibt es eine Instanz eines Asset-Caches (ich mag das Wort "Manager" nicht, speziell für Klassen, denen man notorisch immer nur Get-Methoden implementiert und dann unsinniger Weise behauptet, sie würden irgendwas managen) für GUI-Texturen irgendwo im upper Scope, der passend an die Stellen injected wird, die ihn benötigen. Da brauchst du kein Singleton. Schon allein deswegen, weil du ja offensichtlich noch andere Asset-Caches für non-GUI-Texturen haben willst. Baust du für die dann eine neue Non-Singleton-Variante derselben Klasse?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

LInsoDeTeh

Treue Seele

Beiträge: 372

Wohnort: Essen, Deutschland

Beruf: Team Lead Inhouse-Entwicklung

  • Private Nachricht senden

24

18.08.2016, 08:37

Ich glaube, wir haben uns hier missverstanden. Auch ich bin kein Freund von Singletons und habe auch noch nie einen explizit implementiert. Wir sind hier also absolut auf der gleichen Seite. Mein Beispiel sollte veranschaulichen, dass C# mit den statischen Klassen eine nette Alternative zu globalen Variablen bereitstellt, da man diese schön strukturieren und auch schachteln kann. Dadurch bekomme ich dann die Möglichkeit des Zugriffs über z.B.
Textures.HUD.ButtonXY
Textures.Icons.Multiplayer
etc. Der Vorteil davon ist eben, dass man die ganzen geschachtelten Elemente nicht alle einzeln instantiieren braucht, da das die Runtime tut. Das ist aber eben auch gleichzeitig der größte Nachteil, da man nicht unter Kontrolle hat, wann die Klasse instantiiert wird.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

25

18.08.2016, 09:03

EDIT:
Zur Diskussion stimme ich übrigens Dots Debunking voll zu.
Ich hab noch nie ein Singleton gebraucht. Globale Variablen sind auch nicht gut, aber in einigen Fällen (zB. wegen wenig durchdachter Abhänigkeiten in der Softwarearchitektur) eine Lösung (Notlösung).
Singletons hingegen verkomplizieren das nur ohne weiteren Grund.


Ich stimme dem allgemein zu, allerdings gibt es schon ein paar Fälle, wo man etwas an sehr vielen Stellen braucht, ob man das nun als static, singleton oder globale Variable braucht, ohne dass es ein Architektur No-Go ist.
God-Objekte, die überall reingereicht werden und an denen der gesamte Kontext hängt, sind auch nicht gern gesehen.

Da Frage ich mich: wie implementiert ihr dann einen allgemeinen Logger für eine komplexe Anwendung/Spiel? Und ich meine jetzt nicht so einen popeligen File-Logger, sondern bitte einen der Kategorien, Logging in mehreren Dateien nach Kategorien und einer kummulierten Datei, asynchrones schreiben usw. unterstützt. An den Stellen, wo man einen Logger braucht, jedes mal ein Objekt erstellen, Daten schreiben, Objekt wegwerfen? Das macht den Code ja unheimlich "hübsch".

Tobiking

1x Rätselkönig

  • Private Nachricht senden

26

18.08.2016, 09:46

An den Stellen, wo man einen Logger braucht, jedes mal ein Objekt erstellen, Daten schreiben, Objekt wegwerfen? Das macht den Code ja unheimlich "hübsch".

In Java oder C# kann dir ein Dependency Injection Framework das Erstellen und der GC das wegwerfen abnehmen. Das einzige was du pro Klasse brauchst ist ein Property + evtl. Annotation.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

27

18.08.2016, 10:40

Was genau soll eine "statische Klasse" sein?

Einfach mal "statische Klasse" googlen. ;-) In C# gibt es statische Klassen. Davon erzeugst du selber keine Instanz, das macht die CLR. Die haben sogar auch statische Konstruktoren, allerdings kann man da nicht beeinflussen, wann dieser aufgerufen wird, weil du genau wie bei der GC nicht weißt, wann die intern instanziiert werden. Aus diesem Grund gibt es bei mir zusätzlich eine Methode, die ich unter Kontrolle habe.

Ich weiß schon, dass es in C# statische Klassen gibt, das war eher eine rhetorische Frage. Die gibt es dort halt imo nur als Krücke, weil man aus irgendeinem Grund keine freien Funktionen einbauen wollte. Wann etwas instanziert wird, weißt du übrigens auch mit GC; was du nicht weißt, ist, wann etwas zerstört wird... ;)

Ich glaube, wir haben uns hier missverstanden. Auch ich bin kein Freund von Singletons und habe auch noch nie einen explizit implementiert. Wir sind hier also absolut auf der gleichen Seite. Mein Beispiel sollte veranschaulichen, dass C# mit den statischen Klassen eine nette Alternative zu globalen Variablen bereitstellt, da man diese schön strukturieren und auch schachteln kann. Dadurch bekomme ich dann die Möglichkeit des Zugriffs über z.B.
Textures.HUD.ButtonXY
Textures.Icons.Multiplayer
etc. Der Vorteil davon ist eben, dass man die ganzen geschachtelten Elemente nicht alle einzeln instantiieren braucht, da das die Runtime tut. Das ist aber eben auch gleichzeitig der größte Nachteil, da man nicht unter Kontrolle hat, wann die Klasse instantiiert wird.

Öffentliche, statische Variablen sind Objekte, die von jedem Punkt im Programm aus erreichbar sind. Damit handelt es sich dabei nicht um eine Alternative zu globalen Variablen, sondern um nichts anderes als globale Variablen mit all den entsprechenden Problemen. Warum das konkrete Beispiel keine gute Lösung ist, wurde hier ja schon diskutiert... ;)

Ich stimme dem allgemein zu, allerdings gibt es schon ein paar Fälle, wo man etwas an sehr vielen Stellen braucht, ob man das nun als static, singleton oder globale Variable braucht, ohne dass es ein Architektur No-Go ist.

Globale Konstaten sind so ziemlich die einzige, potentielle Ausnahme, die mir im Moment so einfallen würde (wobei man auch damit möglichst sparsam umgehen sollte); ansonsten: für mich immer ein absolutes No-Go und ich hab noch nie ein fremdes, gutes Design gesehen, in dem derartige Elemente positive Wirkung entfaltet hätten...

Da Frage ich mich: wie implementiert ihr dann einen allgemeinen Logger für eine komplexe Anwendung/Spiel? Und ich meine jetzt nicht so einen popeligen File-Logger, sondern bitte einen der Kategorien, Logging in mehreren Dateien nach Kategorien und einer kummulierten Datei, asynchrones schreiben usw. unterstützt. An den Stellen, wo man einen Logger braucht, jedes mal ein Objekt erstellen, Daten schreiben, Objekt wegwerfen? Das macht den Code ja unheimlich "hübsch".

Nun, zuallererst bin ich kein Fan von Logging, daher hab ich Logs eigentlich ausschließlich nur in Software, die auf Rechnern deployed werden soll, auf denen richtiges Debugging voraussichtlich keine Option ist. Selbst dann gibt es mit Minidumps etc. wesentlich bessere Werkzeuge; Logging hat sich mir bisher eigentlich nur bei so Dingen wie der Diagnose von Konfigurationsproblemen als nützlich erwiesen. Aber wenn wir mal annehmen, dass wir wirklich ein Log haben wollen, dann ist ein globaler Loggingmechanismus so ziemlich das Letzte, was wir wollen. Insbesondere ein so komplexes System, wie du es beschreibst, besteht aus einem riesen Haufen von internem Zustand. Und gerade ein Logger ist die Art von globalem Objekt, die besonders schnell zur Unheilbarkeit metastasiert. Und gerade ein Logger ist eine Art von Objekt, wo wir sehr wahrscheinlich mal die Implementierung drunter switchen wollen (z.B. Logging in Files vs. Logging in was auch immer sonst wenn das ganze gerade in einem Unit Test lauft). Abgesehen davon wollen wir beispielsweise threadspezifische Logs. Aus all dem folgt, dass, wenn wir von ordentlichem Design reden wollen, gerade bei sowas wie einem Logger eigentlich kein Weg an Dependency Injection vorbeiführt. Und da man Logging in der Regel sowieso nur eher grobgranular betreibt, muss man seine Logger in der Regel nur durch wenige Layer reichen, das ist meiner Erfahrung nach in der Praxis wesentlich harmloser, als man sich das vielleicht aufs Erste vorstellen mag... ;)

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »dot« (18.08.2016, 11:10)


LInsoDeTeh

Treue Seele

Beiträge: 372

Wohnort: Essen, Deutschland

Beruf: Team Lead Inhouse-Entwicklung

  • Private Nachricht senden

28

18.08.2016, 10:47


Ich weiß schon, dass es in C# statische Klassen gibt, das war eher eine rhetorische Frage. Die gibt es dort halt imo nur als Krücke, weil man aus irgendeinem Grund keine freien Funktionen einbauen wollte. Wann etwas instanziert wird, weißt du übrigens auch mit GC; was du nicht weißt, ist wann etwas zerstört wird... ;)

Das ist mir klar, das war eine Analogie.

Öffentliche, statische Variablen sind Objekte, die von jedem Punkt im Programm aus erreichbar sind. Damit handelt es sich dabei nicht um eine Alternative zu globalen Variablen, sondern um nichts Anderes als globale Variablen... ;)

Das ist Wortklauberei, aber das weißt du ja sicher auch selbst... ;) Durch die statischen Klassen kannst du eben zusätzlich noch eine Schachtelung/Strukturierung erhalten, die ich zumindest als angenehmer empfinde, als "echte" globale Variablen, die ich erst manuell mit Instanzen irgendwelcher anderer Klassen, die irgendwelche Eigenschaften haben, initialisieren müsste.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

29

18.08.2016, 11:01

Durch die statischen Klassen kannst du eben zusätzlich noch eine Schachtelung/Strukturierung erhalten, die ich zumindest als angenehmer empfinde, als "echte" globale Variablen, die ich erst manuell mit Instanzen irgendwelcher anderer Klassen, die irgendwelche Eigenschaften haben, initialisieren müsste.

Wie würde eine "echte" globale Variable in C# deiner Meinung nach denn aussehen und was genau können die nicht, was deine statischen Variablen können? Auf Beispiele bin ich gespannt... ;)

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

30

18.08.2016, 11:39

Wie würde eine "echte" globale Variable in C# deiner Meinung nach denn aussehen und was genau können die nicht, was deine statischen Variablen können? Auf Beispiele bin ich gespannt...

dot du ziehst dich teilweise an Dingen hoch. Hier geht es doch nicht darum dass statics in C# keine globalen Variablen wären und es dafür andere Konzepte gibt. Hier wurde doch einfach gesagt dass es sich mehr oder weniger um das selbe Konzept handelt, nur dass man sie zusätzlich einer Klasse zuordnet.
Das ist wieder eine dieser vielen schwachsinnigen Diskussionen die wir hier teilweise haben. Absolut am Thema vorbei und auch nicht zielführend. Globale Variablen sind schlecht, ja. Statische Methoden braucht man in C# nun mal teilweise, bzw oft ist es eben sinnig. Dass man diese dann immer auf jeden Fall einer Klasse zuordnen muss ist eben so. So ist die Sprache aufgebaut und da können wir auch nichts dran drehen. Dann sollte man auch vielleicht einfach mal akzeptieren dass unterschiedliche Leute mit unterschiedlichen Sprachen eben unterschiedlich arbeiten. Einem muss ja nicht alles gefallen. Und ich denke wenn man dann zum gefühlt 5ten mal sagt dass man das selbst unsinnig findet und kein Beispiel kennt, ja dann ist das eben so. Ich bin auch kein Freund von Singleton oder globalen Variablen und static, ob für Funktionen oder für Variablen kommt bei mir auch eher in der Ausnahme vor. Mich muss es jetzt aber nicht stressen wenn jemand anderes meint ihm würde das helfen. Bei meinem aktuellen Job arbeiten die anderen Entwickler auch völlig anders als ich es tun würde. Da versuche ich mich eben sinnvoll einzubringen und Design zu diskutieren und am Ende entscheiden wir uns zusammen für eine Lösung. Die muss mir dann nicht gefallen, umsetzen muss ich sie trotzdem. Und wenn sich dann rausstellt dass ich recht hatte mein meine Idee das schönere Design gewesen wäre spreche ich da eben hinterher noch mal drüber wenn wir versuchen Probleme im Design zu analysieren. Beim nächsten mal kann es dann eben besser gemacht werden. Genau so kann das aber auch anders herum passieren. Zusätzlich sollte man auch drüber nachdenken dass die Welt nicht nur objekt orientiert ist. Es gibt viele andere Konzepte und in jedem kann man es übertreiben und overdesignen und sich mehr Arbeit schaffen als es nötig ist. Manchmal kann es eben auch ein kleiner Hack sein der am Ende viel Arbeit spart. Und wenn man damit dann später auf die Nase fällt weiß man es beim nächsten mal besser.
Ihr dürft hier natürlich gern weiter diskutieren wenn ihr meint das wäre in irgendeiner Form sinnvoll. Vielleicht belassen wir es aber auch einfach dabei und kehren zurück zum Thema.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige