mcpField
A
architecture-review

architecture-review

github.com/decebals開発762350 回インストール今日更新
リポジトリ

architecture-review について

プロジェクト構造、依存関係、モジュール境界を調べる開発者向けのアーキテクチャレビュー用スキルです。パッケージ構成、レイヤー設計、クリーンアーキテクチャやヘキサゴナルアーキテクチャの確認項目と分析手順を提供します。

主な機能

  1. 01パッケージとモジュール構成のレビュー
  2. 02依存方向の確認
  3. 03レイヤー境界のチェックリスト
  4. 04アーキテクチャ上の問題の特定
  5. 05コードベース分析コマンド

活用シーン

  1. 01パッケージ構成のレビュー
  2. 02循環依存の発見
  3. 03ドメインとフレームワークの結合確認
  4. 04クリーンまたはヘキサゴナルアーキテクチャの評価

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/decebals/claude-code-java --skill architecture-review

インストール後、Claude Code で/architecture-reviewを入力して読み込まれたか確認します。

同梱ファイルREADME.md

詳細

アーキテクチャレビューのスキル

パッケージ、モジュール、レイヤー、境界など、プロジェクト構造をマクロレベルで分析します。

使用するタイミング

  • ユーザーが「アーキテクチャをレビューして」/「プロジェクト構造を確認して」と依頼したとき
  • パッケージ構成を評価するとき
  • レイヤー間の依存関係の方向を確認するとき
  • アーキテクチャ上の違反を特定するとき
  • クリーンアーキテクチャ/ヘキサゴナルアーキテクチャへの準拠を評価するとき

クイックリファレンス:アーキテクチャ上の問題

問題症状影響
レイヤー単位のパッケージ肥大化50 個以上のクラスを含む service/関連するコードを見つけにくい
Domain → Infra の依存エンティティが @Repository をインポートするコアロジックがフレームワークに結び付く
循環依存A → B → C → Aテスト不能で、脆弱になる
巨大なパッケージutil/ や common/ が肥大化する配置場所を誤ったコードの寄せ集めになる
抽象化の漏れコントローラーが SQL を把握しているレイヤーの境界が侵害される

パッケージ構成の戦略

レイヤー単位のパッケージ構成(従来型)
com.example.app/
├── controller/
│   ├── UserController.java
│   ├── OrderController.java
│   └── ProductController.java
├── service/
│   ├── UserService.java
│   ├── OrderService.java
│   └── ProductService.java
├── repository/
│   ├── UserRepository.java
│   ├── OrderRepository.java
│   └── ProductRepository.java
└── model/
    ├── User.java
    ├── Order.java
    └── Product.java

メリット:なじみがあり、小規模プロジェクトではシンプルです
デメリット:関連コードが分散し、規模の拡大に対応しにくく、モジュールを切り出しにくくなります

機能単位のパッケージ構成(推奨)
com.example.app/
├── user/
│   ├── UserController.java
│   ├── UserService.java
│   ├── UserRepository.java
│   └── User.java
├── order/
│   ├── OrderController.java
│   ├── OrderService.java
│   ├── OrderRepository.java
│   └── Order.java
└── product/
    ├── ProductController.java
    ├── ProductService.java
    ├── ProductRepository.java
    └── Product.java

メリット:関連コードがまとまり、切り出しやすく、境界が明確です
デメリット:横断的関心事に対して共有カーネルが必要になる場合があります

ヘキサゴナル/クリーンアーキテクチャ
com.example.app/
├── domain/                    # Pure business logic (no framework imports)
│   ├── model/
│   │   └── User.java
│   ├── port/
│   │   ├── in/               # Use cases (driven)
│   │   │   └── CreateUserUseCase.java
│   │   └── out/              # Repositories (driving)
│   │       └── UserRepository.java
│   └── service/
│       └── UserDomainService.java
├── application/               # Use case implementations
│   └── CreateUserService.java
├── adapter/
│   ├── in/
│   │   └── web/
│   │       └── UserController.java
│   └── out/
│       └── persistence/
│           ├── UserJpaRepository.java
│           └── UserEntity.java
└── config/
    └── BeanConfiguration.java

重要なルール:依存関係は内側を向きます(アダプター → アプリケーション → ドメイン)


依存関係の方向に関するルール

黄金律
┌─────────────────────────────────────────┐
│              Frameworks                 │  ← Outer (volatile)
├─────────────────────────────────────────┤
│           Adapters (Web, DB)            │
├─────────────────────────────────────────┤
│         Application Services            │
├─────────────────────────────────────────┤
│          Domain (Core Logic)            │  ← Inner (stable)
└─────────────────────────────────────────┘

Dependencies MUST point inward only.
Inner layers MUST NOT know about outer layers.
指摘すべき違反
// ❌ Domain depends on infrastructure
package com.example.domain.model;

import org.springframework.data.jpa.repository.JpaRepository;  // Framework leak!
import javax.persistence.Entity;  // JPA in domain!

@Entity
public class User {
    // Domain polluted with persistence concerns
}

