Tabelog Tech Blog

食べログの開発者による技術ブログです

Cursor導入から4ヶ月、Androidエンジニアが実感した開発効率の劇的変化

はじめに:私がAndroid StudioからCursorへ移行した理由

こんにちは!食べログ開発本部アプリ開発部に所属している、Androidエンジニアの厳です。

私はこれまで長年、IDEの進化や開発手法の変遷を現場で体験してきました。その中で、AIコーディングツールであるCursorは、単なる効率化ツールではなく、IDE登場以来の開発現場のパラダイムシフトを感じさせる存在です。

AIツールが当たり前になった今、問われているのは「いかに効果的に使いこなすか」になります。だからこそ、今本気でCursorと向き合うことに決めました。

今回のテーマ:食べログAndroidのリアーキテクチャにおけるCursor活用

サービスの成長に伴い、既存コードの複雑化や技術的負債が開発効率を下げていました。そこで、現場の課題解決のために、食べログAndroidでは継続的なリアーキテクチャに取り組んでいます。本記事では、その中でもAIコーディングツールCursorを活用した実践的な知見とTipsにフォーカスしてまとめています。

開発の各工程(調査・設計・実装・修正・レビュー・テスト)で、どのようにCursorを活用したかを解説していきます。

1. 調査フェーズ:古い実装の画面をAIと解き明かす

今回対象画面

今回対応画面

やったこと

既存コードの全体像を把握するため、まず調査したい項目を整理してから、一つずつCursorに質問して理解を深めていきました。

調査前の準備:知りたいことをリストアップ

調査を始める前に、以下の項目を整理しました:

  • 関係するクラス一覧:どのクラスが関わっているか
  • 画面一覧:初期状態、検索中、検索結果表示の各状態
  • API一覧:使用しているAPI、発火タイミング、失敗処理
  • 画面動線:ユーザーの操作フロー
  • API返却値フィールドと画面リストセル部品表示関係:データとUIの対応
  • 現在地情報取得成功失敗処理:位置情報関連の処理

AIとの対話形式での調査

リストアップした項目を一つずつ、Cursorに質問していきました。例えば:

  • 「この画面に関連するクラスを教えて」
  • 「APIの呼び出しタイミングは?」
  • 「エラー時の処理はどうなっている?」

成果物

実際に作成した調査資料には以下の内容が含まれています:

  • 概要:調査の目的と範囲
  • 現状把握:現在の実装状況
  • アーキテクチャ一覧:画面遷移図、UI画面、データフロー
  • API通信用一覧:エンドポイント一覧
  • パッケージ構成:クラス構成
  • 現状画面一覧:現在の画面構成
  • UI画面一覧:各画面の詳細構成
  • 画面遷移一覧:ユーザーの操作フロー
  • まとめ:調査結果の総括

Tips

  • 闇雲に聞くのではなく、知りたいことを先にリストアップし、一つずつ対話形式で調査を進める
  • 調査項目を整理することで、AIとの対話がより効率的になる
  • 最終的な成果物として、調査結果を体系的にまとめることで、後から参照しやすくなる

2. 設計フェーズ:AIを壁打ち相手に、新アーキテクチャを描く

やったこと

設計を始める前に、以下の項目を整理してから、一つずつCursorに質問して設計を進めていきました。

設計前の準備:設計したい項目をリストアップ

設計を始める前に、以下の項目を整理しました:

  • PKG構造・クラス名の定義・役目:どのパッケージにどのクラスを配置するか、各クラスの責務は何か
  • UI層とPresenter層の間のIF定義:ViewContractの設計
  • Presenter層とUseCase層の間のIF定義:UseCaseのインターフェース設計
  • UseCase層とリポジトリ層の間のIF定義:Repositoryのインターフェース設計
  • ViewModelの定義:MVPパターンでのViewModel設計
  • リスト表示セルUIのDTO定義:画面表示用のデータ構造設計

AIとの対話形式での設計

リストアップした項目を一つずつ、Cursorに質問していきました。例えば:

  • 「この機能のパッケージ構成を提案してください」
  • 「xxxPresenterの責務は何ですか?」
  • 「UI層とPresenter層のインターフェースを設計してください」
  • 「リスト表示用のDTOクラスを定義してください」

成果物

実際に作成した設計書には以下の内容が含まれています:

  • 概要:設計の目的と範囲
  • 現状把握:現在の実装状況
  • アーキテクチャ一覧:パッケージ構成、クラス構成図
  • API通信用一覧:エンドポイント一覧
  • パッケージ構成:新設計でのクラス配置
  • 現状画面一覧:現在の画面構成
  • UI画面一覧:各画面の詳細構成
  • 画面遷移一覧:ユーザーの操作フロー

