mybook

エピローグ — ロードマップの先へ

旅の終わりと始まり

季節が変わり、ヒロシが入社してから3年目の春になった。

あの日、マイにホワイトボードでロードマップを描いてもらったときから、随分と遠くまで来た気がする。

「マイさん、全部のステージを終えた気がします。」

マイはコーヒーを飲みながら微笑んだ。「終えたんじゃない。ここから始まるんだよ。」

振り返り: 何が変わったか

ヒロシは入社1年目に書いたコードと、今のコードを見比べた。

# 入社1年目のコード
class UsersController < ApplicationController
  def create
    user = User.new(params.require(:user).permit(:name, :email, :password))
    if User.where(email: params[:user][:email]).exists?
      render json: { error: "このメールは既に使われています" }, status: 422
      return
    end
    if params[:user][:password].length < 8
      render json: { error: "パスワードは8文字以上" }, status: 422
      return
    end
    if user.save
      UserMailer.welcome_email(user).deliver_now
      slack_client = Slack::Web::Client.new
      slack_client.chat_postMessage(channel: "#new-users", text: "新規ユーザー登録: #{user.email}")
      user.points.create!(amount: 100, reason: "signup_bonus")
      render json: { user: user }, status: 201
    else
      render json: { errors: user.errors }, status: 422
    end
  end
end
 
# 3年目の同じ機能
class UsersController < ApplicationController
  def create
    result = UserRegistrationService.new(registration_params).call
 
    if result.success?
      render json: UserSerializer.new(result.user).as_json, status: :created
    else
      render json: { errors: result.errors }, status: :unprocessable_entity
    end
  end
 
  private
 
  def registration_params
    params.require(:user).permit(:name, :email, :password)
  end
end

「コントローラーが6行になった。」

「でも、それより重要なのは?」マイが聞いた。

「テストが書けること。変更が怖くないこと。新しいメンバーが読んでも意図がわかること……。」

「そう。コードの品質は、読む人と変更する人への優しさだ。」

ロードマップの全体像を振り返る

Loading diagram...

「各ステージで学んだことは、孤立した知識じゃない。全部つながっている。」

ステージ核心の問い
クリーンコードこのコードは明日の自分が読めるか?
パラダイムどの考え方でモデル化するのが自然か?
SOLID変更のたびに恐怖を感じないか?
デザインパターンこの問題に名前はあるか?
アーキテクチャ原則変更は局所化されているか?
アーキテクチャスタイルシステム全体の構造は適切か?
DB設計データは正しく整合されているか?
テスト戦略動くことを証明できるか?
DevOpsデプロイは安全で繰り返せるか?
分散システムスケールに対応できるか?

T字型エンジニアへ

「次の目標はなんですか?」ヒロシが聞いた。

「T字型エンジニアを目指すといい。」

Loading diagram...

「このロードマップを終えたヒロシは、縦軸の基盤ができた。どの方向に深くするかは自分で選ぶ。」

  • フロントエンド深化: React の状態管理・パフォーマンス・アクセシビリティ
  • バックエンド深化: DDD(ドメイン駆動設計)・イベントソーシング
  • インフラ深化: Platform Engineering・SRE・コスト最適化
  • データ深化: データエンジニアリング・機械学習パイプライン

学び続けるための習慣

「技術は止まらない。学び続けることが唯一の戦略。」

読む

推薦図書:
- Clean Code (Robert C. Martin)
- Designing Data-Intensive Applications (Martin Kleppmann)
- System Design Interview (Alex Xu)
- The Pragmatic Programmer (David Thomas, Andrew Hunt)
- Domain-Driven Design (Eric Evans)

書く

# 副作用のないコードを書く練習
# ローカルでOSSにコントリビュートする
# 技術ブログで学んだことを言語化する
# 社内勉強会で発表する
 
# 「人に説明できるか?」が理解度のリトマス紙

作る

「理論だけでは身につかない。実際に作ることで血肉になる。」

# サイドプロジェクトのアイデア
# - 自分のRails APIをECSにデプロイする
# - 分散キューをRedisで自作してみる
# - テストを書かないとマージできないCI環境を作る
# - モノリスを段階的にサービス分割する練習

INFO

