mcpField
S
separation-of-concerns

separation-of-concerns

github.com/jordancoin開発1168 回インストール35 週間前に更新
リポジトリ

separation-of-concerns について

separation-of-concernsは、モジュールやコンポーネントを個別の責務ごとに構成するためのコーディングスキルです。原則をプロジェクトに適用する開発者向けに、実践ルール、アンチパターン、境界の考え方、コードレビュー用チェックリストを示します。

主な機能

  1. 01責務分離のルール
  2. 02レイヤー境界の指針
  3. 03代表的なアンチパターン
  4. 04コードレビュー用チェックリスト
  5. 05技術スタックに応じた適用方法

活用シーン

  1. 01多くの処理を担うハンドラーのレビュー
  2. 02ビジネスロジックとデータアクセスの分離
  3. 03テストしやすいアプリケーションモジュールの設計

MCP 対応

原則を適用する際、フレームワーク固有の詳細にはcontext7 MCPを使い、情報がなければウェブ検索を使うよう案内します。

インストール

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

$npx skills add https://github.com/jordancoin/codingskills --skill separation-of-concerns

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

詳細

SoC — 関心の分離

適用する前に

.agents/stack-context.md が存在する場合は、まず読みます。検出されたスタックに適した慣用的なパターンを使って、この原則を適用します。フレームワーク固有の詳細については、context7 MCP またはウェブ検索を利用し、推測しないでください。

原則

システム内の各モジュール、レイヤー、コンポーネントは、単一の関心事を扱うべきです。関心事とは、データアクセス、ビジネスルール、プレゼンテーション、認証、エラー処理、ロギングなど、機能の個別の側面を指します。

本番環境で重要な理由

関心事が絡み合っていると、変更が危険になります。データベーススキーマを変更しても UI が壊れるべきではありません。ログの形式を変更してもビジネスロジックに影響するべきではありません。認証を追加するために、すべてのハンドラーを書き直す必要があってはいけません。

関心事を分離すると、次のような利点があります。

  • 障害の隔離。 描画のバグでデータが破損することはありません。データベースのタイムアウトで UI がクラッシュすることもありません。
  • 独立したテスト。 ビジネスルールはデータベースなしでテストできます。UI はバックエンドなしでテストできます。
  • 並行開発。 チームメンバーが異なるレイヤーで作業しても、マージコンフリクトを避けられます。
  • 的を絞ったデバッグ。 問題が起きたとき、問題はスタック全体に広がるのではなく、1 つのレイヤーに限定されます。

ルール

  1. ポリシーと仕組みを分離します。 ビジネスルール(何をするか)は、インフラストラクチャ(どのように実行するか)から独立させるべきです。価格計算関数は、HTTP ハンドラーから呼び出されるのか、バックグラウンドジョブから呼び出されるのかを知る必要はありません。
  2. データアクセスとビジネスロジックを分離します。 クエリや変更処理はデータレイヤーに置きます。ビジネスルールはドメインレイヤーに置きます。ハンドラーやコントローラーで両者を連携させます。
  3. 入力の解析と処理を分離します。 境界で入力を検証して解析します。内部関数には、ワイヤーから受け取った生の文字列ではなく、型が明確で検証済みのデータを渡すべきです。
  4. オーケストレーションと計算を分離します。 複数の手順を調整する関数に、それらの手順の実装も含めるべきではありません。調整役は薄く保ちます。
  5. 横断的関心事は専用の仕組みで分離します。 認証、ロギング、レート制限、エラー処理は、すべてのハンドラーに散りばめるのではなく、ミドルウェア、デコレーター、インターセプターで処理すべきです。

アンチパターン

  • 肥大化したハンドラー/コントローラー: 1 つの関数内ですべてを行う HTTP ハンドラー。入力の解析、検証、データベースへの問い合わせ、ビジネスロジックの適用、出力の整形、エラー処理をすべて担います
  • データベース内のビジネスロジック: アプリケーションコード内でテストやバージョン管理ができるようにすべき複雑な条件分岐が、SQL クエリやストアドプロシージャに含まれています
  • ドメインコード内のインフラストラクチャ: HTTP クライアント、データベースドライバー、ファイルシステムモジュールを直接インポートするビジネスルール関数
  • データモデル内のプレゼンテーション: HTML の書式設定、JSON のシリアライズ設定、UI 固有のフィールドを含むデータベースモデル
  • ビジネスロジック内のロギング: 実際のロジックを見えにくくするログ出力が散りばめられた中核アルゴリズム

例

-- Concerns entangled
def create_order(request):
    # parsing
    data = json.parse(request.body)
    # validation
    if not data.items:
        return http_response(400, "No items")
    # business logic
    total = sum(item.price * item.qty for item in data.items)
    tax = total * 0.08
    # data access
    db.execute("INSERT INTO orders ...")
    # side effects
    email_service.send(user.email, "Order confirmed")
    logger.info("Order created")
    # presentation
    return http_response(201, {"order_id": id, "total": total + tax})

-- Concerns separated
def create_order_handler(request):            # orchestration
    order_input = parse_order_request(request) # parsing + validation
    order = OrderService.create(order_input)   # business logic
    OrderRepo.save(order)                      # data access
    notify_order_created(order)                # side effects
    return format_order_response(order)        # presentation

境界

  • 分離とは、レイヤーを最大限に増やすことではありません。 CRUD エンドポイントに 7 つのレイヤーを設けるのは、ロジックをインラインで記述するより悪い場合があります。目標は官僚的にレイヤーを積み重ねることではなく、自然な障害境界に沿って意味のある分離を行うことです。
  • ある程度の結合は自然です。 オーケストレーションレイヤーがドメインレイヤーとデータレイヤーの両方を知っている必要があるのは、その役割だからです。目標は、ドメインとデータが互いを知らないようにすることです。
  • マイクロサービスの境界は、SoC を極端に推し進めたものです。 ネットワークのオーバーヘッド、分散システムの複雑さ、運用コストが伴います。組織面またはスケーリング面でのメリットが正当化される場合にのみ、サービスを分割してください。
  • KISS との緊張関係: 単純なロジックを過度に分離すると、メリットのない間接化が増えます。5 行のスクリプトに 3 層アーキテクチャは必要ありません。

コードレビューのチェックリスト

  • 各関数/モジュールは単一の関心事に対応していますか?
  • インフラストラクチャ(データベース、ネットワーク、ファイルシステム)なしでビジネスロジックをテストできますか?
  • 横断的関心事(認証、ロギング、エラー処理)は、ハンドラーごとではなくミドルウェアを通じて一貫して適用されていますか?
  • データベースが変更された場合、ビジネスロジックも変更する必要がありますか?(変更する必要はありません。)
  • API の形式が変更された場合、ビジネスロジックも変更する必要がありますか?(変更する必要はありません。)

関連するスキル

  • solid:分離されたレイヤー内のインターフェースレベルの設計に使用します
  • kiss:分離によって明確さよりも間接性が増している場合に使用します
  • law-of-demeter:レイヤー間のコミュニケーションを適切に保つために使用します

コメント