概念的距離の圧縮
概要
概念的距離の圧縮とは、開発者が思考する抽象レベルと、実際にコードで記述するレベルとの距離を最小限にするというプログラミング設計原則 「考えていることをそのままコードで表現できる」状態を目指す。
「自分がやりたいこと(ドメインの意図)」と「実際に書くコード」のあいだの“ステップ数”をできるだけ短くする
ざっくりとこんな発想
code: (ruby)
# ファイル名: app/models/user.rb
class User < ApplicationRecord
# これだけで users テーブルと自動的に関連付けられる
end
通常なら「Userクラスがusersテーブルと対応する」という設定を明示的に書く必要がありますが、Railsでは命名規約によってこの概念的距離が圧縮されています
code: (ruby)
class User < ApplicationRecord
has_many :posts
end
class Post < ApplicationRecord
belongs_to :user
end
# 使用時
user.posts # 「このユーザーの投稿一覧」という概念をそのまま表現
「ユーザーは複数の投稿を持つ」という概念を、SQLの複雑なJOINではなく、自然な英語表現で記述できます。
code: (ruby)
# config/routes.rb
resources :users
# これで以下のルートが自動生成される:
# GET /users # index(一覧)
# GET /users/new # new(新規作成フォーム)
# POST /users # create(作成)
# GET /users/:id # show(詳細)
# GET /users/:id/edit # edit(編集フォーム)
# PATCH /users/:id # update(更新)
# DELETE /users/:id # destroy(削除)
「ユーザー」というリソースに対する基本的な操作という概念を、一行で表現できます。
code: (ruby)
# SQL的思考:SELECT * FROM users WHERE age > 18 ORDER BY name
# Rails的表現:
User.where(age: 18..).order(:name)
# より自然な表現
User.adults.alphabetical # スコープを使えば更に自然に
メリット
認知負荷の軽減: 開発者は本質的な問題に集中できる
開発速度の向上: 定型的なコードを書く時間が削減される
可読性の向上: コードが意図を直接的に表現する
メンテナンス性: 概念とコードが一致しているため、変更が容易
注意点・デメリット
学習コストの初期負担: 規約を覚える必要がある
魔法的すぎる: 内部で何が起こっているか分からなくなる可能性
柔軟性の制約: 規約から外れた場合の対応が複雑になることがある
現代の設計のベストプラクティスと相反するのか?
k8s 抽象化も
サーバレスも
広い意味では「インフラの概念的距離の圧縮」
ポイントは「エンジニアがビジネス上の問題に集中できるよう、余計な概念を隠す/まとめる」
つまり圧縮そのものは悪ではなく、むしろ現代のプラクティスの中核でもある。
問題は「どの概念を一緒くたに圧縮するか」
DDDやクリーンアーキテクチャの文脈ではドメイン層、アプリケーション層、インフラ層をはっきり分けることが推奨される。しかしRailsの素直な世界観はActiveRecordモデルに「状態 + 永続化 + ドメインロジック」が全部のる。コントローラがユースケースもエンドポイントも背負う。
その結果「分けて考えるべきものまで 1 つのオブジェクト/レイヤに詰め込まれている」という状態を生む。
ここで「現代のベストプラクティス(モジュラリティ・明示的な境界)」と摩擦が出てている。
個人的な答えは、Railsの概念的距離の圧縮は「最初の加速」には最高のツールだけど、ずっとそれ一本でやり切るべきものではない。