# モチベーションと katachi の立ち位置








katachi の全体像を掴むための、5分で読めるスライドもあります。

<LinkCard
  title="5分でわかる katachi"
  description="katachi が解く問題と、1つの定義からテストとドキュメントを出す仕組みを、スライドでざっと掴む。"
  href="../../slides/katachi-in-5-minutes/index.html"
  target="_blank"
/>

## アーキテクチャドキュメントは必ず実装と乖離する

優秀なあなたのことですから、プロジェクトには `/docs` ディレクトリがあり、プロジェクト全体の構造や各コンポーネントのルールが詳しく書かれていることでしょう。

しかし、**ドキュメントに書かれた「UseCase はこう書く」という文言には、何の強制力もありません**。プロジェクトのルールを知らない新規参入者や、振る舞いに不確実さのある AI Agent は、そのルールをたやすく破りかねません。

## Konsist だけでは足りない

ルールを無視したコードを通さないガードレールとして働くツールの1つに、[Konsist](https://docs.konsist.lemonappdev.com/) があります。

Konsist はプロジェクトのルールを Unit test として記述できます。

```kt
class UseCaseKonsistTest {
  @Test
  fun `UseCase は 1 つの invoke 関数のみを持つ`() {
      Konsist
          .scopeFromProject()
          .classes()
          .withNameEndingWith("UseCase")
          .assertTrue { it.functions().map { function -> function.name } == listOf("invoke") }
  }
}
```

一見すると、Konsist があればプロジェクトのルールを十分に強制できそうです。
しかし実際には、Konsist のある特性のために、それは難しいのです。

:::caution[Scope の外は検証されない]
Konsist は Scope と呼ばれる記法で、プロジェクト内の特定のファイルに絞って検証します。**Scope の外にあるファイルやディレクトリは、検証されません**。
:::

特定のファイルに絞って見るだけでなく、**プロジェクト全体を見渡して検証する手段が必要** です。

## katachi の出番

katachi では、プロジェクト全体を見渡して、現れてよいファイルの種類とその置き方を宣言できます。

```kt
val projectArchitecture = architecture {
  "UseCase" {
    layout {
      "src/main/kotlin/com/example/project/useCase" / "*UseCase".ktFile()
    }
  }
}
```

katachi では次の2つを宣言します。

- プロジェクトの中に現れて良いファイルの種類（Role と呼ばれます）
- その Role のファイルがどこに現れて良いか

これを宣言的な DSL で書くと、プロジェクト全体のディレクトリ構造をテストできるようになります。

<Aside title="Deny by default" type="tip">

katachi が採用している Deny by default の原則により、**`projectArchitecture` に宣言されていないファイルは存在が許されません**。

AI Agent がルールに背くコードを書いたとしても、katachi はそのファイルを許さず、違反として報告します。
</Aside>

<details>
<summary>このルールによって検知される例</summary>

もし AI Agent が `com.example.project.GetUserUseCase` という名前のファイルを配置した場合:

```kt
// com/example/project/GetUserUseCase.kt
package com.example.project // ❌ 本来は com.example.project.useCase に置くべきです

class GetUserUseCase {
  suspend fun invoke() = ...
}
```

<FileTree>
- src/main/kotlin/com/example/project/
  - **GetUserUseCase.kt** ❌ 宣言されていない場所に置かれた
  - useCase/
    - UpdateUserUseCase.kt ⭐️ 宣言どおりの場所
</FileTree>

katachi を含んだ Unit test を実行すると、以下のようにエラーが報告されます。

```
Katachi check failed: 1 violation (Unexpected: 1)

[UnexpectedFile] file:///path/to/project/src/main/kotlin/com/example/project/GetUserUseCase.kt
  No role is defined for this file.

  Nearby locations:
    UseCase file:///path/to/project/src/main/kotlin/com/example/project/useCase/

  How to fix:
    - Move it to one of the locations above
    - Delete it if it is not needed
    - Add a new role for it:
        "GetUserUseCase" {
          summary = "TODO"
          layout {
            "src/main/kotlin/com/example/project" / "GetUserUseCase".ktFile()
          }
        }
```

</details>

## katachi による自動生成

katachi は、アーキテクチャ定義からさまざまなものを生成できます。

<details>
<summary>ドキュメントを生成する</summary>

katachi で書いたプロジェクト構造の定義から、markdown のドキュメントを生成できます。

```shell
$ ./gradlew katachiDocs
```

Gradle plugin の `katachi { architecture = "..." }` で定義の場所を指定しておくと、定義を置いたモジュールの `build/katachi/docs` に書き出されます。

<CodeComparison>
  <CodeComparison.Panel label="アーキテクチャ定義" labelVariant="note">
    ```kt title="ProjectArchitecture.kt"
    val projectArchitecture = architecture {
      "UseCase" {
        title = "ユースケース"
        summary = "各画面で発生するアプリ固有の1つの振る舞い"

        example("GetUserUseCase", "ユーザーを取得する")
        example("UpdateUserUseCase", "ユーザーを更新する")

        layout {
          "src/main/kotlin/com/example/project/useCase" {
            description = "複数の画面から使われるもの"
            "*UseCase".ktFile()
          }
        }
      }

      // ...
    }
    ```

  </CodeComparison.Panel>

  <CodeComparison.Panel label="生成された Markdown" labelVariant="success">
    ```md title="build/katachi/docs/UseCase.md"
    [Architecture](README.md)

    # ユースケース

    各画面で発生するアプリ固有の1つの振る舞い

    ## Placement

    | Path | When to use |
    |---|---|
    | `src/main/kotlin/com/example/project/useCase/*UseCase.kt` | 複数の画面から使われるもの |

    ## Examples

    - `GetUserUseCase` ... ユーザーを取得する
    - `UpdateUserUseCase` ... ユーザーを更新する
    ```

  </CodeComparison.Panel>
</CodeComparison>

katachi で定義したプロジェクト構造を SSoT にして、人間も AI Agent も読めるドキュメントを生成しましょう。

詳しくは [ドキュメント生成](/katachi/ja/guides/document-generation/) をご覧ください。

<LinkCard
    title="ドキュメント生成"
    description="architecture { } の定義から、Role ごとの Markdown を生成する方法。"
    href="/katachi/ja/guides/document-generation/"
/>

</details>

<details>
<summary>テンプレートからコード生成する</summary>

アーキテクチャ定義の、ファイルの宣言そのものに典型的なソースコードのテンプレートを付けると、そのファイルをコマンド1つで生成できます。

```shell
$ ./gradlew katachiTemplate --arg template=UseCase,UseCaseImplementation --arg name=GetUser
```

<CodeComparison>
  <CodeComparison.Panel label="アーキテクチャ定義" labelVariant="note">
    ```kt title="ProjectArchitecture.kt"
    val projectArchitecture = architecture {
      "UseCase" {
        layout {
          "src/main/kotlin/com/example/project/useCase" /
            "${capture("name")}UseCase".ktFile()
                .template {
                  val name = captureValue("name")
                  """
                    package com.example.project.useCase

                    interface ${name}UseCase {
                      suspend operator fun invoke()
                    }
                  """.trimIndent()
                }
        }
      }

      "UseCaseImplementation" {
        layout {
          "src/main/kotlin/com/example/project/useCase" /
            "${capture("name")}UseCaseImpl".ktFile()
                .template {
                  val name = captureValue("name")
                  """
                    package com.example.project.useCase

                    class ${name}UseCaseImpl : ${name}UseCase {
                      override suspend fun invoke() {
                        // ここに振る舞いを書く
                      }
                    }
                  """.trimIndent()
                }
        }
      }
      // ...
    }
    ```
  </CodeComparison.Panel>

  <CodeComparison.Panel label="生成するコマンドと生成されたソースコード" labelVariant="success">

    ```shell
    $ ./gradlew katachiTemplate --arg template=UseCase,UseCaseImplementation --arg name=GetUser
    [1/3] Processors: template

    [2/3] Processing...
      [template] Generating 2 files under file:///path/to/project
      [template] Wrote file:///path/to/project/src/main/kotlin/com/example/project/useCase/GetUserUseCase.kt
      [template] Wrote file:///path/to/project/src/main/kotlin/com/example/project/useCase/GetUserUseCaseImpl.kt

    ========================================
    [3/3] Katachi processor run: 1 succeeded, 0 failed

    [OK] template

    ========================================
    ```

    ```kt title="src/main/kotlin/com/example/project/useCase/GetUserUseCase.kt"
    package com.example.project.useCase

    interface GetUserUseCase {
      suspend operator fun invoke()
    }
    ```
  </CodeComparison.Panel>
</CodeComparison>

詳しくは [テンプレートからコード生成](/katachi/ja/guides/generate-code-from-template/) をご覧ください。

<LinkCard
    title="テンプレートからコード生成"
    description=".template { } の書き方と、パラメータ・既存ファイルがあるときの扱い。"
    href="/katachi/ja/guides/generate-code-from-template/"
/>

</details>

## katachi と Konsist

Konsist と連携すると、katachi でプロジェクト全体を検証したあとに、個々のファイルを別々に検証できます。

```kt
val projectArchitecture = architecture {
  "UseCase" {
    // どこに置いてよいか
    layout {
      "src/main/kotlin/com/example/project/useCase" / "*UseCase".ktFile()
    }

    // 中身がどうあるべきか
    "1 つの invoke 関数のみを持つこと".konsist {
      classes()
        .withNameEndingWith("UseCase")
        .must { it.functions().map { function -> function.name } == listOf("invoke") }
    }
  }
}
```

テストで `assert(FileConstraintCheck())` を呼ぶと、配置の違反と中身の違反が、同じ1つのレポートに並びます。

**katachi でプロジェクト全体の構造をテストし、そのあと Konsist で各ファイルの中身を検証する** という使い分けをおすすめします。

詳しくは [Konsist との統合](/katachi/ja/guides/konsist-integration/) をご覧ください。

## まとめ

- AI を使った開発では、**プロジェクト構造のルールを AI Agent に守らせる手段** が必要です。
- katachi はプロジェクト全体の構造を定義・テストしたり、ドキュメントを生成したりする DSL を提供します。
- プロジェクト全体の構造は katachi、各ファイルの中身は Konsist。**役割が違うので、併用するのがおすすめの使い方です**。

## 次のステップ

- [初めてのアーキテクチャ定義](/katachi/ja/get-started/first-architecture/) ... あなたのプロジェクトに katachi のアーキテクチャ定義を導入して、その有用性を実感しましょう。
- [FAQ](/katachi/ja/get-started/faq/) ... katachi の設計思想をよくある質問を通して理解しましょう。
- [Role の定義](/katachi/ja/guides/role/) ... katachi でアーキテクチャ定義を行う基本単位である Role について学びましょう。
- [Layout](/katachi/ja/guides/layout/) ... katachi でディレクトリ構造を定義するための Layout について学びましょう。