J'ai essayé de créer une classe parent d'objet de valeur dans Ruby

J'ai essayé de créer un objet de valeur en raison de la conception axée sur le domaine, mais c'était assez gênant, j'ai donc créé une classe parent. (Comme il est conçu pour le développement personnel afin d'accélérer le développement, nous ne garantissons pas qu'il puisse être utilisé tel quel dans le produit)

Qu'est-ce qu'un objet de valeur?

https://qiita.com/kichion/items/151c6747f2f1a14305cc C'est un objet avec les caractéristiques décrites dans.

Si vous l'écrivez en Ruby, ce sera un objet comme ↓. Cet exemple est un objet de valeur qui contient le nom de l'utilisateur. (Si vous voulez faire une définition légitime, il serait préférable de définir quelque chose comme ʻequal`, mais je ne l'utilise pas tellement, donc je ne l'ai pas défini maintenant.)

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

C'est pratique à utiliser, mais c'est un problème d'écrire quelques lignes de getters et de setters dans ce champ de routine. J'ai donc créé une classe parente qui les définit arbitrairement.

Classe parent de l'objet de valeur

domain/base/value_object.rb


module Domain::Base
  class ValueObject
    attr_reader :changed_fields

    FIELDS = []

    class << self
      #Définissez la méthode suivante new_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
    # -Fondamentalement, seuls les CHAMPS et les accesseurs sont définis du côté de l'objet de valeur.
    # -initialize permet au parent d'utiliser cette classe d'objets.
    # -Il est possible d'implémenter votre propre initialisation. Cependant, dans ce cas, seule l'initialisation de cette classe parente est utilisée du côté de l'objet de valeur, et l'utilisateur d'objet de valeur n'est pas autorisé à utiliser directement l'initialisation de cette classe.
    #   - changed_Les modifications telles que les champs sont effectuées uniquement en interne
    #   -Veillez à ce que les arguments d'initialisation de l'objet valeur lui-même soient aussi simples que possible
    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

En utilisant cela, la méthode originale peut être fournie par la méthode d'écriture suivante.

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

Remarques

――Si vous utilisez trop de magie noire de la métaprogrammation, vous ne pourrez pas la suivre (que ce soit grep ou visuellement), nous n'avons donc pas défini de méthodes compliquées ――Vous pouvez automatiser ʻattr_reader, mais ʻattr_reader ne pèse pas sur le lecteur, donc je suis la méthode d'écriture de base Ruby. ――Cette façon d'écrire indique implicitement que les arguments doivent être entrés dans l'ordre spécifié par FILED au moment de ʻinitialize, et je ne l'ai pas spécifié, mais je connais le problème moi-même, alors maintenant Il est évité par l'opération. --changed_fields` a été créé comme vous le souhaitez parce que je voulais mettre à jour uniquement les champs qui ont été mis à jour lorsque la base de données a été mise à jour.

Recommended Posts

J'ai essayé de créer une classe parent d'objet de valeur dans Ruby
J'ai créé un client RESAS-API en Java
J'ai essayé d'utiliser pleinement le cœur du processeur avec Ruby
J'ai essayé de créer une fonction de connexion avec Java
Mappage à une classe avec un objet de valeur dans How to My Batis
J'ai essayé un problème de calendrier avec Ruby
J'ai essayé d'écrire du code comme une déclaration de type en Ruby
J'ai essayé de faire un Numeron qui n'est pas bon avec Ruby
Je veux changer la valeur de l'attribut dans Selenium of Ruby
Je voulais que (a == 1 && a == 2 && a == 3) vrai en Java
J'ai essayé de créer une application de conversation en Java à l'aide de l'IA «A3RT»
Je veux obtenir la valeur en Ruby
J'ai essayé de créer un exemple de programme en utilisant le problème du spécialiste des bases de données dans la conception pilotée par domaine
Nommer et appeler explicitement des méthodes de classe parent dans Ruby
Je veux appeler une méthode d'une autre classe
J'ai essayé de créer une compétence Clova en Java
[Ruby / Rails] Définissez une valeur unique (unique) dans la classe
J'ai essayé de créer une fonction de message de l'extension Rails Tutorial (Partie 1): Créer un modèle
J'ai essayé de faire une demande en 3 mois d'inexpérimenté
Je souhaite créer un modèle spécifique d'ActiveRecord ReadOnly
Je voulais juste créer une propriété réactive en Java
J'ai brièvement résumé la grammaire de base de Ruby
J'ai essayé de convertir une chaîne de caractères en un type LocalDate en Java
Je veux créer un fichier Parquet même en Ruby
J'ai essayé d'implémenter une application web pleine de bugs avec Kotlin
J'ai essayé de résumer l'orientation de l'objet à ma manière.
J'ai essayé de faire une fonction de réponse de l'extension Rails Tutorial (Partie 3): Correction d'un malentendu des spécifications
J'ai essayé de convertir l'exemple d'application en microservice selon l'idée du livre "Microservice Architecture".
J'ai essayé de créer une fonction de message pour l'extension Rails Tutorial (Partie 2): Créer un écran à afficher
[VBA] J'ai créé un outil pour convertir le type primitif de la classe Entity générée par Hibernate Tools en type de référence correspondant.
J'ai essayé de résoudre le problème de la "sélection multi-étapes" avec Ruby
J'ai essayé de créer une application cartographique simple dans Android Studio
J'ai essayé d'implémenter le traitement Ajax de la fonction similaire dans Rails
J'ai essayé d'illuminer le sapin de Noël dans un jeu de la vie
[Unity] J'ai essayé de créer un plug-in natif UniNWPathMonitor en utilisant NWPathMonitor
J'ai essayé d'approfondir ma compréhension de l'orientation des objets de n%
[Java] J'ai essayé de faire un labyrinthe par la méthode de creusage ♪
J'ai essayé de créer une fonction de groupe (babillard) avec Rails
[Rails] Implémentation de la fonction de catégorie multicouche en utilisant l'ascendance "J'ai essayé de créer une fenêtre avec Bootstrap 3"
J'ai essayé d'exprimer les résultats avant et après de la classe Date avec une ligne droite numérique
J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part2 ~ Façon basique d'écrire Dash ~
Notez les arguments de mot-clé Ruby
J'ai essayé d'incorporer une formule dans Javadoc
J'ai essayé de créer une simple application Android de reconnaissance faciale en utilisant OpenCV
[Rails] Je souhaite envoyer des données de différents modèles dans un formulaire
Étapes pour rendre Spring Boot capable de faire référence à la valeur dans le fichier de propriétés
[iOS] J'ai essayé de créer une application de traitement de type insta avec Swift
J'ai essayé de créer une API Web qui se connecte à DB avec Quarkus
[Ruby] Je souhaite extraire uniquement la valeur du hachage et uniquement la clé
J'ai créé un bot de transaction d'arbitrage de monnaie virtuelle et essayé de gagner de l'argent
J'ai essayé de résoudre le problème de la séquence Tribonacci en Ruby, avec récurrence.
[Ruby] Je souhaite afficher les éléments publiés par ordre de date la plus récente
Comment changer la valeur d'une variable à un point d'arrêt dans intelliJ