ホームページ >バックエンド開発 >Golang >Go で DTO 変換を行う方法を調べる

Go で DTO 変換を行う方法を調べる

PHPz
PHPzオリジナル
2023-04-11 10:43:311973ブラウズ

Go は、マイクロサービスや Web 開発で広く使用されている優れたプログラミング言語です。 DTO (Data Transfer Object) 変換は、Go アプリケーションでよくある問題です。この記事では、Go で DTO 変換を実行する方法について説明します。

1. DTO とは

DTO は、Java や .NET などのプログラミング言語におけるデータ送信の問題を解決するために使用される一般的なデザイン パターンです。 DTO は Data Transfer Object の略で、あるレイヤーから別のレイヤーにデータを転送するために使用されます。転送されるデータは、データベース、Web サービス、Web フォーム、またはその他のソースからのデータである可能性があります。

DTO には、ビジネス ロジックを含まない単純なデータ属性が含まれています。 DTO は多くの場合、データベース テーブルやその他のデータ ソースのデータ構造に対応するため、DTO の属性名とタイプはデータベース フィールドとデータ タイプに基づきます。

Go では、DTO はデータベース テーブルまたはその他のデータ ソースのプロパティを含む構造です。 DTO は転送されるデータ専用であるため、軽量である必要があります。

2. DTO が必要な理由

アプリケーションでは通常、データはデータベースに保存され、Web アプリケーションはデータベースにデータを追加、更新、削除、取得する必要があります。アプリケーションには多くのレイヤーがあり、それぞれが異なる責任を負います。たとえば、Web アプリケーションには、ビューを表すレイヤー、ビジネス ロジックを表すレイヤー、データ アクセスを表すレイヤーがあります。

これらのレイヤー間でデータを送信する場合、多くの場合、データの変換が必要になります。異なる層には異なるデータ構造が必要になる場合があり、DTO は共通のデータ形式を使用してデータを送信できます。

DTO には、データベース スキーマの変更を保護できるという別の利点もあります。データベース スキーマの変更により DTO を変更する必要がある場合は、DTO のみを変更する必要があり、DTO を使用するすべてのレイヤーを変更する必要はありません。

3. Go での DTO 実装

Go では、構造体を定義することで DTO を簡単に実装できます。たとえば、ユーザー名とパスワードのフィールドを含むユーザー アカウント テーブルがあるとします。 UserDTO 構造体は次のように定義できます。

type UserDTO struct {
    Username string
    Password string
}

DTO からエンティティ オブジェクトにプロパティを変換する場合、標準の Go 構造体フィールド割り当てを使用してエンティティ オブジェクトのプロパティを設定できます。たとえば、User エンティティ オブジェクトがあるとします:

type User struct {
    ID string
    Username string
    Password string
}

次のコードを使用して、UserDTO を User に変換できます:

userDTO := UserDTO{
    Username: "testuser",
    Password: "testpassword",
}
user := &User{
    Username: userDTO.Username,
    Password: userDTO.Password,
}

同様に、User を UserDTO に変換することもできます:

user := &User{
    ID: "1",
    Username: "testuser",
    Password: "testpassword",
}
userDTO := &UserDTO{
    Username: user.Username,
    Password: user.Password,
}

上記のコードは、UserDTO から User へ、および User から UserDTO への DTO 変換を示しています。

4. DTO 変換にリフレクションを使用する

DTO に多数の属性がある場合、DTO 変換を手動で実行するのは面倒になる可能性があります。この場合、リフレクションを使用すると DTO 変換の実装が容易になります。

たとえば、次のコードを使用して、UserDTO から User へのリフレクション変換を実行できます。

type UserDTO struct {
    ID string
    Username string
    Password string
}

func (u *UserDTO) ToEntity() (*User, error) {
    user := &User{}
    elem := reflect.ValueOf(user).Elem()

    for i := 0; i < elem.NumField(); i++ {
        field := elem.Type().Field(i)
        tag := field.Tag.Get("json")
        sourceField := reflect.ValueOf(u).Elem().FieldByName(tag)

        if !sourceField.IsValid() {
            continue
        }

        destField := elem.Field(i)

        if !destField.IsValid() {
            continue
        }

        if !destField.CanSet() {
            continue
        }

        destField.Set(sourceField)
    }

    return user, nil
}

上記のコードは、リフレクションを使用して UserDTO から User に変換します。このコードは、まず空の User オブジェクトを作成し、次に、reflect.ValueOf メソッドを使用してオブジェクトの要素を取得します。次に、コードは User オブジェクトの各フィールドをループし、フィールドを設定できるかどうかを確認します。フィールドを設定できる場合、UserDTO オブジェクトの対応するプロパティが User オブジェクトの対応するプロパティにコピーされます。

さらに、同様の方法を使用して User を UserDTO に変換することもできます。例:

type User struct {
    ID string
    Username string
    Password string
}

func (u *User) ToDTO() (*UserDTO, error) {
    userDTO := &UserDTO{}
    elem := reflect.ValueOf(userDTO).Elem()

    for i := 0; i < elem.NumField(); i++ {
        field := elem.Type().Field(i)
        tag := field.Tag.Get("json")
        sourceField := reflect.ValueOf(u).Elem().FieldByName(field.Name)

        if !sourceField.IsValid() {
            continue
        }

        destField := elem.Field(i)

        if !destField.IsValid() {
            continue
        }

        if !destField.CanSet() {
            continue
        }

        destField.Set(sourceField)
    }

    return userDTO, nil
}

上記のコードは、同様のメソッドを使用して User オブジェクトを UserDTO に変換します。

5. 結論

この記事では、DTO とは何か、およびアプリケーションで DTO 変換が必要な理由を紹介します。この記事では、Go で DTO を定義する方法を示し、DTO をエンティティ オブジェクトに変換する 2 つの方法 (手動とリフレクションによる) を示します。 DTO 変換は Go アプリケーションでよく発生する問題であり、DTO を使用するとコードが読みやすく、保守しやすくなります。

以上がGo で DTO 変換を行う方法を調べるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。