Herzliche Glückwünsche! Sie haben gerade den Globus des Programmiersprachen- / Typensystems umrundet und sind auf der anderen Seite der Welt angekommen, von wo aus Sie abgereist sind. Sie sind gerade an der Grenze von Land mit dynamischer Sprache / Prototypen gelandet!
In vielen dynamischen Sprachen (z. B. JavaScript, PHP, Python) können Objekteigenschaften zur Laufzeit erweitert oder geändert werden.
Die extreme Form davon ist eine prototypbasierte Sprache wie Self oder JavaScript. Sie haben streng genommen keinen Unterricht. Sie können Dinge tun, die wie klassenbasierte, objektorientierte Programmierung mit Vererbung aussehen, aber die Regeln sind im Vergleich zu schärfer definierten, klassenbasierten Sprachen wie Java und C # erheblich gelockert.
Sprachen wie PHP und Python leben im Mittelfeld. Sie haben regelmäßige, idiomatische klassenbasierte Systeme. Objektattribute können jedoch zur Laufzeit hinzugefügt, geändert oder gelöscht werden - allerdings mit einigen Einschränkungen (z. B. "außer für integrierte Typen"), die Sie in JavaScript nicht finden.
Der große Kompromiss für diese Dynamik ist die Leistung. Vergessen Sie, wie stark oder schwach die Sprache getippt ist oder wie gut sie bis zum Maschinencode kompiliert werden kann. Dynamische Objekte müssen als flexible Maps / Wörterbücher und nicht als einfache Strukturen dargestellt werden. Dies erhöht den Aufwand für jeden Objektzugriff. Einige Programme sind sehr bemüht, diesen Overhead zu reduzieren (z. B. mit Phantom-Warg-Zuweisung und slotbasierten Klassen in Python), aber der zusätzliche Overhead ist in der Regel nur eine Frage des Kurses und des Eintrittspreises.
Kehren Sie zu Ihrem Entwurf zurück und übertragen Sie die Fähigkeit, dynamische Eigenschaften auf eine Teilmenge Ihrer Klassen zu übertragen. A Product
kann variable Attribute haben; vermutlich ein Invoice
oder ein Order
würde und konnte nicht. Es ist kein schlechter Weg. Es gibt Ihnen die Flexibilität, Variationen dort zu haben, wo Sie sie benötigen, und bleibt dabei in einem strengen, disziplinierten Sprach- und Typensystem. Auf der anderen Seite sind Sie für die Verwaltung dieser flexiblen Eigenschaften verantwortlich. Möglicherweise müssen Sie dazu Mechanismen verwenden, die sich geringfügig von den nativen Attributen unterscheiden. p.prop('tensile_strength')
eher als p.tensile_strength
zum Beispiel und p.set_prop('tensile_strength', 104.4)
eher alsp.tensile_strength = 104.4
. Aber ich habe mit vielen Programmen in Pascal, Ada, C, Java und sogar in dynamischen Sprachen gearbeitet und sie erstellt, die genau diesen Get-Set-Zugriff für nicht standardmäßige Attributtypen verwendeten. Der Ansatz ist klar umsetzbar.
Im Übrigen ist diese Spannung zwischen statischen Typen und einer sehr unterschiedlichen Welt äußerst verbreitet. Ein analoges Problem tritt häufig beim Entwerfen eines Datenbankschemas auf, insbesondere für relationale und vorrelationale Datenspeicher. Manchmal geht es darum, "Super-Zeilen" zu erstellen, die genügend Flexibilität enthalten, um die Vereinigung aller vorgestellten Variationen zu enthalten oder zu definieren, und dann alle Daten, die in diese Felder gelangen, zu stopfen. Die Wordpress - wp_posts
Tabelle , zum Beispiel, haben Felder wie comment_count
, ping_status
, post_parent
und post_date_gmt
, die nur unter bestimmten Umständen interessant, und dass in der Praxis oft leer gehen. Ein anderer Ansatz ist ein sehr sparsamer, normalisierter Tisch wp_options
, ähnlich wie IhrProperty
Klasse. Es ist zwar eine explizitere Verwaltung erforderlich, die darin enthaltenen Elemente sind jedoch selten leer. Objektorientierte Datenbanken und Dokumentendatenbanken (z. B. MongoDB) haben es oft leichter, Optionen zu ändern, da sie Attribute nach Belieben erstellen und festlegen können.