Ich kann diese Methode nicht für gut heißen und auch nicht empfehlen.
Was hier beschrieben wird, hat nichts mit echtem modularen Code-Aufbau zu tun, sondern verteilt den eigentlichen Code nur in unzählige Includes, was den Code nur verteilt und sonst keinen Mehrwert bringt, der die Nachteile davon überwiegen würde. Es wird ein falscher Eindruck von Modularem Coding vermittelt.
Unter Modularem Coding versteht man nämlich im weitesten Sinne:
- Einzelne Planung und Aufbau von Software-Paketen, die voneinander unabhängig funktionieren
- Erstellung von universellen Modulen, die mehrfach wiederverwendet werden können
- Die Nutzung wird in der Regel über Klassen/Libraries realisiert, die beliebig implementiert werden können
Weitere Informationen zu echter modularer Programmierung: https://de.wikipedia.org/wiki/Modulare_Programmierung bzw. https://en.wikipedia.org/wiki/Modular_programming
Keiner der oben genannten Aspekte trifft auf die hier beschriebene Logik zu.
Es erzeugt deutlich mehr Verkomplizierungen, wenn man seine Systeme in Includes auslagert.
Beispielsweise kann man in den Includes dann keine systemübergreifenden Funktionen einbauen, ohne dass diese im falschen Include stehen.
Stellen wir uns mal vor, man hat ein Banksystem und ein Autohaussystem. Die Include des Banksystems steht vor der Include des Autohaussystems im Code. Dinge wie z.B. #define GetCarValue(%0) carInfo[%0][cValue] können dann nicht im Banksystem verwendet werden. Auf den ersten Blick mag dies auch nicht notwendig sein. Denkt man aber nur einen Schritt weiter, dann kann dies durchaus notwendig sein. Man muss sich nur vorstellen, man kann ein Fahrzeug Leasen und will die Bankrate entsprechend es Fahrzeug-Werts berechnen. In welches System (und damit in welche Include) gehört der Leasing-Vertrag dann, der mit der Bank aber im Autohaus abgeschlossen wird? Oder ein entsprechender Kreditvertrag, bei dem die Fahrzeug-Papiere bei der Bank hinterlegt werden? Natürlich kommt man über stock-Funktionen etc. an die Werte auch im Banksystem hin, darum geht es nicht. Man verkompliziert sich den Aufbau und wird niemals eine 100%'ige Trennung hinbekommen. In zig Threads zur Code-Optimierung wird gepredigt, keine unnötigen Funktionen aufzubauen, was man mit dieser Variante aber sehr wohl machen müsste.
Zusätzlich, und das ist der springende Punkt an diesem Beispiel, vermischen sich die beiden Beispiele hier. Man wird daher nicht zwingend alle Punkte, die ein Autohaus betreffen, auch in der Autohaus-Include haben. Ich werde jetzt nicht dutzende Beispiele bringen, die durch diese Methode schlechter werden, das Beispiel genügt.
Zusätzlich, stellen wir uns doch mal vor, wir haben ein Flughafen-System und ein Bahnhof-System. Hat man nun zum Beispiel in einem Timer eine Prüfung drin, die überprüft, ob der Spieler an einem Flughafen oder einem Bahnhof ist, und dann irgendetwas ausführt, dann geht dies hier nicht ohne weiteres. Normales Verhalten wäre ein 1-Sekunden-Timer (oder was auch immer), der prüft, ob der Spieler entweder am Bahnhof oder am Flughafen ist. Das klappt hier nicht, da man beides nicht in eine Include packen kann. Somit hat man zwei Timer und somit hat man auch erneut das Gegenteil von der hier als nicht vorhanden genannten Performanceverschlechterung erreicht.
Es gibt natürlich noch deutlich mehr und deutlich komplexere Logiken, bei denen Systeme ineinandergreifen müssen, um korrekt zu funktionieren. Das ist immer vom jeweiligen Gamemode abhängig.
Um nochmal auf die Ressourcen zurück zu kommen. Bisher hat man ein Callback im Code, dort steht alles drin. Hookt man das Callback jetzt in 10 Includes, dann muss in jedem Callback beispielsweise eine Variable "string[145]" zur Ausgabe von Nachrichten deklariert werden. Auch hier wird in unzähligen Threads geschrieben, dass man die mehrfache Deklaration von Variablen nach Möglichkeit vermeiden soll. Hier würde man dies explizit machen und sich daher den x-fachen Speicher anhäufen. Dies nur als einzelnes Beispiel.
Wie man an den Beispielen aber sieht, ist diese hier sogenannte "modulare Programmierung" (was es nicht ist!) hier nur in der Theorie gegeben, sieht auf dem Papier schön aus, macht es in der Praxis aber nur unnötig kompliziert.
Wofür sind Includes eigentlich gedacht? Includes sind dafür gemacht, wie oben in den Punkten genannt, fertige Funktionen, die unabhängig voneinander funktionieren, in den Code einzubinden, zum Beispiel einen Checkpoint-Streamer. Im Prinzip nichts anderes als Libraries in Java zum Beispiel. Niemand würde in Java auf die Idee kommen, seinen gesamten Code in Libraries auszulagern. So sollte auch in PAWN niemand auf die Idee kommen, seinen Code in Includes auszulagern.
Der Ansatz, wie er hier als schlecht beschrieben wird, Funktionen in Includes zu trennen, bringt technisch gesehen zwar nichts, wird aber sehr häufig in der Praxis verwendet, um gigantische Code-Dateien zu vermeiden. Ein Beispiel aus meinem Alltag sind zum Beispiel SAP Reports, diese sind , bei deutlicher Komplexität, öfters auch so aufgebaut, dass es eine Include gibt (TOP-Include), welche alle Deklarationen beinhaltet, eine Include, welche die Selektions-GUI beinhaltet und diverse Includes, welche die jeweilig getrennten Funktionen beinhalten. Dies kann man machen, muss man aber nicht. Ich persönlich (meine Meinung) finde diesen Ansatz in der Regel trotzdem nicht sinnvoll, da im Falle von SAP z.B. eine Möglichkeit besteht, Code direkt in der Ausführung zu debuggen. Springt man ständig durch die Includes, fehlt oftmals die Verbindung zwischen den Funktionen und auch für Anpassungen muss man oftmals durch diverse Includes springen, um alle Anpassungen machen zu können.
Fazit:
Eine Trennung der Logik kann und sollte nicht über Includes realisiert werden, aus oben genannten Gründen, welche im Wesentlichen aus der unnötigen Verkomplizierung vom Aufbau des Codes bestehen und der nicht sauber vorhandenen Trennbarkeit von Systemen.
Zudem hat der beschriebene Ansatz im Tutorial nichts mit der tatsächlichen Idee der Modularen Programmierung zu tun und vermittelt ein falsches Bild dessen.
Includes sollten dafür genutzt werden, wofür sie auch gemacht sind. Um Funktionen unabhängig und in mehreren Codes einbinden zu können.
Ich kann nur hoffen, niemand verbiegt sich hierdurch unnötigerweise seinen Code.