Ich habe versucht, ein übergeordnetes Wertklasseobjekt in Ruby zu erstellen

Ich habe versucht, ein Wertobjekt aufgrund des domänengesteuerten Designs zu erstellen, aber es war ziemlich problematisch, daher habe ich eine übergeordnete Klasse erstellt. (Da es für die persönliche Entwicklung entwickelt wurde, um die Entwicklung zu beschleunigen, können wir nicht garantieren, dass es so verwendet werden kann, wie es im Produkt enthalten ist.)

Was ist ein Wertobjekt?

https://qiita.com/kichion/items/151c6747f2f1a14305cc Es ist ein Objekt mit den in beschriebenen Eigenschaften.

Wenn Sie es in Ruby schreiben, ist es ein Objekt wie ↓. Dieses Beispiel ist ein Wertobjekt, das den Namen des Benutzers enthält. (Wenn Sie eine legitime Definition vornehmen möchten, ist es besser, etwas wie "gleich" zu definieren, aber ich verwende es nicht so oft, sodass ich es jetzt nicht definiert habe.)

domain/user/name.rb


module Domain::User
  class Name
    attr_reader :first_name, :last_name

    def initialize(first_name, last_name)
      @first_name = first_name
      @last_name = last_name
    end

    def update_first_name(first_name)
      self.new(first_name, @last_name)
    end

    def update_last_name(last_name)
      self.new(@first_name, last_name)
    end

    def fullname
      "#{@last_name} #{@first_name}"
    end
  end
end

Es ist bequem zu bedienen, aber es ist mühsam, ein paar Zeilen mit Gettern und Setzern in dieses Routinefeld zu schreiben. Also habe ich eine übergeordnete Klasse erstellt, die diese willkürlich definiert.

Übergeordnetes Wertklasseobjekt

domain/base/value_object.rb


module Domain::Base
  class ValueObject
    attr_reader :changed_fields

    FIELDS = []

    class << self
      #Definieren Sie die folgende Methode neu_date = date.update_month(11)
      def attr_updater(*attrs)
        attrs.map(&:to_sym).each do |defining_attr|

          define_method("update_#{defining_attr}") do |defining_value|
            values = attrs.map { |attribute| attribute == defining_attr ? defining_value : instance_variable_get("@#{attribute}")}
            changed_fields = @changed_fields.include?(defining_attr) ? @changed_fields : @changed_fields + [defining_attr]
            self.class.new(*values, changed_fields: changed_fields)
          end

        end
      end
    end

    # NOTE
    # -Grundsätzlich werden auf der Wertobjektseite nur FELDER und Accessoren definiert.
    # -Mit initialize kann der Elternteil diese Klasse von Dingen verwenden.
    # -Es ist möglich, eine eigene Initialisierung zu implementieren. In diesem Fall wird jedoch nur die Initialisierung dieser übergeordneten Klasse von der Wertobjektseite verwendet, und der Benutzer des Wertobjekts darf die Initialisierung dieser Klasse nicht direkt verwenden.
    #   - changed_Änderungen wie Felder werden nur intern vorgenommen
    #   -Achten Sie darauf, die Initialisierungsargumente des Wertobjekts selbst so einfach wie möglich zu halten
    def initialize(*field_values, fields: self.class::FIELDS, changed_fields: [])
      define_fields(fields, field_values)
      @changed_fields = changed_fields
    end

    private

    def define_fields(fields, field_values)
      fields.zip(field_values).each do |field, field_value|
        instance_variable_set("@#{field}", field_value)
      end
    end
  end
end

Auf diese Weise kann die ursprüngliche Methode durch die folgende Schreibmethode bereitgestellt werden.

domain/user/name.rb


module Domain::User
  class Name < ::Domain::Base::ValueObject
    FIELDS = %I(first_name last_name)
    attr_reader *FIELDS
    attr_updater*FIELDS

    def fullname
      "#{@last_name} #{@first_name}"
    end
  end
end

Bemerkungen

――Wenn Sie zu viel schwarze Magie der Metaprogrammierung verwenden, können Sie dieser nicht folgen (ob grep oder visuell), daher haben wir keine komplizierten Methoden definiert ――Sie können attr_reader automatisieren, aber wenn Sie attr_reader haben, wird der Leser nicht belastet, daher folge ich dem grundlegenden Ruby-Schreibstil. ――Diese Schreibweise gibt implizit an, dass die Argumente in der Reihenfolge eingegeben werden sollten, die zum Zeitpunkt der Initialisierung in FILED angegeben ist, und ich habe sie nicht angegeben, aber ich kenne das Problem selbst, also jetzt Es wird durch die Operation vermieden. --changed_fields wurde nach Ihren Wünschen erstellt, da ich nur die Felder aktualisieren wollte, die bei der Aktualisierung der Datenbank aktualisiert wurden.

Recommended Posts

