Ich habe kürzlich darüber nachgedacht, dass manchmal mehrere Objekte voneinander abhängen (z. B. wenn sie zyklische Referenzen enthalten). Daher wäre es nützlich, sie als Teil einer atomaren Operation zu erstellen, die sicherstellt, dass die neuen Objekte nach der Konstruktion eine kollektive Einschränkung erfüllen .
Zu diesem Zweck könnte man Konstruktoren haben, die mehr als ein Objekt erstellen können. Der Programmierer würde dann den gesamten Code in einen einzigen Konstruktor einfügen, um sicherzustellen, dass die Objekte o 1 , ..., o n nach dem Erstellen alle erforderlichen Einschränkungen erfüllen (z. B. sind alle Verknüpfungen zwischen den neuen Objekten bereits vorhanden). Ich habe den Begriff kollektive Konstruktoren selbst erfunden, weil ich noch nie von einem solchen Merkmal gehört habe, aber es könnte durchaus einen akzeptierten Namen für dieses Konzept geben.
Gibt es eine Programmiersprache, die diese Art von Konstruktoren unterstützt? Wenn nicht, wurde die Idee bereits ausprobiert?
factory
Muster.A with B
Komposition von Stiltypen gearbeitet habe, deren resultierender Konstruktor im Wesentlichen den neuen Typ erstellen würde, der aus den beiden Merkmalen besteht.Antworten:
Das klingt für mich wie das Builder-Muster , eine komplexere Form einer Fabrik. Ein Java-Beispiel ist ein StringBuilder , mit dem Sie einen String erstellen und dann aufrufen,
builder.toString()
wenn Sie das unveränderliche Ergebnis wünschen. Sie können jedoch das Builder-Muster verwenden, um komplexere inhomogene Sammlungen von Objekten zu erstellen. Sie können diefriend
Semantik in einem Builder verwenden, um Zugriff auf private Variablen zu erhalten, die nach dem Erstellen des Ergebnisobjekts als unveränderlich gelten.Funktionale Sprachen könnten Inspiration liefern. Scala verfügt beispielsweise über einen veränderlichen ListBuffer , der für die Erstellungsphase verwendet und dann in eine unveränderliche Liste konvertiert werden kann .
Ein weiteres möglicherweise relevantes Konzept sind Freezable Objects , bei dem ein Objekt als veränderlich betrachtet wird, bis eine
Freeze()
Methode darauf aufgerufen wird. Ein Builder könnte die nicht gefrorenen Objekte verwenden und sie dann einfrieren, bevor er zurückkehrt.quelle
Ruby, Smalltalk, Self, Newspeak usw. haben keine Konstruktoren, sondern nur eine Namenskonvention für Factory-Methoden (z
new
. B. in Ruby). Da es sich wie bei jeder anderen Methode nur um Standardmethoden handelt, können sie alles tun, was sie wollen, einschließlich der Zuweisung und Initialisierung so vieler Objekte, wie sie möchten. Das Hauptproblem besteht darin, dass solche Factory-Methoden gemäß Konvention ein einzelnes Objekt zurückgeben, das eine Instanz der Klasse ist, für die die Factory-Methode aufgerufen wurde. Dh beim AufrufenFoo.new
wird erwartet, dass Sie ein einzelnes Objekt zurückerhalten, das eine Instanz von istFoo
. Bei ausreichender Dokumentation können Sie jedoch eine Struktur (z. B. eineArray
) mehrerer neuer Objekte zurückgeben.Beispiel:
In ECMAScript sind Konstruktoren nur reguläre Prozeduren, oder vielmehr kann jede Prozedur als Konstruktor verwendet werden, indem einfach das
new
Schlüsselwort davor gesetzt wird. Da es sich nur um reguläre Verfahren handelt, können sie alles tun, was sie wollen.quelle
Zyklische Abhängigkeiten zwischen den Objekten? Dann lautet die Antwort "Verwenden Sie (nur) keinen Konstruktor", da zyklische Methodenaufrufe keinen Sinn ergeben. Stattdessen ist dies ein klassisches Szenario für einige Factory-Methoden .
Hier ist ein Beispiel (in PHP), das irgendwie albern ist, aber die allgemeine Idee veranschaulicht: Sie können kein
Sprocket
ohne zugehöriges erstellenWidget
und umgekehrt. Jedes Objekt hat einen Verweis auf das andere, sobald es verfügbar ist.Wenn ich dies in PHP 5.2 im wirklichen Leben tun müsste, würde ich die Konstruktoren einfach öffentlich lassen und den Leuten sagen , dass sie sie nicht verwenden sollen . Stattdessen hätte ich eine
makeWidgetWithSprocket()
Funktion. Wenn die Sprache Java wäre, würde ich die Sichtbarkeitssteuerelemente auf Paketebene verwenden, um Fehler weiter zu vermeiden.Zusätzliche Lektüre:
create()
, berücksichtigen Sie das Builder-Muster .quelle