追加クラスのパッケージ構造

追加クラスPKG構造

追加クラスのクラス図

追加クラスのクラス図

Tips

  • 一度に全体ではなく、クラス単位で少しずつ設計を進めるのが精度を高める秘訣
  • 参考情報として、理想形となる既存のコード(リアーキテクチャ後の別クラスなど)を読み込ませると、設計の質が向上する
  • 複雑な仕様や修正時は、まず案を出してテーブルで比較する
    • 例:XXX部分に指摘がありました。修正する前に案を出してテーブルでまとめてください。
  • 認識違いが大きい場合、追加説明よりプロンプト修正が効率的

失敗談

設計中にCursorがうまく依頼者の説明を理解せず、複数回追加説明しても伝わらなかったことがありました。

  • 対策:一番理解してもらいたところに戻し、プロンプト文を分かりやすく修正する
  • 教訓:AIは具体的な情報や明確な指示には強いが、抽象的な概念や文脈の理解は不得意。人間が「何をどう伝えるか」を工夫し、AIの弱みを補うことが重要だと実感しました。

3. 実装フェーズ:設計書からコードを1クラスごとに生成する

やったこと

設計書を元に、画面、Presenter、ViewModel、UseCaseなどのクラスを生成しました。

実装の進め方

実装では、以下のような段階的なアプローチを取りました:

  1. 順序立てたクラス作成

    • 依存関係を考慮した順序で1クラスずつ確実に進める
    • 例:「次にxxxUseCase.ktを作成して下さい」「次にxxxUseCaseImpl.ktクラスを作成して下さい」
  2. 具体的な修正指示

    • 細かい修正点まで具体的に指示
    • 例:「aliasnameはaliasNameにして下さい」「user.logCountはnull対応するためuser.logCount.toZeroOrInt()にして下さい」
  3. 参考コードの明確な指定

    • 既存の良いコードパターンを活用
    • 例:「書き方はxxxUseCaseImpl.ktを参考にして下さい」「ロジックはリアーキテクチャ前のクラスを、書き方はリアーキテクチャ後のクラスを参考にして下さい」
  4. 段階的な実装と即座の修正

    • 実装後すぐに問題点を指摘・修正
    • 例:「!!はNullPointerExceptionが発生するから使わないこと」「photoUrl.toString()必要ある、他も1箇所ある」
  5. 依存関係の適切な管理

    • DIコンテナへの登録を忘れずに実行
    • 例:「xxxModule.ktにxxxPresenterの定義を追加して下さい」「xxxModule.ktにxxxUseCaseを追加して下さい」

Tips

  • 関連性の少ないクラスから、一つずつ着実に生成・確認していく
  • 完璧なコードを求めすぎない。「的外れであればプロンプト修正、正解に近ければ部分指摘」の使い分けが重要
  • 段階的アプローチ:依存関係を考慮した順序で実装することで品質を保証
  • 具体的な指示:曖昧さのない明確な指示で効率的な開発を実現
  • 既存コードの活用:良いパターンを参考にすることで一貫性を保持し、学習コストを最小化
  • 即座の修正:実装後すぐに問題点を指摘・修正することで品質を段階的に向上
  • アーキテクチャの一貫性:設計書に基づいた実装とDIコンテナへの適切な登録

実装フェーズでの課題と解決

  • 問題:設計した後に画面作成を指示すると、現状のリアーキテクチャ後画面と違った形になることがあった

    • 現状アプリはMVP、CursorはMVVMで生成しがち
    • 基底クラスの拡張の書き方も異なる
  • 解決:現状のリアーキテクチャ後の画面を先に読み込ませてから、画面作成を依頼することで、意図通りの構成で生成できるようになった

実装で特に効果的だったポイント

  • 体系的で効率的な実装プロセス:リアーキテクチャにおいて、1クラスずつ確実に進めることで品質を保証
  • 実用的な成果物の作成:具体的なコード例を提示し、既存のパターンに合わせた実装を強制
  • エラー処理の徹底:エラー処理の統一性を重視し、不要な複雑性を排除
  • 命名規則の統一:キャメルケースの統一やメソッド名の一貫性を確保

4. テストフェーズ:面倒なテストコード実装を効率化する

やったこと

設計書を元に、各クラスのテストコードを段階的に実装しました。

テストコード実装の進め方

