🐚
概念 #Unix哲学 #アーキテクチャ #設計原則 #マイクロサービス #進化的アーキテクチャ 📚 進化的アーキテクチャ

Unix 哲学を現代アーキテクチャへ翻訳する

Eric Raymond の17原則から特に重要な5つを選び、マイクロサービス・イベント駆動・可観測性などの現代的設計へ翻訳する。Unix 哲学が進化的アーキテクチャを支える理由を整理する

Unix 哲学とは

1970年代、Unix の設計者たちは「良いプログラムとはどうあるべきか」という問いに答える哲学を蒸留した。Ken Thompson の言葉は簡潔だ。

「一つのことをうまくやるプログラムを書け」

Doug McIlroy(パイプの発明者)は設計哲学を 3 行にまとめた。

  1. 一つのことだけをうまくやるプログラムを書け
  2. プログラム同士が協力して動けるように書け
  3. テキストストリームを扱うように書け。テキストは汎用インタフェースだ

Eric Raymond は The Art of Unix Programming(2003)でこれを17の原則に体系化した。現代のソフトウェア設計でも有効な 5 つを選び、翻訳する。

原則1: モジュール性(Rule of Modularity)

「明確なインタフェースを持つ、シンプルなパーツで構築せよ」

単一責任の原則(SRP)と同義だ。マイクロサービスの分割基準としてそのまま使える。

// Before: 一つのクラスが注文・請求・通知を全部担う(モジュール性なし)
class OrderManager {
  async processOrder(order: Order): Promise<void> {
    await this.db.save(order);           // 永続化
    await this.stripe.charge(order);     // 請求
    await this.sendgrid.notify(order);   // 通知
    await this.inventory.reserve(order); // 在庫
  }
}

// After: 各責務を分離し、明確なインタフェースで接続する
class OrderService {
  async createOrder(command: CreateOrderCommand): Promise<Order> {
    const order = Order.create(command);
    await this.orderRepo.save(order);
    await this.eventBus.publish(new OrderCreatedEvent(order)); // イベントで協調
    return order;
  }
}
// 請求・通知・在庫は OrderCreatedEvent を購読して各自が動く

マイクロサービス分割の判断軸: 「このコードを変えると、なぜか別のコードも変えなければならない」と感じたら、責務が混在している。

原則2: 明確性(Rule of Clarity)

「巧みさより明確さを選べ。明確なコードは維持しやすい」

暗黙の慣習(マジックナンバー・暗黙の状態遷移)を排除し、意図を明示する。

// Before: 暗黙の状態(0, 1, 2 が何を意味するか分からない)
async function updateOrderStatus(id: string, status: number) {
  if (status === 1) { /* ... */ }  // 1 は何?
}

// After: 型で意図を明示する(Connascence of Name に変換)
type OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'cancelled';

async function updateOrderStatus(id: string, status: OrderStatus) {
  // status の意味がコードを見るだけで分かる
}

原則3: 合成(Rule of Composition)

「プログラムは互いに接続できるよう設計せよ」

Unix のパイプ(ls | grep | sort)の思想だ。現代では「イベントストリームによる疎結合」として表れる。

Unix:
  ls -la | grep ".ts" | sort | head -10
  ↑ 各コマンドは単体で動く。パイプで繋ぐだけで強力な組み合わせになる

現代アーキテクチャ:
  OrderService → [order.created] → InventoryService
                                 → BillingService
                                 → NotificationService
  ↑ 各サービスは独立して動く。イベントで繋ぐだけで協調する
// Kafka/SQS のトピックが「パイプ」の役割を果たす
// OrderService は下流の存在を知らない
await this.eventBus.publish('order.created', {
  orderId: order.id,
  items: order.items,
  totalAmount: order.totalAmount,
});
// → InventoryService、BillingService、NotificationService が各自購読

原則4: 早めの失敗(Rule of Repair)

「早めに失敗し、うるさく失敗せよ(fail loudly)」

エラーをサイレントに飲み込まず、できるだけ早く・詳細に失敗させる。バリデーションをシステムの境界(API エントリポイント)に集める。

// Before: 奥深くでサイレントに失敗する(原因追跡が困難)
class OrderService {
  async createOrder(data: any): Promise<void> {
    if (!data.userId) return; // サイレントな無視
    // ...
  }
}

// After: 境界で早めに・明示的に失敗する
class CreateOrderController {
  async handle(req: Request): Promise<Response> {
    const result = CreateOrderSchema.safeParse(req.body);
    if (!result.success) {
      // 境界で即座に・詳細なエラーを返す
      return new Response(JSON.stringify({ errors: result.error.issues }), {
        status: 400,
      });
    }
    await this.orderService.createOrder(result.data);
    return new Response(null, { status: 201 });
  }
}

原則5: 修理可能性(Rule of Repair / Transparency)

「透明に設計せよ。診断しやすく作れ」

システムの内部状態が外から観察できるように設計する。現代における「可観測性(Observability)」だ。

// 構造化ログ:機械可読にして診断しやすくする
logger.info('注文を作成しました', {
  orderId: order.id,
  userId: order.userId,
  totalAmount: order.totalAmount,
  itemCount: order.items.length,
  // 後から Elasticsearch / CloudWatch で絞り込める形式で
});

// メトリクス:状態を継続的に公開する
histogram('order.creation.duration_ms', duration, { status: 'success' });
counter('order.created.total', 1, { userId: order.userId });

Unix 哲学と進化的アーキテクチャの接続

Unix 哲学の 5 原則は進化的アーキテクチャの 3 原則と対応している。

Unix 哲学進化的アーキテクチャ
モジュール性(一つのことをうまくやる)Appropriate Coupling(適切な結合)
合成(パイプで繋ぐ)Incremental Change(段階的に繋ぎ変える)
早めの失敗 / 明確性Fitness Functions(特性を自動検証する)
修理可能性(透明性)Fitness Functions(継続的モニタリング)

1970年代のシンプルな哲学が、2020年代のマイクロサービス設計にそのまま適用できる。「良いソフトウェアの原則は時代を超える」

関連概念

出典・参考文献

  • Eric S. Raymond, The Art of Unix Programming (2003) — catb.org/esr/writings/taoup
  • Brian W. Kernighan, Rob Pike, The Unix Programming Environment (1984)
  • Mike Gancarz, Linux and the Unix Philosophy (2003)

出典: The Art of Unix Programming(Eric S. Raymond)/ The Unix Programming Environment(Kernighan & Pike)