Kata(型稽古)のすすめ

「コードカタ」という練習方法があります。同じ小さな問題(FizzBuzz、TDD by Example等)を繰り返し解くことで、設計の感覚を磨く。武道の「型稽古」と同じ原理です。

kata-log.rocks など、問題集のサイトも参考に。

コミュニティで成長する

「一人で学ぶより、コミュニティで学ぶ方が10倍速い。」

  • コードレビューをお願いする: 人の目線が最大の学習源
  • OSS にPRを送る: 世界中のエンジニアからフィードバックが来る
  • 勉強会に登壇する: 「話せるレベル」が真の理解
  • ペアプログラミング: リアルタイムで思考プロセスを共有
# コードレビューのお願い例
# 「動くコードをレビューしてほしい」ではなく
# 「この設計のここが迷っているので意見を聞かせてほしい」
# と具体的な問いを持ってお願いする

エンジニアとしての哲学

「最後に、一番大切なことを伝える。」マイが立ち上がり、ホワイトボードに書いた。

"Make it work. Make it right. Make it fast." — Kent Beck

「まず動かせ。次に正しくしろ。最後に速くしろ。この順番を守れ。」

「多くのエンジニアが、動いてもいないうちから設計を完璧にしようとして止まる。または動いてから正しくすることを後回しにして、技術的負債を積み上げる。」

# 良いエンジニアの思考プロセス
 
# Step 1: Make it work
def calculate_discount(user, price)
  # とにかく動かす
  price * 0.9
end
 
# Step 2: Make it right
def calculate_discount(user, price)
  # テストを書きながら正しくする
  return price unless user.premium?
  (price * (1 - user.discount_rate)).ceil
end
 
# Step 3: Make it fast (必要なら)
def calculate_discount(user, price)
  # プロファイリングでボトルネックを特定してから最適化
  Rails.cache.fetch("discount_rate/#{user.id}", expires_in: 5.minutes) do
    user.discount_rate
  end.then { |rate| (price * (1 - rate)).ceil }
end

ヒロシのこれから

数週間後、ヒロシは新しく入ったジュニアエンジニアのコードレビューをしていた。

# ジュニアのコード
class OrderController < ApplicationController
  def create
    order = Order.new(params.require(:order).permit(:user_id, :total))
    if order.save
      # ウェルカムメール送信
      OrderMailer.confirmation(order).deliver_now
      # Slackに通知
      slack = Slack::Web::Client.new
      slack.chat_postMessage(channel: "#orders", text: "新規注文: #{order.id}")
      render json: { order: order }, status: 201
    else
      render json: { errors: order.errors }, status: 422
    end
  end
end

ヒロシはコメントを書いた。

「動くコードですね!一点だけ提案です。コントローラーにメール送信とSlack通知のロジックが入っています。OrderCreationServiceに切り出して、テストを書きやすくしませんか?理由は……」

ヒロシは、自分がかつてマイに言われた言葉を思い出しながら、丁寧にコメントを続けた。

教えることが、最も深く学ぶ方法だ。

ロードマップの次へ

「マイさん、次に何を学べばいいですか?」

マイは笑った。「自分で地図が読めるようになったんだから、自分で次の目的地を選べるようになった。それがこのロードマップの目標だったんだよ。」

ヒロシはノートを閉じた。


旅はここで終わらない。良いコードへの追求は、エンジニアである限り続く。

この本を読んだあなたも、今日から次のステージへ。


参考リソース

テーマリソース
クリーンコードClean Code / Clean Architecture — Robert C. Martin
SOLIDAgile Software Development — Robert C. Martin
デザインパターンDesign Patterns — GoF
Rails設計The Rails Way — Obie Fernandez
DB設計Database Design for Mere Mortals — Michael Hernandez
分散システムDesigning Data-Intensive Applications — Martin Kleppmann
システム設計System Design Interview — Alex Xu
DevOpsThe Phoenix Project — Gene Kim

INFO

このロードマップを終えたら

次のロードマップとして「DDD(ドメイン駆動設計)」がおすすめです。今学んだSOLID、クリーンアーキテクチャ、テスト戦略の全てが、DDDで統合されます。

ヒロシの成長物語は、まだ続く。