テストコード実装では、以下のような段階的なアプローチを取りました:

  1. 段階的なテストクラス作成

    • 1クラスずつ順序立ててテストクラスを作成
    • 既存のテストクラスを参考にして一貫性を保持
    • 例:「次にxxxUseCaseImpl.ktのテストクラスxxxUseCaseImplTest.ktを作成して下さい」
  2. 既存テストコードの学習と活用

    • 既存の成功例から学習することで効率化
    • テストパターンの一貫性を保持
    • 例:「まず既存のxxxPresenterImplTest.ktの書き方を学習して下さい」「xxxFactory.ktの既存の書き方を学習して下さい」
  3. テストデータの体系的な準備

    • テストデータを段階的に準備
    • 再利用可能なデータファクトリを活用
    • 例:「xxxResult.ktの返却値をxxxFactory.ktに追加して下さい」「上記の返却値を利用してxxxPresenterImplTest.ktのテストケースに使って下さい」
  4. エラー分析と修正の効率化

    • エラーログの詳細な分析
    • テスト環境特有の問題を理解
    • 例:「テストケースの実行エラーを確認して下さい。Method parse in android.net.Uri not mocked...」「No other calls allowed in stdObjectAnswer than equals/hashCode/toString io.mockk.MockKException...」
  5. 学習アプローチの活用

    • 問題解決に行き詰まった際の学習アプローチ
    • 既存の成功例から学ぶ姿勢
    • 例:「直らないですね。まず修正しないで、xxxPresenterImplTest.ktのxxxFactory.fromJsonの書き方を学習して下さい」

Tips

  • 段階的アプローチ:1クラスずつ順序立ててテストクラスを作成することで品質を保証
  • 既存コードの活用:既存のテストクラスを参考にして一貫性を保持し、学習コストを最小化
  • テストデータの体系化:再利用可能なデータファクトリを活用して効率的なテストデータ準備
  • エラー分析の効率化:テスト環境特有の問題を理解し、具体的な修正案を提示
  • 学習アプローチの活用:問題解決に行き詰まった際の学習方法により、効率的な問題解決を実現

テストフェーズで特に効果的だったポイント

  • 体系的で効率的なテスト作成プロセス:開発プロジェクトにおいて、段階的にテストクラスを作成することで品質を保証
  • 既存パターンの活用:既存のテストクラスを参考にすることで、一貫性のあるテストコードを作成
  • テストデータの効率化:データファクトリを活用することで、再利用可能で保守性の高いテストデータを準備
  • 問題解決の効率化:エラー分析と学習アプローチにより、テスト環境特有の問題を効率的に解決

5. バグ修正とPR指摘:Cursorによる原因特定と修正の流れ

やったこと(バグ修正)

UIの表示崩れが発生した際、スクリーンショットと関連コードを読み込ませ、原因を推測させました。

バグ修正の進め方

バグ修正では、以下のような体系的なアプローチを取りました:

  1. 問題の体系的な分析

    • 問題の原因を特定するために関連クラスを分析
    • 分析結果をテーブルで整理して可視化
    • 例:「画面起動後xxxInfoのリスト作成して該当UI表示したいですが、現在xxxInfoになっている。xxxPresenterImpl.kt と xxxViewModel.kt を分析して、画面起動後の処理を精査して下さい。テーブルでまとめて下さい。」
  2. エラー分析と具体的な修正指示

    • エラーログの詳細な分析
    • 発生箇所の特定
    • 例:「次にxxxItemViewHolder.ktのパラメータ設定時にクラッシュしました。まず原因と対応案をテーブルで挙げて下さい。発生する行:photoView.layoutParams = params クラッシュ内容:java.lang.ClassCastException...」
  3. 段階的な修正アプローチ

    • 問題を段階的に解決
    • 各段階で具体的な修正内容を指示
    • 例:「loadNextPage API失敗してhandleNextPageError()を表示する。エラー表示中にも通信してエラーセル追加されて、エラーセル複数表示される。対応案をあげてテーブルまとめて下さい。」

やったこと(PR指摘対応)

レビューコメントと該当コードを読み込ませ、修正案を複数提案させました。

PR指摘対応の進め方