// ❌ Domain depends on adapter
package com.example.domain.service;

import com.example.adapter.out.persistence.UserJpaRepository;  // Wrong direction!

// ✅ Domain defines port, adapter implements
package com.example.domain.port.out;

public interface UserRepository {  // Pure interface, no JPA
    User findById(UserId id);
    void save(User user);
}

アーキテクチャレビューチェックリスト

1. パッケージ構造
  • 明確な構成戦略(レイヤー単位、機能単位、またはヘキサゴナル)
  • モジュール間で命名規則が統一されている
  • util/ や common/ パッケージが際限なく肥大化していない
  • 機能パッケージにまとまりがある(関連コードが一緒になっている)
2. 依存関係の方向
  • ドメインにはフレームワークのインポートが一切ない(Spring、JPA、Jackson)
  • アダプターはドメインに依存し、その逆ではない
  • パッケージ間に循環依存がない
  • 依存関係の階層が明確である
3. レイヤーの境界
  • コントローラーにビジネスロジックが含まれていない
  • サービスが HTTP を認識していない(HttpServletRequest がない)
  • リポジトリーがコントローラーに漏れていない
  • 境界には DTO、内部にはドメインオブジェクトを使用している
4. モジュールの境界
  • 各モジュールに明確な公開 API がある
  • 内部クラスはパッケージプライベートである
  • モジュール間の通信にはインターフェースを介する
  • 内部実装を利用するためにモジュール間を「横断」していない
5. スケーラビリティの指標
  • 機能を独立したサービスとして切り出せるか(マイクロサービス化に対応できるか)
  • 境界は強制されているか、それとも慣習にすぎないか
  • 機能を追加するたびに、多数のパッケージを変更する必要があるか

よくあるアンチパターン

1. 泥団子
src/main/java/com/example/
└── app/
    ├── User.java
    ├── UserController.java
    ├── UserService.java
    ├── UserRepository.java
    ├── Order.java
    ├── OrderController.java
    ├── ... (100+ files in one package)

修正方法:パッケージ構造を導入します(まずは機能単位から始めます)

2. util の何でも入れ
util/
├── StringUtils.java
├── DateUtils.java
├── ValidationUtils.java
├── SecurityUtils.java
├── EmailUtils.java      # Should be in notification module
├── OrderCalculator.java # Should be in order domain
└── UserHelper.java      # Should be in user domain

修正方法:ドメインロジックを適切なモジュールに移し、本当に汎用的なユーティリティだけを残します

3. 貧血ドメインモデル
// Domain object is just data
public class Order {
    private Long id;
    private List<OrderLine> lines;
    private BigDecimal total;
    // Only getters/setters, no behavior
}

// All logic in "service"
public class OrderService {
    public void addLine(Order order, Product product, int qty) { ... }
    public void calculateTotal(Order order) { ... }
    public void applyDiscount(Order order, Discount discount) { ... }
}

修正方法:振る舞いをドメインオブジェクトに移します(リッチドメインモデル)

4. ドメイン内でのフレームワークへの結合
package com.example.domain;

@Entity  // JPA
@Data    // Lombok
@JsonIgnoreProperties(ignoreUnknown = true)  // Jackson
public class User {
    @Id @GeneratedValue
    private Long id;

    @NotBlank  // Validation
    private String email;
}

修正方法:ドメインモデルと永続化/API モデルを分離します


分析コマンド

アーキテクチャをレビューする際は、以下を確認します。

# Package structure overview
find src/main/java -type d | head -30

# Largest packages (potential god packages)
find src/main/java -name "*.java" | xargs dirname | sort | uniq -c | sort -rn | head -10

# Check for framework imports in domain
grep -r "import org.springframework" src/main/java/*/domain/ 2>/dev/null
grep -r "import javax.persistence" src/main/java/*/domain/ 2>/dev/null

# Find circular dependencies (look for bidirectional imports)
# Check if package A imports from B and B imports from A

推奨事項の形式

調査結果を報告する際は、以下の形式を使用します。

## Architecture Review: [Project Name]

### Structure Assessment
- **Organization**: Package-by-layer / Package-by-feature / Hexagonal
- **Clarity**: Clear / Mixed / Unclear

### Findings

| Severity | Issue | Location | Recommendation |
|----------|-------|----------|----------------|
| High | Domain imports Spring | `domain/model/User.java` | Extract pure domain model |
| Medium | God package | `util/` (23 classes) | Distribute to feature modules |
| Low | Inconsistent naming | `service/` vs `services/` | Standardize to `service/` |

### Dependency Analysis
[Describe dependency flow, violations found]

### Recommendations
1. [Highest priority fix]
2. [Second priority]
3. [Nice to have]

トークンの最適化

大規模なコードベースの場合:

  1. find から始めて構造を把握します
  2. ドメインパッケージにフレームワークのインポートがないかだけを確認します
  3. パターン分析のために 2~3 個の機能をサンプルとして確認します
  4. すべてのファイルを読むのではなく、パターンを探します

コメント