Hallo,
Im Allgemeinen halte ich folgende Architektur für sinnvoll:
- OOP mit Konstruktoren und Instanzen, d.h. Nutzung von prototypische Delegation
- Singletons vermeiden
- Model-View-Controller mit Trennung von Daten- und DOM-Logik
- Durch Routing wird JavaScript-Code für bestimmte Seiten ausgeführt (das Kriterium kann die URL sein oder das DOM)
- Modularisierung mit AMD-, Common.js- oder ECMAScript-6-Modulen
- Größtmögliche Kapselung, sodass idealerweise keine Objekte global erreichbar sind
- Sinnvolle Speicherbereinigung – Objekte werden geordnet abgebaut und ihre Referenzen entfernt, wenn der zugehörige UI-Kontext verlassen wird
Diese Regeln gelten für größere JavaScript-Anwendungen, sind aber auch für mit etwas JavaScript angereicherte Seiten hilfreich. Viele Pattern der obigen Liste werden von einfachen Bibliotheken wie Backbone.js oder Can.js abgedeckt.
- Allgemeingültige JS für alle Seiten/Gruppen
Common.Domhelper.toggleButton();
Ein Button wäre aus OOP-Sicht auch nur eine weitere Interfacekomponente. Solche Logik gehört in eine View-Klasse oder ein darin verfügbaren DOM-Toolkit.
Falls es ein DOM-Toolkit ist, so würde ich mir eine bessere API überlegen. Eine jQuery-/Zepto-/DOMAssistant-artige hat sich hier durchgesetzt. Falls irgendwann ein anderer daran arbeiten soll, würde ich definitiv für jQuery votieren.
Common.Ajax.getXYData();
Solche Logik gehört in eine Model-Klasse oder, falls es sich um einen generischen HTTP-Adapter handelt, in eine Service-Klasse.
- JS für eine bestimmte Gruppe
Object.Handlecontrols.getABCId();
Sieht nach View-Logik aus.
Object.States.getObjectState()
Sieht nach Model-Logik aus.
- JS, die nur auf einer bestimmten Seite Verwendung finden
ObjectPart.Calculation.getMonthRate();
Sieht nach einer Service-Klasse aus, die idealerweise rein funktional arbeitet (ohne Zustände, ohne Nebenwirkungen). Ansonsten ist es eine einfache Klasse mit Eingabewerten und Methoden.
ObjectPart.ButtonStates.setButtonDisabled("buttonid");
Wieder ein Fall für eine Button-View-Klasse.
Das hätte für mich den Vorteil, das ich dann, wenn alles zusammengeneriert wird, sofort erkennen kann, wo die entsprechende Funktionalität steckt.
Dafür sind eher Modulformate gedacht. AMD, Common.js oder ECMAScript-6-Module, welche man zu ECMAScript 5 »transpilieren« kann. So kann man den Code sinnvoll in Dateien aufteilen und sie in einer Weise verbinden, dass die Abhängigkeiten ersichtlich (und maschinenlesbar) sind.
Die Methoden sind überwiegend "statischer" Natur, abundzu macht es sicher Sinn ein Art von Objekten für bestimmte Zustände von "Gruppen" vor zu halten.
Das ist m.E. das Problem. Ich würde dagegen votieren, für alles statische Methoden anzulegen. Klassen sind besser automatisiert testbar und eignen sich besser, um Zustände zu speichern, Funktionalität zu kapseln und Code wiederzuverwenden.
Grüße,
Mathias