PR指摘対応では、以下のような効率的なアプローチを取りました:

  1. 複数対応案の提示と比較

    • 指摘内容を理解した上で複数の解決案を提示
    • 各案のメリット・デメリットを客観的に評価
    • 例:「JOB_KEY_INIT_LOAD、JOB_KEY_SEARCHなどのジョブキーについて、まず解決可能な案をテーブルで挙げて下さい。各案の良い点悪い点も挙げて下さい。」
  2. コードレビュー指摘への体系的な対応

    • 指摘内容を正確に理解
    • 該当コードを特定
    • 具体的な修正方針を提示
    • 例:「xxxPresenterImpl.kt クラスのhandleNextPageError()に指摘あります。指摘内容:DTOの生成等はViewModelにまとめた方が良いかと思います。」
  3. 継続的な改善

    • 指摘内容の本質を理解
    • より良い実装方法を提案
    • コードの品質向上を重視
    • 例:「このフラグはdataListの中にxxxListDto.Error.NextPageErrorが入ってセットになっているので、dataList.contains(xxxListDto.Error.NextPageError)で判定する方が良いと思います。」

Tips

  • エラーログや指摘内容だけでなく、「こうなってほしい」という理想の状態やコンテキストを伝えることで、的確な回答が得られやすくなる
  • 表示バグを依頼する時は、文章で説明するよりも「正解のキャプチャ」と「間違ったキャプチャ」を添付すると伝わりやすい
  • 問題解決の体系化:問題の原因分析→対応案の提示→実装→検証の流れで効率的に解決
  • 複数視点での解決案提示:単一の修正ではなく、複数のアプローチを提示し、各案のメリット・デメリットを客観的に評価
  • 学習と実践の組み合わせ:問題解決に行き詰まった際は、既存の成功例から学ぶ姿勢が重要
  • 継続的な品質向上:単なる修正ではなく、より良い実装方法の提案を心がける
  • 効率的な問題解決:エラーログの詳細分析と発生箇所の特定により、具体的な修正指示を実現

バグ修正・PR指摘で特に効果的だったポイント

  • 体系的で効率的な問題解決プロセス:開発プロジェクトにおいて、問題を段階的に解決することで品質を保証
  • 客観的な評価基準:複数の解決案を提示し、各案のメリット・デメリットを評価することで、最適な解決策を選択
  • 学習アプローチの活用:問題解決に行き詰まった際の学習方法により、効率的な問題解決を実現
  • 品質向上への意識:コードレビュー指摘への積極的な対応により、継続的な品質向上を実現

まとめ

Cursorはエンジニアの「思考のパートナー」となる存在です。

単なるコード生成ツールではなく、調査・設計・レビューなど、開発プロセス全体を加速させるパートナーです。

実装だけでなく、「1スレッド=1案件」として、調査・設計・実装・テストコード作成・バグ対応・指摘対応・案件の振り返りまで、一連の作業を通して対応することの大切さを実感しました。

AIと人間の協業においては、発散的な情報収集や定型的なコード生成はAIに任せ、設計や意思決定、ビジネス要件の翻訳といった判断は人間が担うべきです。

体感として、Cursorを活用したことで開発スピードがこれまでの2倍近くに向上し、バグ対応やレビューのストレスも大きく減ったと感じています。数値で示すのは難しい部分もありますが、現場のエンジニアとして「明らかに仕事の進め方が変わった」と実感しています。

例えば、従来は調査・設計に2日かかっていた規模のタスクが、AIとの壁打ちによって0.5日で方向性が定まるといった事例もありました。こうした小さな効率化の積み重ねが、全体のスピードアップにつながっています。

今後について

AIコーディングツールの進化は、今後も加速度的に進むと考えています。今はまだ「AIに任せる部分」と「人間が担う部分」を意識的に分担していますが、将来的にはAIがより抽象的な設計や意思決定にも関与する時代が来るかもしれません。

次のステップとして検討したい取り組み

現在はCursor単体での活用に留まっていますが、今後は以下のような併用パターンを検討したいと考えています:

  • Cursor + Claude Code: 設計はClaude Code、実装はCursorという役割分担
  • Cursor + Devin Ask: Devin Askで調査、Cursorで実装という役割分担
  • Cursor + GitHub Copilot Workspace: 大規模な設計変更はCopilot Workspace、細かい実装はCursor

エンジニアとしての成長戦略

そのとき、エンジニアには「AIと共創する力」や「AIのアウトプットを批判的に評価し、より良い方向へ導く力」がますます重要になります。

私自身も、AIの進化に合わせて自分のスキルや考え方をアップデートし続けたいと考えています。新しい技術やツールを積極的に試し、AIと協力しながらより良い開発を目指していきます。

このパラダイムシフトの中で、個人として「AIと共に考え、成長し続けるエンジニア」でありたいと思います。

最後に、食べログでは一緒に働く仲間を募集しています! 食べログで働いてみたいと感じてくださった方は、以下の採用情報のリンクから是非応募してみてください!!!