Maison >développement back-end >Golang >vogen - Générateur d'objets de valeur dans Golang

vogen - Générateur d'objets de valeur dans Golang

DDD
DDDoriginal
2024-12-29 14:41:11224parcourir

vogen - Value Object Generator in golang

Introduction

Comprenez-vous la conception pilotée par domaine (DDD) ? Je n’ai toujours pas réussi à le comprendre complètement.

Récemment, je me suis plongé dans des livres sur la conception pilotée par domaine (DDD). En DDD, la notion d'Objet Valeur apparaît. Un Objet Valeur présente principalement les caractéristiques suivantes (les éléments sans rapport avec le sujet principal de cet article sont intentionnellement omis) :

  • Immuable
  • Les objets sont considérés comme égaux lorsque leurs valeurs sont équivalentes

Pour satisfaire aux spécifications ci-dessus dans Golang, l'implémentation devrait ressembler à ceci :

type Person struct {
    name string
}

func NewPerson(name string) Person {
    return Person{name: name}
}

func (o Person) Name() string {
    return o.name
}

func (o Person) Equal(other Person) bool {
    return o.Name() == other.Name() 
}

Franchement, implémenter ce genre de fonctionnalité est une véritable galère. De plus, écrire des tests unitaires pour Getter() ou Equal() semble inutile. Je me suis souvent demandé : « Si seulement Golang avait quelque chose comme la classe de valeurs ou la classe de données de Kotlin. »

Génère du code objet de valeur

Le package nao1215/vogen est une bibliothèque qui génère automatiquement du code Value Object avec les méthodes New(), Getter et Equal(). Le nom signifie "Value Object Generator".

Avec cette bibliothèque, vous écrivez des métadonnées pour les objets de valeur dans Golang, et sur la base de ces métadonnées, le code est automatiquement généré. L'inspiration pour cette spécification vient de shogo82148/myddlmaker (une bibliothèque qui génère DB DDL à partir de métadonnées).

Utilisation prévue

L'utilisation typique consiste à définir des métadonnées dans value_object/gen/main.go et à exécuter go generate ./... pour générer le fichier value_object/value_object.go. Il est également possible de répartir la sortie sur plusieurs fichiers.

Vous trouverez ci-dessous un exemple d'implémentation pour value_object/gen/main.go.

package main

import (
    "fmt"
    "path/filepath"

    "github.com/nao1215/vogen"
)

//go:generate go run main.go

func main() {
    // Step 1: Create a Vogen instance with custom file path and package name.
    // By default, the file path is "value_objects.go" and the package name is "vo".
    gen, err := vogen.New(
        vogen.WithFilePath(filepath.Join("testdata", "example_output.go")),
        vogen.WithPackageName("vo_example"),
    )
    if err != nil {
        fmt.Printf("Failed to create Vogen instance: %v\n", err)
        return
    }

    // Step 2: Append the ValueObject definition
    if err := gen.AppendValueObjects(
        vogen.ValueObject{
            StructName: "Person",
            Fields: []vogen.Field{
                {Name: "Name", Type: "string", Comments: []string{"Name is the name of the person."}},
                {Name: "Age", Type: "int", Comments: []string{"Age is the age of the person."}},
            },
            Comments: []string{
                "Person is a Value Object to describe the feature of vogen.",
                "This is sample comment.",
            },
        },
        // Use auto generated comments.
        vogen.ValueObject{
            StructName: "Address",
            Fields: []vogen.Field{
                {Name: "City", Type: "string"},
            },
        },
    ); err != nil {
        fmt.Printf("Failed to append ValueObject: %v\n", err)
        return
    }

    // Step 3: Generate the code
    if err := gen.Generate(); err != nil {
        fmt.Printf("Failed to generate code: %v\n", err)
        return
    }
}

Dans vogen.New(), vous pouvez spécifier le chemin du fichier et le nom du package pour le code généré, mais ceux-ci sont facultatifs. En cas d'omission, un fichier value_objects.go sera généré par défaut sous le package vo.

vogen.ValueObject() correspond aux métadonnées. Les commentaires pour la structure et ses champs sont facultatifs. En cas d'omission, la sortie inclura des commentaires en anglais sans âme. Pour les types, vous pouvez spécifier des types définis (types définis par l'utilisateur), mais dans de tels cas, vous devez également fournir le chemin du module. Les types définis n’ayant pas encore été testés, je les ai délibérément omis de l’exemple de code (des tests sont prévus pour plus tard).

Code généré automatiquement

Vous trouverez ci-dessous le code généré automatiquement à partir de l'exemple ci-dessus :

// Code generated by vogen. DO NOT EDIT.
package vo_example

import (
    "fmt"
)

// Person is a Value Object to describe the feature of vogen.
// This is sample comment.
type Person struct {
    // Name is the name of the person.
    name string
    // Age is the age of the person.
    age int
}

// NewPerson creates a new instance of Person.
func NewPerson(name string, age int) Person {
    return Person{name: name, age: age}
}

// Name returns the name field.
func (o Person) Name() string {
    return o.name
}

// Age returns the age field.
func (o Person) Age() int {
    return o.age
}

// Equal checks if two Person objects are equal.
func (o Person) Equal(other Person) bool {
    return o.Name() == other.Name() && o.Age() == other.Age()
}

// Address represents a value object.
type Address struct {
    city string
}

// NewAddress creates a new instance of Address.
func NewAddress(city string) Address {
    return Address{city: city}
}

// City returns the city field.
func (o Address) City() string {
    return o.city
}

// Equal checks if two Address objects are equal.
func (o Address) Equal(other Address) bool {
    return o.City() == other.City()
}

Pourquoi j'ai écrit cet article

Je voulais savoir si des fonctionnalités telles que le package vogen intéresseraient les utilisateurs de Golang.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn