<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ishikawa's blog</title><link>https://example.org/</link><description>Recent content on ishikawa's blog</description><generator>Hugo</generator><language>ja</language><lastBuildDate>Sat, 18 Apr 2026 10:00:00 +0900</lastBuildDate><atom:link href="https://example.org/index.xml" rel="self" type="application/rss+xml"/><item><title>何か作りたくて個人ブログを作成した話</title><link>https://example.org/posts/first/</link><pubDate>Sat, 18 Apr 2026 10:00:00 +0900</pubDate><guid>https://example.org/posts/first/</guid><description>&lt;h2 id="何か作りたくて個人ブログを作った話">何か作りたくて個人ブログを作った話&lt;/h2>
&lt;p>暇な土日ですが、OSS活動は今日はいいかなって思って何をするか考えていたらブログを作ればいいんじゃないかと考えに至りました。&lt;/p>
&lt;p>ZennやQiitaなどのプラットフォームで投稿していましたが、つよつよエンジニア達はこぞってブログから情報を発信していたので、なんか真似したくなったってわけ&lt;/p>
&lt;p>じゃあどうやってブログ作ろかなーとOpusと話して、爆速でデプロイできる構成にしようと考えていたがあれやこれやしていく過程で違う構成になった。&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>当初の想定&lt;/th>
&lt;th>実際の構成&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>SSG&lt;/td>
&lt;td>Hugo&lt;/td>
&lt;td>Hugo&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>テーマ&lt;/td>
&lt;td>PaperMod&lt;/td>
&lt;td>PaperMod(RSS/404/robots.tstのみ現存)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>レイアウト&lt;/td>
&lt;td>PaperModの標準&lt;/td>
&lt;td>自作(index/single/list/terms)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>スタイル&lt;/td>
&lt;td>PaperModCSS&lt;/td>
&lt;td>自作&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>グラフ&lt;/td>
&lt;td>なし(想定してない)&lt;/td>
&lt;td>　D3.jsでforce-directedグラフ　&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>テーマ切り替え&lt;/td>
&lt;td>　PaperMod　&lt;/td>
&lt;td>自作&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ローカル開発&lt;/td>
&lt;td>Docker&lt;/td>
&lt;td>Docker&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>デプロイ&lt;/td>
&lt;td>Cloudflare Workers&lt;/td>
&lt;td>Cloudflare Workers&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>大体変わった。個人開発だし欲は出していこう。&lt;/p>
&lt;p>大体7:3くらいでCladueへ任せて、こちらはハーネスを握りながら開発していったつもり。&lt;/p>
&lt;p>個人的にはいい感じのブログができたのでZennやQiitaの記事も持ってきてブログを充実させよう！&lt;/p></description></item><item><title>AIにコードを書かせるほど、設計を考えなくなっていた</title><link>https://example.org/posts/20260418/</link><pubDate>Sat, 18 Apr 2026 09:00:00 +0900</pubDate><guid>https://example.org/posts/20260418/</guid><description>&lt;h2 id="はじめに">はじめに&lt;/h2>
&lt;p>こんにちは。
2025年中盤からClaude Codeやcopilot等のエージェントツールが目まぐるしく進化し、コーディング作業はかなり楽になりました。
一方で、AI漬けの日々に疲れを感じることも増えてきて、休日くらいはAIデトックスして純粋にプログラミングを楽しんだほうがいいんじゃないかと思っています。&lt;/p>
&lt;p>この記事では、AIエージェントに開発の舵を渡してしまっていた自分が、ペアプロをきっかけに「自分の意思で設計する」ことを取り戻した話を書きます。&lt;/p>
&lt;h2 id="aiに任せていた頃">AIに任せていた頃&lt;/h2>
&lt;p>エージェントってどういう使い方されてます？&lt;/p>
&lt;p>私はというと、フレームワークのベストプラクティスをなんとなく拾ってきて読み込ませ、AI側にコーディングの規約や構造を判断させてレビューや開発をしていました。レガシー環境のプロジェクトでは、読み込ませる工程すら省いていたと思います。&lt;/p>
&lt;p>自分でレビューや調整はしていたので、大きく意図と違う状態になることは&lt;strong>あまり&lt;/strong>ありませんでした。でも「なんか違う・・・」と感じたことは何回もあって、その度に&lt;strong>まぁこんなもんやろ&lt;/strong>とAIの評価をしていました。&lt;/p>
&lt;p>今思えば、「自分はこう作りたい」が無い状態でAIに書かせていたので、出力の良し悪しを判断する基準がそもそも無かったんですよね。&lt;/p>
&lt;h2 id="転機--ペアプロで突きつけられたこと">転機 ― ペアプロで突きつけられたこと&lt;/h2>
&lt;p>AIに対する評価が180度変わったのは、0→1開発にアサインされた時のことでした。&lt;/p>
&lt;p>バックエンド開発が主な内容で、私ともう一人の開発メンバー、そしてメンター兼レビュワーとして2人の先輩エンジニアという体制で進めていました。0→1開発の経験が浅く、開発期限にも余裕がなかったため、「設計思想は作りながら確立して、まずは動くものを」をベースに開発を進めていきました。&lt;/p>
&lt;p>暫くして、歴が倍以上ある先輩エンジニアのTさんからペアプロの提案がありました。
正直、開発は進んでいるしスケジュールに間に合わせたい。悠長にリファクタリングしている暇は無い、と思っていました。&lt;/p>
&lt;p>しかし、そもそもTさんの思考や技術を盗みたいと思ったからこのチームへの移籍願いを出したのだと思い出し、ペアプロを受けることにしました。&lt;/p>
&lt;h3 id="このコードどんな意思があって書いた">「このコード、どんな意思があって書いた？」&lt;/h3>
&lt;p>ペアプロでTさんによく言われたのはこういうことでした。&lt;/p>
&lt;ul>
&lt;li>「このコードはどんな意思があって書いているのか」&lt;/li>
&lt;li>「どんなことがしたくてこの分け方にした？」&lt;/li>
&lt;/ul>
&lt;p>たとえば、あるAPIからのレスポンス変換処理をServiceクラスに書いていた時、「なんでここに置いたの？」と聞かれました。正直、明確な理由はなく「なんとなくServiceだから」としか答えられませんでした。&lt;/p>
&lt;p>振り返ると、今まで自分がやっていたのは、バグが起こっていないか、先方から言われた仕様通りに動いているか、それだけでした。思想や自分の考えは基本無視して、どれだけIssueをこなすかだけを考えていた。そしてそれが評価に直結していたため、PRが通る＝これでいいんだという感覚になり、&lt;strong>「なぜこう書くのか」を考えるという当たり前のことを、いつの間にか忘れていました。&lt;/strong>&lt;/p>
&lt;h2 id="思想を整理する--設計ドキュメントを書いた">思想を整理する ― 設計ドキュメントを書いた&lt;/h2>
&lt;p>ペアプロを経て、私は現在のアーキテクチャ構造を選定した理由を細かい粒度で説明できるようにしようと決めました。各設計判断のメリット・デメリットとプロジェクトのドメインロジックから、設計のテーマを整理してTさんにも確認していただきながらドキュメントに落とし込みました。&lt;/p>
&lt;h3 id="なぜmvcでもクリーンアーキテクチャでもないのか">なぜMVCでもクリーンアーキテクチャでもないのか&lt;/h3>
&lt;p>最初に向き合ったのは「なぜこの構造なのか」という問いでした。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>MVC&lt;/strong>：Modelに処理が集中しやすく、改修が重なると肥大化して保守が難しくなる&lt;/li>
&lt;li>&lt;strong>クリーンアーキテクチャ等&lt;/strong>：Interfaceやドメイン層の分離が必要で、今回の改修規模に対して過剰&lt;/li>
&lt;/ul>
&lt;p>どちらも「ダメ」ではなく、&lt;strong>このプロジェクトには合わない&lt;/strong>という判断です。そこで、Modelの責務をUsecase／Serviceの2層に分離する方針を採用しました。&lt;/p>
&lt;pre tabindex="0">&lt;code>プレゼンテーション層 → ユースケース層 → サービス層
&lt;/code>&lt;/pre>&lt;ul>
&lt;li>&lt;strong>ユースケース層&lt;/strong>：サービスを呼び出して業務フローを組み立てる（処理の流れだけを書く）&lt;/li>
&lt;li>&lt;strong>サービス層&lt;/strong>：具体的な処理を実装する&lt;/li>
&lt;/ul>
&lt;p>この構造なら、今後ビジネスロジックが複雑化してもユースケース層は「サービスの呼び出し順序」だけを管理するので、コードがシンプルに保たれます。新しい処理はサービス層に追加し、ユースケース層で差し替えるだけ。改修時のバグリスクも抑えられます。&lt;/p>
&lt;h3 id="迷ったポイントサービス間のdiを禁止した理由">迷ったポイント：サービス間のDIを禁止した理由&lt;/h3>
&lt;p>設計を整理する中で特に迷ったのは、サービス同士の依存をどうするかでした。&lt;/p>
&lt;p>ServiceAからServiceBを呼びたい場面は当然出てきます。でも、それを許可するとサービス間の依存関係がスパゲッティ化して、どこで何が呼ばれているか追えなくなる。結局「サービスはサービスをコンストラクタで受け取らない（サービス間のDI禁止）」というルールにしました。&lt;/p>
&lt;p>サービス間で処理を共有したい場合は、ユースケース層で両方のサービスを呼び出して組み立てる。こうすれば処理の流れはユースケース層を見れば全て分かります。&lt;/p>
&lt;h3 id="メソッドの分類ルール">メソッドの分類ルール&lt;/h3>
&lt;p>サービス層のメソッドは以下の3種類に分類するルールも定めました。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>更新系&lt;/strong>：状態を変更する。戻り値はvoid（値を返すべきではない）&lt;/li>
&lt;li>&lt;strong>参照系&lt;/strong>：副作用を持たない。DTOを受け取ってDTOを返す&lt;/li>
&lt;li>&lt;strong>ドメインロジック系&lt;/strong>：純粋関数として実装し、DTOの変換に特化させる（DB操作や外部サービス連携は行わない）&lt;/li>
&lt;/ul>
&lt;p>この分類があると、メソッドを見た瞬間に「これは何をする処理か」が分かります。レビューする側も楽になりますし、AIにレビューさせる時も判断基準が明確になります。&lt;/p>
&lt;p>:::details 当時作成した設計ドキュメントの全文&lt;/p>
&lt;h2 id="各層の責務">各層の責務&lt;/h2>
&lt;h3 id="プレゼンテーション層">プレゼンテーション層&lt;/h3>
&lt;ul>
&lt;li>ユーザーインターフェースの処理&lt;/li>
&lt;li>HTTPリクエストの受け取りとHTTPレスポンスの返却&lt;/li>
&lt;li>コマンド引数の受け取りとコマンドの実行&lt;/li>
&lt;li>入力のデータ形式をバリデーション&lt;/li>
&lt;li>ユースケースの呼び出し&lt;/li>
&lt;/ul>
&lt;h3 id="ユースケース層">ユースケース層&lt;/h3>
&lt;ul>
&lt;li>手続き的な処理の流れを記述する&lt;/li>
&lt;li>サービス層のメソッドを呼び出して処理を組み立てる&lt;/li>
&lt;li>ビジネスロジックはサービス層に委譲し、ユースケース自身には書かない&lt;/li>
&lt;li>コンストラクタでサービスを受け取る（DIコンテナ経由）&lt;/li>
&lt;li>サービス層からの例外を受け取らず、ユースケース内で例外処理を行わない（例外はプレゼンテーション層に伝播させる）&lt;/li>
&lt;/ul>
&lt;h3 id="サービス層">サービス層&lt;/h3>
&lt;ul>
&lt;li>ドメインロジックとデータアクセスを一つの層で担当&lt;/li>
&lt;li>バリデーション・ビジネスルール・DB操作・外部サービス連携をすべてここに実装&lt;/li>
&lt;li>サービスはサービスをコンストラクタで受け取らない（サービス間のDI禁止）&lt;/li>
&lt;li>不正な状態は例外を投げる&lt;/li>
&lt;/ul>
&lt;h2 id="主要なコンポーネント">主要なコンポーネント&lt;/h2>
&lt;h3 id="dto">DTO&lt;/h3>
&lt;ul>
&lt;li>層をまたぐデータ転送に使用&lt;/li>
&lt;li>&lt;code>readonly class&lt;/code> で実装する&lt;/li>
&lt;li>プロパティはプリミティブ型（Carbon等の標準ライブラリ型はプリミティブ型に詰め替える）&lt;/li>
&lt;li>ユースケースやサービスの引数・戻り値に使用&lt;/li>
&lt;/ul>
&lt;h2 id="依存性の管理">依存性の管理&lt;/h2>
&lt;ul>
&lt;li>LaravelのDIコンテナ（AppServiceProvider.php）はサービスをユースケースに注入する目的のみで使用&lt;/li>
&lt;li>サービス同士はDIコンテナで結びつけない&lt;/li>
&lt;/ul>
&lt;h2 id="コーディング規約">コーディング規約&lt;/h2>
&lt;h3 id="層の責務">層の責務&lt;/h3>
&lt;ul>
&lt;li>各層の責務を明確に分離する&lt;/li>
&lt;li>ドメインロジックはサービス層に書く&lt;/li>
&lt;li>ユースケース層にビジネスロジックを書かない&lt;/li>
&lt;li>サービスはコンストラクタで他のサービスを受け取らない&lt;/li>
&lt;/ul>
&lt;h3 id="サービス">サービス&lt;/h3>
&lt;ul>
&lt;li>サービスのメソッドは単一の責務を持つようにする&lt;/li>
&lt;li>サービスのメソッドの役割は更新系・参照系・ドメインロジック系のいずれかに分類できるようにする&lt;/li>
&lt;li>更新系のメソッドの戻り値はvoidにする（更新系のメソッドは状態を変更することが目的で、値を返すべきではないため）&lt;/li>
&lt;li>参照系のメソッドは副作用を持たないようにし、引数のDTOを受け取ってDTOを返す形にする（副作用があると予測しづらくなり、バグの原因になるため）&lt;/li>
&lt;li>ドメインロジック系のメソッドは純粋関数として実装し、DTOの変換に特化させる（DB操作や外部サービス連携は行わない）&lt;/li>
&lt;/ul>
&lt;h3 id="例外処理">例外処理&lt;/h3>
&lt;ul>
&lt;li>例外を投げる箇所はサービス層に集約する&lt;/li>
&lt;li>API/Controllerの例外ハンドリングはHandler.phpで行う&lt;/li>
&lt;li>Commandの例外ハンドリングはプレゼンテーション層内で行う&lt;/li>
&lt;/ul>
&lt;h3 id="バリデーション">バリデーション&lt;/h3>
&lt;ul>
&lt;li>プレゼンテーション層ではプリミティブ型のデータ形式のバリデーションを行う&lt;/li>
&lt;li>サービス層では仕様のバリデーションを行い、不正な場合は例外を投げる&lt;/li>
&lt;/ul>
&lt;h3 id="インジェクション">インジェクション&lt;/h3>
&lt;ul>
&lt;li>プレゼンテーション層（Command / Controller）では以下のルールでユースケースを受け取る
&lt;ul>
&lt;li>1Command/Controller1アクションならメソッドインジェクションでユースケースを受け取る&lt;/li>
&lt;li>1Command/Controller複数アクションならコンストラクタインジェクションでユースケースを受け取る&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>ユースケース層ではコンストラクタインジェクションでサービスを受け取る
:::&lt;/li>
&lt;/ul>
&lt;h2 id="頭が整理されると手が止まらなくなる">頭が整理されると、手が止まらなくなる&lt;/h2>
&lt;p>思想を整理し、ルールを定義し、ドキュメントに記載することで予想外のメリットがありました。&lt;strong>リファクタリングの作業効率が格段に上がったのです。&lt;/strong>&lt;/p></description></item><item><title>意識を高くするためにテックニュースをGitHub Issueに登録する</title><link>https://example.org/posts/20260418-01/</link><pubDate>Sat, 18 Apr 2026 09:00:00 +0900</pubDate><guid>https://example.org/posts/20260418-01/</guid><description>&lt;p>通勤中だったり始業時間までの時間にはてブ見ながら情報収集するのがルーティンなんですが、休日とかはもっと情報収集したいなーと思ってたんです。
スタバとかでMacで見てたらなんかかっこいいかもだし&lt;/p>
&lt;h2 id="作りたかったもの">作りたかったもの&lt;/h2>
&lt;p>平日は６時に起きて7:30には会社にいるか、エニタイムにいるか、コメダ珈琲で小倉トースト食べてるかなので、毎朝６時に自動実行されているといいなと思いました。
20以上のテックブログやニュースサイトから記事を収集して、Claude api　でジャンル分析してGithub Issueとして登録するシステムです。
収集するテックブログは&lt;a href="https://qiita.com/tomox1001/items/384e27b6259efdb6064e">永久保存版！エンジニア向け情報収集サイトをまとめてみた【定期更新】&lt;/a>とAIKIDOのセキュリティブログとかそんなんです。&lt;/p>
&lt;h2 id="機能">機能&lt;/h2>
&lt;ul>
&lt;li>毎朝06:00に自動実行(Github Actions)&lt;/li>
&lt;li>テックブログ・ニュースサイトから記事を収集&lt;/li>
&lt;li>ジャンルごとにGithub Issueを自動作成&lt;/li>
&lt;li>前日取得記事との差分チェック&lt;/li>
&lt;/ul>
&lt;h2 id="ディレクトリ構成">ディレクトリ構成&lt;/h2>
&lt;pre tabindex="0">&lt;code> news-digest/
├── .github/
│ └── workflows/
│ └── news_digest.yml # GitHub Actions設定
├── scripts/
│ ├── main.py # メイン処理
│ ├── fetch_news.py # スクレイピング
│ ├── summarize.py # Claude API要約・分類
│ ├── create_issues.py # GitHub Issue作成
│ └── utils.py # キャッシュ管理
├── cache/
│ ├── .gitkeep
│ └── articles_cache.json # 前日比較用（自動生成）
├── .gitignore
├── requirements.txt
└── README.md
&lt;/code>&lt;/pre>&lt;h2 id="システムアーキテクチャ">システムアーキテクチャ&lt;/h2>
&lt;pre tabindex="0">&lt;code> ┌─────────────────────────────────────┐
│ GitHub Actions (JST 06:00) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 1. fetch_news.py │
│ - 各サイトをスクレイピング │
│ - BeautifulSoup4で記事抽出 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 2. utils.py │
│ - キャッシュと差分チェック │
│ - 新規記事のみ抽出 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 3. summarize.py │
│ - Claude API (Haiku)で要約 │
│ - ジャンル自動分類 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 4. create_issues.py │
│ - GitHub REST API │
│ - ジャンルごとにIssue作成 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 5. キャッシュ更新 &amp;amp; Git Commit │
└─────────────────────────────────────┘
&lt;/code>&lt;/pre>&lt;h2 id="実行後のissue">実行後のIssue&lt;/h2>
&lt;p>&lt;img alt="image.png" loading="lazy" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162351/56f2a6ec-4b33-4687-9b5e-98f16011d467.png">&lt;/p></description></item><item><title>Hugoの基本</title><link>https://example.org/posts/hugo-basics/</link><pubDate>Fri, 10 Apr 2026 09:00:00 +0900</pubDate><guid>https://example.org/posts/hugo-basics/</guid><description>&lt;p>Hugoを使ったブログ構築の基本的な流れ。&lt;/p></description></item><item><title>Docker活用tips</title><link>https://example.org/posts/docker-tips/</link><pubDate>Sun, 05 Apr 2026 09:00:00 +0900</pubDate><guid>https://example.org/posts/docker-tips/</guid><description>&lt;p>Dockerを使った開発環境構築のtips集。&lt;/p></description></item><item><title>CSSアニメーション入門</title><link>https://example.org/posts/css-animation/</link><pubDate>Sat, 28 Mar 2026 09:00:00 +0900</pubDate><guid>https://example.org/posts/css-animation/</guid><description>&lt;p>CSSだけで作れる洗練されたアニメーションの作り方。&lt;/p></description></item><item><title>JavaScript モダン記法</title><link>https://example.org/posts/js-tips/</link><pubDate>Fri, 20 Mar 2026 09:00:00 +0900</pubDate><guid>https://example.org/posts/js-tips/</guid><description>&lt;p>ES2024以降のモダンなJavaScript記法まとめ。&lt;/p></description></item><item><title>About</title><link>https://example.org/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://example.org/about/</guid><description/></item></channel></rss>