0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ようこそ!クリーンアーキテクチャ世界一周ツアーへ

Posted at

皆さま、本日は「クリーンアーキテクチャ」という壮大なソフトウェアの世界を巡るツアーにご参加いただき、ありがとうございます!
これから4つの不思議な“層の国”を旅してまいります。ガイドは私。エンジニアリングの世界をナビゲートするコンダクターです。では、旅を始めましょう!

🪄第一の目的地:ドメイン層王国

image.png

最初に訪れるのは、「仮想世界の創造主たち」が住むドメイン層王国。ここは、物語の世界や魔法の国、未来の宇宙都市さえもプログラムの力で再現された、想像力あふれる世界です。

この国の住人たちは、「ドメインモデル図」という地図を使って、自分たちの世界を可視化しています。解決したい問題領域に対する最適な構造を探求する、まさに創造の中心地です。

🎯具体例:エンティティ「User」とその振る舞い

// domain/user.go
package domain

import (
    "errors"
)

type User struct {
    ID    string
    Name  string
    Email string
}

func (u *User) ChangeEmail(newEmail string) error {
    if !isValidEmail(newEmail) {
        return errors.New("invalid email format")
    }
    u.Email = newEmail
    return nil
}

func isValidEmail(email string) bool {
    return len(email) > 5 && // シンプルな例
        (email[len(email)-4:] == ".com" || email[len(email)-3:] == ".jp")
}

🎭第二の目的地:ユースケース層シアター

image.png

さて、お次はドメイン層王国で築かれた仮想世界を舞台に、ドラマが繰り広げられるユースケース層シアターへと向かいましょう!

この劇場では、「どのように物語が動くのか」が脚本として記されています。
たとえば「ユーザーがボタンを押すと、どんな反応が返ってくるのか?」──そんなアプリケーションの具体的な流れが、ここで演出されているのです。

そして、このステージの舞台装置として使われているのが、なんとドメイン層王国の住人たちが作り上げた“仮想世界のふるまい”。
彼らの創造した魔法や仕組みを、私たち現実世界の演出家(開発者)はありがたく利用しながら、劇を成立させているのです。

このユースケース層はまさに、「仮想世界の力を借りて現実のニーズに応える舞台」──私たちはその公演の恩恵を存分に享受している観客でもあり、演出家でもあるのです。

🎯具体例:ユーザーのメールアドレス変更ユースケース

// usecase/change_email.go
package usecase

import (
    "context"
    "example.com/project/domain"
)

type UserRepository interface {
    FindByID(ctx context.Context, id string) (*domain.User, error)
    Save(ctx context.Context, user *domain.User) error
}

type ChangeEmailUseCase struct {
    Repo UserRepository
}

func (uc *ChangeEmailUseCase) Execute(ctx context.Context, userID, newEmail string) error {
    user, err := uc.Repo.FindByID(ctx, userID)
    if err != nil {
        return err
    }

    if err := user.ChangeEmail(newEmail); err != nil {
        return err
    }

    return uc.Repo.Save(ctx, user)
}

🔄第三の目的地:インターフェースアダプタ通訳センター

image.png

続いてやって来たのは、現実世界と仮想世界の橋渡しをしてくれるインターフェースアダプタ通訳センターです!

ここではControllerたちがユーザーの入力を翻訳し、Presenterたちが仮想世界からの返答を“私たちにも分かる言葉”に変換してくれます。まさに国際空港の通訳ブースのような場所!

さらに、データベースとの橋渡しをしてくれるGatewayたちも働いています。おかげで、複雑な内部構造に迷わずにすむのです。

🎯具体例:HTTP Controllerとデータ変換

// interface/controller/user_controller.go
package controller

import (
    "net/http"
    "encoding/json"
    "example.com/project/usecase"
)

type ChangeEmailRequest struct {
    UserID   string `json:"user_id"`
    NewEmail string `json:"new_email"`
}

func ChangeEmailHandler(uc *usecase.ChangeEmailUseCase) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        var req ChangeEmailRequest
        _ = json.NewDecoder(r.Body).Decode(&req)

        err := uc.Execute(r.Context(), req.UserID, req.NewEmail)
        if err != nil {
            http.Error(w, err.Error(), http.StatusBadRequest)
            return
        }

        w.WriteHeader(http.StatusOK)
        w.Write([]byte("email changed"))
    }
}

🛠️最終目的地:フレームワーク&ドライバ市場

image.png

旅の最後は、現実世界との接点である“道具の市場”──フレームワーク&ドライバ層へとご案内します。

ここには、WebサーバやUIフレームワーク、データベースといった実行環境が所狭しと並んでおり、まさに開発者のためのバザール!

このマーケットにあるツールたちが、先ほどの通訳センターを通して、ユースケース層の動きを具体的なアプリとして実現してくれるのです。

🎯具体例:DBへの接続と実装

// infrastructure/repo/user_repo.go
package repo

import (
    "context"
    "database/sql"
    "example.com/project/domain"
)

type UserRepo struct {
    DB *sql.DB
}

func (r *UserRepo) FindByID(ctx context.Context, id string) (*domain.User, error) {
    row := r.DB.QueryRowContext(ctx, "SELECT id, name, email FROM users WHERE id = ?", id)
    var user domain.User
    if err := row.Scan(&user.ID, &user.Name, &user.Email); err != nil {
        return nil, err
    }
    return &user, nil
}

func (r *UserRepo) Save(ctx context.Context, user *domain.User) error {
    _, err := r.DB.ExecContext(ctx, "UPDATE users SET email = ? WHERE id = ?", user.Email, user.ID)
    return err
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?