Ich habe versucht, ein übergeordnetes Wertklasseobjekt in Ruby zu erstellen
Ich habe einen RESAS-API-Client in Java erstellt
Ich habe versucht, den CPU-Kern mit Ruby voll auszunutzen
Ich habe versucht, eine Anmeldefunktion mit Java zu erstellen
Zuordnung zu einer Klasse mit einem Wertobjekt in How to My Batis
Ich habe ein Kalenderproblem mit Ruby versucht
Ich habe versucht, Code wie eine Typdeklaration in Ruby zu schreiben
Ich habe versucht, einen Numeron zu erstellen, der mit Ruby nicht gut ist
Ich möchte den Wert von Attribute in Selenium of Ruby ändern
Ich wollte (a == 1 && a == 2 && a == 3) in Java wahr machen
Ich habe versucht, mit AI "A3RT" eine Talk-App in Java zu erstellen.
Ich möchte den Wert in Ruby erhalten
Ich habe versucht, ein Beispielprogramm mit dem Problem des Datenbankspezialisten für domänengesteuertes Design zu erstellen
Benennen und rufen Sie in Ruby übergeordnete Klassenmethoden explizit auf
Ich möchte eine Methode einer anderen Klasse aufrufen
Ich habe versucht, eine Clova-Fähigkeit in Java zu erstellen
[Ruby / Rails] Legen Sie einen eindeutigen (eindeutigen) Wert in der Klasse fest
Ich habe versucht, eine Nachrichtenfunktion der Rails Tutorial-Erweiterung (Teil 1) zu erstellen: Erstellen Sie ein Modell
Ich habe versucht, innerhalb von 3 Monaten einen Antrag von unerfahren zu stellen
Ich möchte ein bestimmtes Modell von ActiveRecord ReadOnly erstellen
Ich wollte nur eine reaktive Eigenschaft in Java erstellen
Ich habe die grundlegende Grammatik von Ruby kurz zusammengefasst
Ich habe versucht, in Java von einer Zeichenfolge in einen LocalDate-Typ zu konvertieren
Ich möchte eine Parkettdatei auch in Ruby erstellen
Ich habe versucht, eine Webanwendung voller Fehler mit Kotlin zu implementieren
Ich habe versucht, die Objektorientierung auf meine Weise zusammenzufassen.
Ich habe versucht, eine Antwortfunktion für die Rails Tutorial-Erweiterung (Teil 3) zu erstellen: Ein Missverständnis der Spezifikationen wurde behoben
Ich habe versucht, die Beispielanwendung gemäß der Idee des Buches "Micro Service Architecture" in einen Mikrodienst zu verwandeln.
Ich habe versucht, eine Nachrichtenfunktion für die Erweiterung Rails Tutorial (Teil 2) zu erstellen: Erstellen Sie einen Bildschirm zum Anzeigen
[VBA] Ich habe ein Tool erstellt, um den primitiven Typ der von Hibernate Tools generierten Entity-Klasse in den entsprechenden Referenztyp zu konvertieren.
Ich habe versucht, das Problem der "mehrstufigen Auswahl" mit Ruby zu lösen
Ich habe versucht, eine einfache Karten-App in Android Studio zu erstellen
Ich habe versucht, die Ajax-Verarbeitung der ähnlichen Funktion in Rails zu implementieren
Ich habe versucht, den Weihnachtsbaum in einem Lebensspiel zu beleuchten
[Unity] Ich habe mit NWPathMonitor ein natives Plug-In UniNWPathMonitor erstellt
Ich habe versucht, mein Verständnis der Objektorientierung um n% zu vertiefen
[Java] Ich habe versucht, mit der Grabmethode ein Labyrinth zu erstellen ♪
Ich habe versucht, mit Rails eine Gruppenfunktion (Bulletin Board) zu erstellen
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Ich habe versucht, ein Fenster mit Bootstrap 3 zu erstellen"
Ich habe versucht, die Ergebnisse vor und nach der Date-Klasse mit einer geraden Zahl auszudrücken
Ich habe eine App für maschinelles Lernen mit Dash (+ Docker) Teil 2 ~ Grundlegende Schreibweise für Dash ~ erstellt
Notieren Sie sich die Ruby-Schlüsselwortargumente
Ich habe versucht, eine Formel in Javadoc einzubetten
Ich habe versucht, eine einfache Gesichtserkennungs-Android-Anwendung mit OpenCV zu erstellen
[Rails] Ich möchte Daten verschiedener Modelle in einem Formular senden
Schritte zum Ausführen von Spring Boot beziehen sich auf die Werte in der Eigenschaftendatei
[iOS] Ich habe versucht, mit Swift eine insta-ähnliche Verarbeitungsanwendung zu erstellen
Ich habe versucht, eine Web-API zu erstellen, die mit Quarkus eine Verbindung zur Datenbank herstellt
[Ruby] Ich möchte nur den Wert des Hash und nur den Schlüssel extrahieren
Ich habe einen Arbitrage-Transaktionsbot für virtuelle Währungen erstellt und versucht, Geld zu verdienen
Ich habe versucht, das Problem der Tribonacci-Sequenz in Ruby mit Wiederholung zu lösen.
[Ruby] Ich möchte veröffentlichte Artikel in der Reihenfolge des neuesten Datums anzeigen
So ändern Sie den Wert einer Variablen an einem Haltepunkt in IntelliJ