OmniAICreator/Qiita-1.07M huggingface dataset:
VSCodeコード折りたたみ操作・作業効率が上がるショートカット集

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94360/40f8fca1-38de-4bff-bdc5-2c2a0ff0dd8d.png)

## VSCodeの「折りたたみ」って使ってる？

ファイルの行数が増えてくると、目的の場所を見失いやすくなります。そんなときに便利なのが VSCode の **「コードの折りたたみ／展開」** 機能です。この記事では、日常的に使えるショートカット操作に絞って、覚えておくと便利な折りたたみ操作を紹介します。

ここで取り上げるショートカットは、`Ctrl + K` を起点とする "2ストローク操作" です。これは `Ctrl`キーを押しながら2つのキーを順に押すだけでOK。実際にはスムーズな1動作のように直感的に使えます。

## `Ctrl` + `KL` 折りたたみ状態をトグル：最もシンプルな操作

「畳むか開くか」を意識せず、**トグルで切り替えたい**ときに便利なのがこのショートカットです。**マウスで折りたたみを行う操作と同じ動き**をキーボードで再現できます。

### 操作：

- `Ctrl + KL` **折りたたみ／展開をトグル**
- `Ctrl + KJ` すべて展開（元に戻す）

## `Ctrl` + `K-` 今見ている場所以外をすべて折りたたむ

- 今作業している関数・クラスに集中したいとき
- その他のコードを一時的に視界から除外し、 Zen モードのように集中した編集状態を作る

### 操作：

- `Ctrl + K-` **選択したブロック以外をすべて折りたたむ**
- `Ctrl + KJ` すべて展開（元に戻す）

このショートカットは、現在選択中のブロック以外をすべて折りたたんでくれるため、特定の処理だけに集中したい場面で有効です。

## `Ctrl` + `K,` 任意の範囲を手動で折りたたむ（おすすめ！）

- コード構造に関係なく、自分が「ここを折りたたみたい」と思った範囲を自由に指定できる
- 画面共有でコードレビューを受ける時など、不要な部分を隠してあげるとレビュアーに説明しやすい

### 操作：

- `Ctrl + K,` **選択範囲から折りたたみ範囲を作成する**
- `Ctrl + KJ` すべて展開（元に戻す）

この操作を使えば、言語の構文やインデントに依存せずに、任意の範囲を自由に選んで折りたたむことができます。ちょっとした整理や集中作業にぴったりです。

## `Ctrl` + `K0` 全体の流れを残して折りたたむ

- WordPress の `functions.php` やフレームワークの `bootstrap.php` のように、クラスや関数で構造化されていないトップレベルのコードが並ぶファイルで、処理の流れをざっくり把握したいときに便利
- これらのファイルは、処理フローを抽象的に書くために使われますが、その場しのぎの追記が累積し、複雑化していくケースが少なくありません

このようなときに折りたたみ操作を活用することで、構造を一時的に整理して見通しを得ることができます。

### 操作：

- `Ctrl + K0` **すべて折りたたむ**
- `Ctrl + KJ` すべて展開（元に戻す）

## `Ctrl` + `K/` 複数行コメントを折りたたんで、コードを見渡しやすくする

PHPやTypeScriptでは各メソッドにPHPDocやJSDocを書きますが、

```php
/**
 * この関数は...
 * @param int $id
 * @return string
 */
public function getName(int $id): string {
    ...
}
```

このようなコメントがファイル全体に散らばっていると、構造が見づらくなりがち。そんなときは「コメントだけ」を一括で折りたたんで、見渡しをスッキリさせましょう。

### 操作：

- `Ctrl + K/` **すべての複数行コメントを折りたたむ**
- `Ctrl + KL` 一部のコメントだけ展開
- `Ctrl + KJ` すべて展開（元に戻す）

## おすすめの覚え方

よく使うショートカットとして特におすすめなのが以下の2つ。

- `Ctrl + KL`（折りたたみ／展開をトグル）
- `Ctrl + KJ`（すべて展開）

この2つを覚えておくだけで、多くの場面をカバーできます。`J`, `L` は、キーボード上で `K` の左右に隣接しているため簡単に覚えることができます。

## 最後に：折りたたみ操作とリファクタリングの関係

行数が長く複雑な構成のファイルは、そもそもリファクタリングの対象です。折りたたみ操作に慣れることで、複雑なファイルもある程度は「扱える」ようになりますが、そのまま放置すると、メンテナンス性や可読性は損なわれたままです。

折りたたみ操作は、**整理のきっかけ**や**リファクタ前の視界確保**に有効なツールです。まずは「どこが複雑なのか」を把握するために活用し、最終的にはコード自体をシンプルにする方向へつなげていきましょう。
Set で一発解決！検索履歴の重複ワードを効率的に管理する方法

PaizaのCランク問題「検索履歴」を解いていて、最初は `Map` でゴリ押ししようとしたけど、実は `Set` を使えばめちゃくちゃシンプルに書けると気づいた！

今回は、検索履歴の重複ワードを排除して、最適な履歴リストを作る方法を解説する。

## <br>📚 問題概要

与えられた検索ワードを以下のルールで管理しよう。

既に履歴にあるワードが再度入力された場合 → 履歴から削除し、先頭に追加。

履歴にないワードが入力された場合 → そのワードを履歴の先頭に追加。

すべての入力を処理した後の履歴を表示。

<br>📚 入力例
```
5
book
candy
apple
book
candy
```

📃 出力例
```
candy
book
apple
```

## <br>❌ NG例: 配列だけでゴリ押ししたパターン

最初は `Array` の `includes()` を使って頑張ろうとした。
```js
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];

rl.on('line', (input) => { lines.push(input); });

rl.on('close', () => {
    const N = Number(lines[0]);
    const words = [];
    
    for (let i = 1; i <= N; i++) {
        // 既にある場合は削除して追加
        if (words.includes(lines[i])) {
            words.splice(words.indexOf(lines[i]), 1);
        }
        words.unshift(lines[i]);
    }
    words.forEach(word => console.log(word));
});
```
❌ 問題点:

`includes()` の計算量が O(N)  なので、大量データだと遅くなる。

`splice()` で要素削除すると、配列全体をシフトするためコストが高い。

## <br>✅ OK例: Set で最適化！

`Set` を使うことで、高速に重複チェックが可能！
```
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];

rl.on('line', (input) => { lines.push(input); });

rl.on('close', () => {
    const N = Number(lines[0]);
    const words = lines.slice(1).reverse(); // 逆順に取得
    const seen = new Set(); // 出力済みの単語を記録

    words.forEach(word => {
        if (!seen.has(word)) {
            console.log(word);　//出力
            seen.add(word); //Setに追加
        }
    });
});
```
✅ 改善点:

`Set` の `has()` は O(1) で超高速チェック！

`reverse()` を使うことで、リストを逆順にし `unshift()` を使わずに済む。

## <br>📝 新しく学んだこと

✅ `Set` で一瞬で重複チェック！

`Set` は 重複を許さない コレクション。だから `has()` で存在確認しつつ、重複なくデータを保存できる。
検索履歴の問題では、`Set` を使ってすでに出力した単語を記録し、二重出力を防いでいる！

✅ `reverse()` で順番をひっくり返す！

配列の要素を 逆順に並び替える 便利メソッド。
検索履歴は「最後に入力した単語が先に出る」から、`reverse()` で逆順にして処理するのがポイント！

✅ `unshift()` で配列の先頭に追加！

`push()` が末尾に追加するのに対して、`unshift()` は 先頭に追加する。
ただし `unshift()` は 配列全体をずらす から、大量データには向かない！

## <br>🔍 まとめ

✅ `Set` を使えば、O(1) の高速な重複チェックができる！
✅ `reverse()` で履歴を逆順にすれば `unshift()` を使わずスッキリ！

検索履歴を管理する問題を通して、 データ構造の選び方でパフォーマンスが大きく変わる ことを学んだ！

<br>[僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/04/03/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e6%a4%9c%e7%b4%a2%e5%b1%a5%e6%ad%b4%e3%82%92%e7%ae%a1%e7%90%86%ef%bc%81%e9%87%8d%e8%a4%87%e3%83%af%e3%83%bc%e3%83%89/)
GitHubアカウントの切り替え

## はじめに
会社のプロジェクトは会社のGitHubアカウントで、個人プロジェクトは個人のアカウントで管理するのが一般的です。
しかし、2つのアカウントを切り替えるのは手間がかかり、SSHキーの衝突によって認証エラーが発生することもよくあります。
この記事では、SSHの設定によってアカウントの切り替えを自動化し、安定して管理する方法をご紹介します。

## デバッグ：どのSSHキーが使用されているか確認する
SSH接続時に使用されているキーを確認するには、以下のコマンドを実行します：

```bash
ssh -vT git@github.com
# 出力：...
#      debug1: Offering public key: /Users/you/.ssh/**id_ed25519_personal**
#      ...
```

このログから、GitHubに提供されているキーがどれかを確認できます。
もし意図したアカウントのキーと一致していない場合は、設定の修正が必要です。

## SSHキーの作成
アカウントごとに別々のSSHキーを作成します：

**個人用アカウント**
```bash
ssh-keygen -t ed25519 -C "me@example.com" -f ~/.ssh/id_ed25519_personal
```

**会社用アカウント**
```bash
ssh-keygen -t ed25519 -C "me@company.com" -f ~/.ssh/id_ed25519_work
```

## GitHubに公開鍵を登録する
各アカウントのGitHubのSSH設定ページで、上記で生成しt該当の公開鍵（.pubファイル）を登録します。

![Screenshot 2025-04-03 at 23.49.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529304/101a8f05-ecb5-4427-a93d-17a0231b9e9f.png)

## ~/.ssh/configの設定
SSH接続時に使用するキーを明示的に指定することで、衝突を防ぎます：

**個人アカウント用**
```bash
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
```

**会社アカウント用**
```bash
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
```

- HostはGitのリモートURLで使用する別名です。
- IdentitiesOnly yesにより、指定したキーのみが使用され、エージェントやデフォルトのキーは無視されます。

## 認証テスト
設定が正しく行われているか、以下のコマンドで確認します：

```bash
ssh -T git@github-personal 
# 出力：Hi personal-github-username! You've successfully authenticated, but GitHub does not provide shell access.
```

```bash
ssh -T git@github-work
# 出力：Hi work-github-username! You've successfully authenticated, but GitHub does not provide shell access.
```

## プロジェクトごとのGitリモート設定
各プロジェクトで正しいSSHキーが使用されるように、リモートURLを設定します。

**個人プロジェクトの場合：**
```bash
git remote set-url origin git@github-personal:your-username/your-repo.git
```

**会社プロジェクトの場合：**
```bash
git remote set-url origin git@github-work:company-org/repo.git
```

これにより、それぞれのプロジェクトが自動的に正しいSSHキーを使ってGitHubにアクセスします。
🚀【超実践】LangMem × GPT-4o で「記憶するAI」爆速構築！Cloud SQLで永続化も！！【5分で動くサンプル付き】

# はじめに
LangMem、とっつきやすいですが、Storeの永続化をしないと、
忘れんぼ MEMちょ、になってしまいます😢

でも、なんだかんだ情報が少なくて、Storeとpostgreの連携がわかりにくかったので、
サンプルコード作ってみました！

説明は次回するとして、とりあえず試してみましょう！

## やってみよう！！
[GCP の Cloud SQL とサービスアカウントの設定は終了している前提で進めます！]

## 1️⃣ リポジトリをCloneしてください！
https://github.com/dev-cat-v/langmem-postgre/commits/main/

## 2️⃣ `docker-compose.yaml` を設定
```docker-compose.yaml
environment:
    - POSTGRES_URL=postgresql://{user}:{pass}@cloudsql-proxy:5432/{dbname}
~~ 中略 ~~
cloudsql-proxy:
    - instances={Cloud SQLの接続名}=tcp:0.0.0.0:5432
```

## 3️⃣ .env.local を設定
```.env.local
OPENAI_API_KEY={your open ai key}
POSTGRES_URL=postgresql://{user}:{pass}@cloudsql-proxy:5432/{dbname}
```

## 4️⃣ GCPのサービスアカウントのsecretsを配置
```
.
├── Dockerfile
├── backend
│   └── api
│       ├── __init__.py
│       ├── main.py
│       └── routers
│           └── chat.py
├── docker-compose.yaml
└── secrets
    └── service_account.json <== ここに挿入
```

## 5️⃣ docker-compose実行
```
docker-compose up --build 
```

以下ログが出たら、起動完了です！！
```
demo-api_1        | Store initialized!
```

# 動作確認
### こんな感じで名前を覚えさせて...!!!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722068/3e66db43-bce3-47d6-8b60-e357adcd1122.png)

### 聞いてみると？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722068/fd68d97b-3f46-4734-a820-733fa19e9aed.png)

### ちゃんと答えてくれますね！！

# 仕様
一応、ユーザーごとに別の記憶を保持できるようになってます。
あと、どのように記憶されているか確認できるように、レスポンスに記憶全てを含めるようにしています。
細かいところは、僕の指が痛くない時に、いつか書きますww

# 発展系
### 📝 このリポジトリを使ってもらった人は、CloudRunにもすぐデプロイできます！
### 😭 prompt_optimizer 使いたいけどむずいねほんと。memory_toolとの関係性がよくわからんです。
### ‼️ なんか前後の文脈覚えられないのと、あんまりフランクにしてくれないのがイマイチですね。もっと人間ぽくしたい。そこは色々調整ですかね！

# 最後に
### ‼️「いいね」・「ブックマーク」・「フォロー」してくださると泣いて喜びます‼️
### こういうの知りたい、興味あるなどコメントくだされば、ChatGPTより頑張って調べて記事にしますので、コメント待ってます 笑
【Next.js】Router機能について調べてみた





## Router機能とは？

てすとてすとてすとてすと



## サンプルコード



```bash
<div className="mb-4 p-3 bg-[#F7F6F3] rounded-md">
  <h4 className="text-sm font-medium text-[#37352F] mb-2">含まれるブロックの種類:</h4>
  <div className="flex flex-wrap gap-2">
    {blockTypes[item.id]?.map((type, index) => (
      <span 
        key={index}
        className="px-2 py-1 bg-white rounded text-sm text-[#37352F] border border-[#E9E8E6]"
      >
        {type}
      </span>
    ))}
  </div>
</div>
```

> 💡 てすとてすてすと
【Flutter】開発中にリリースビルドを試す

Android/iOS両OSで開発している時に、
**開発中のdebugビルドだとうまくいくが、リリースしたアプリだとグレー画面**
で表示されることがあった。

その際の知見をまとめておく！

# Androidのリリースビルド

以下コマンドを実行

```bash
flutter build apk --release
```

　

apkファイルが以下パスに出力される

```bash
build/app/outputs/flutter-apk/app-release.apk
```

　
作成されたapkファイルを実機にインストールする

```bash
flutter install
```



実機やエミュレータなど接続していたらどの端末にインストールするかの確認が出るので
番号を押下する



# iOSのリリースビルド

以下コマンドを実行

```bash
flutter build ios --release
```

ipaファイルが以下パスに出力される

```bash

/build/ios/iphoneos/Runner.app

```

以下流れはAndroidと同じ。

```bash
flutter install
```
を実行して実機にiOSリリースビルドしたipaをインストール

# まとめ

開発中のデバッグビルドとリリースビルドで差異がある場合が出てくるとは。。
flutter沼だな。。
Laravelの session()->flash() と view() の違いを整理してみた【一時データ vs ビュー描画の本質】

# はじめに

Laravelでよく使う関数やメソッドに、

- `session()->flash('key', 'value')`
- `return view('viewname', [...])`

があります。

一見、全く違う用途に思えますが、「データをどこかに一時的に渡す」という点では共通点もあります。

この記事では、`flash()` の意味と使い方、`view()` との違いや使い分けについて、整理してみました。

---

# ①`session()->flash()` とは？

## 意味：
Laravelのセッションに「**1回限りの一時データ**」を保存するためのメソッドです。

```php
session()->flash('message', '投稿が完了しました！');
```
**特徴:**
- **次のリクエストで1度だけ取り出せる**
- 表示された後は自動で削除される
- 通常は redirect() と一緒に使う

## 使用例:
```php
public function store(Request $request)
{
    // 保存処理...
    session()->flash('message', '保存しました！');
    return redirect()->route('posts.index');
}
```
**Blade側:**
```blade
@if (session('message'))
    <div class="alert alert-success">
        {{ session('message') }}
    </div>
@endif
```
→投稿一覧画面にリダイレクト後、**「保存しました！」という1回限りのメッセージが表示される**

# ②view() 関数とは？
**意味:**
特定の Blade テンプレート（ビュー）を表示する関数。コントローラーやルートでよく使います。
```php
return view('posts.index', ['posts' => $allPosts]);
```
**特徴:**
- ビューに変数を**その場で直接渡す**
- セッションやリダイレクトを挟まず、**即時に表示**

**使用例:**
```php
public function index()
{
    $posts = Post::all();
    return view('posts.index', ['posts' => $posts]);
}
```
Blade側:
```blade
@foreach ($posts as $post)
    <p>{{ $post->title }}</p>
@endforeach
```

# ③共通点と違い
![IMG_7754.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/6dcc7f57-4610-45d0-89c2-2a164b08fd43.jpeg)

# ④おまけ：redirect()->with() との違いは？

**実は with() は flash() のショートカットです：**
```php
return redirect()->route('home')->with('message', 'ようこそ！');
```
これは内部的に:
```php
session()->flash('message', 'ようこそ！');
```
と同じ処理をしています。

# ⑤まとめ
![IMG_7755.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/8497caa6-077b-4882-b6fc-08197fa83e79.jpeg)

**「データを一時的に渡す」のか、「今すぐ描画に使う」のか**を意識すると、両者の違いがスッキリ理解できます。
CH32V003をUSBのHIDデバイスにして、Windowsパソコンとデータ送受

# 経緯
　CH32V003が乗った基板が安かったので購入した。
　Type-Cのコネクタが付いて居る、チップ自体はUSB機能を持たないが、
　電源入力だけじゃ勿体ないよな。
　◆◆◆　よし、USB通信に使ってみよう　◆◆◆
　サンプルはその辺のネットに転がっているだろう。

# HIDとしての動作
　PC(パソコン)側からデータ送信し、デバイス(CH32V003)からデータを受け取る。
　単にHIDデバイス(キーホードやマウス)として動作するだけでなく、
　パソコンとの間のデータのやり取りを行う、インテリジェンスデバイスとして動作させる。
　USBシリアルでもデータのやり取りは可能だが、専用のDriverが必要となる。
　HIDデバイスで有ればDriverの作成は不用であり敷居が低い。
  
　大昔はCPUの信号を直接取り扱うことが出来て、其れにはプリンタポート等が利用されてきた。
　しかし今では、プリンタポートなんか付いてるパソコンは有るだろう。
　PCと通信する場合はDriverという、極めて難易度の高いソフトが必要となる。※MSの認可も必要。
　HIDデバイスはそれに代わる通信手段で有ろう。※策度が遅いが。


# 開発環境(ハード)
　「[前回](https://qiita.com/hi631/items/8b529e568934212964c6)」に同じ。
![usb_hid_conect.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/058341fb-0cf4-460d-8914-b00be60bf3aa.jpeg)

# 接続
　下記を基板とWCH-LinkE間で接続。
  　※ＴＸ・ＲＸはプログラム内通信で使う。WCH-LinkEはUSBシリアルとして動作。
　　　V003では入出力のピン配置を部分的に変更可能。
　　　USBとバッティングするのでこの位置(PC0,PC1)に設定。
　　基板　　　WCH-LinkE
　　Ｖ　　　　３Ｖ３　　　電源
　　Ｇ　　　　ＧＮＤ　　　グランド
　　ＰＤ１　　ＳＷＤＩＯ　書き込み信号
　　ＰＣ０　　ＲＸ　　　　シリアル送信
　　ＰＣ１　　ＴＸ　　　　シリアル受信
　上記配線に、USB用に下記を追加。
 　　基板　　　　基板
　　ＰＡ１(D+)　ＰＤ５　　　Ｄ＋信号
　　ＰＡ２(D-) 　ＰＤ６　　　Ｄ－信号
　　Ｖ(1.5K) 　　ＰＡ２　　　Ｄ－を1.5KΩの抵抗でプルアップ
　　※Type-CのD+とD-への接続と、ロースピードを指定するD-のプルアップが必要。
　　　例示基板では、PD5/6がUSB端子に基板上で繋がっているため、この様な妙な配線になる。
　　　当然、PD5/6は入出力に使ってはならない。
　　　基板の電源はUSBから来るので、WCH-LinkEとは繋いでいない。

# 開発環境(ソフト)
　「[前回](https://qiita.com/hi631/items/8b529e568934212964c6)」に同じ。


# CH32V003側のソフト(CH32V003 USB_HID)の説明
　「[ソフトの格納場所(Github)](https://github.com/hi631/CH32V003/tree/master/usb_hid) 」に格納。
　　※今回は構成が多少複雑なのでインクルードするファイルを全て纏めた。(行儀が悪いが)
　　　このまま make を実行すれば、usb_hid.hexが出来上がるので、WCHLinkEで書き込む。
　　※ビューアーでHIDデバイスが見えれば動作正常。
![hid_usb_tv.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/3f01c74b-7811-4b79-8ec0-7b22b208bf14.jpeg)
　機能はPCからの送信データをシフトして、送り返しているだけだが、
　データの4バイト目は、送信データをPC5/6/7にセットして、PC2/3/4を読みだし写真データに書いている。
　　※usb_hid.cのusb_rx()/usb_tx()を参照。

# PC側のソフト(CH32V003 HIDAPI)の説明
　「[ソフトの格納場所(Github)](https://github.com/hi631/CH32V003/tree/master/hidapi) 」に格納。
　ソフトはAPI本体(hidapi)と、APIの呼出ソフト見本(3種類)で出来ている。
  　hidapi 	 API本体(DLL)
　　hidtest　APIをCから呼び出している。
　　ccall  　APIをC#コンソールから呼び出している。
　　callhid　APIをC#フォームから呼び出している。
　　※呼出ソフトはCで作製されたDLLの呼出方法確認用、callhid以外は多分不要。
　ソフトはvisualstudio2022でコンパイルを確認している。
　　※hidapi.slnを指定して起動し、一端ソリューションのリビルドを行っておく事。
　ソフトを起動し"通信開始"を押せは、通信が継続される。
![usb_hid_txrx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/d1663ba4-0d87-4156-b08c-5ba0f8a2d3bb.jpeg)


# 通信状況
　400usに一回程度、送受信(8byte)を行っている。
　下記は送受信を2回実行。※途中にkiip信号が挟まっている。
　１÷0.0004×8=20KB/秒=160Kbps/秒の通信速度となる。※早くはない。
![tx_rx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/5a40739d-437c-4727-8ba6-2b0c9eba95f1.jpeg)
　下記は送信データ
 ![tx_sig.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/d9b9e3f1-e475-42bb-8e92-6c96e1ec8111.jpeg)


# 感想
　市販されているものも有るが、PC連動を深く考えて無い気がする。
　PCの持つデータと連動させれば、面白い物が作れそうな気がする。
　なお、上記記載内容は全て無保証であり、各自の責任においてご利用願います。
Society5.0時代における介護サポートシステムの構築をしてみた

# Society5.0とは？
https://business.ntt-west.co.jp/glossary/words-00210.html
上記より抜粋
Society5.0（ソサエティー5.0）とは、2016年に閣議決定された「第5期科学技術基本計画」において、日本がめざすべき未来社会の概念です。
狩猟社会「Society 1.0」、農耕社会「Society 2.0」、工業社会「Society 3.0」、情報社会「Society 4.0」の次に始まる未来社会が「Society5.0」であり、「超スマート社会」とも呼ばれます。
内閣府が提唱するのは、「サイバー空間（仮想空間）とフィジカル空間（現実世界）を融合したシステムにより、経済発展と社会的課題の解決を両立する人間中心の社会」です。
さらに、「必要なもの・サービスを、必要な人に、必要な時に、必要なだけ提供し、社会の様々なニーズにきめ細かに対応でき、あらゆる人が質の高いサービスを受けられ、年齢、性別、地域、言語といった様々な違いを乗り越え、活き活きと快適に暮らすことのできる社会」という定義もあります。

### こんなかっこいい事書いてますが、既製品のものを有り合わせでつくった仕組みです。
おなじ状況の方がいれば参考に利用いただければいいなと思い今回投稿します。


# 現状
2018年から祖母の高齢化に伴い１人暮らし。
自力での生活が困難となっており、実家は中国地方に、親戚一同は関西や関東に居住をしており定期的に帰宅するような状況で平日の安否確認は電話で数分程度の会話となっており、詳細な生活実態は把握できない状況となっていました。
この状況をよりきめ細やかな生活実態の把握をすべく、本プロジェクトを実施する事になりました。

## 当初導入していたもの
ペット用のカメラを数箇所配置しており、遠隔で除き、生活実態を把握しており、徘徊などに対して警戒をしていました。ただ、介護のみまもりと介護される側のプライバシーの両立を確保したいとの想いで、こちらは廃止する方向で検討していました。
# 用意したもの
-モバイル回線
-IoTドアセンサー
-モーションセンサー
-Alexa(モニター付き)

# 苦労したネット回線の敷設
８０代の高齢者の家にはNW回線などはなく黒電話のみのためネット回線の用意がどうしても必要でした。
料金としては安価で月1500円以下の事業者を探し、さまざまなMNOやMVNOなどを検証し、モバイル端末を選定しドコモ回線が一番安価であるも端末の入手や電波の受信状況などを検証し、最終的に
安価に入手可能なUQWIMAXの機種を中古で購入し、
KDDI系のSIMで500Kbps(現在は1.5Mbps)でAlexaのビデオ通話可能であったオプテージのmineoに決まりました。

# 準備
準備ができれば、まずは購入品の設置です。
実家のトイレや玄関など定期的に通過する場所にIoTドアセンサーやモーションセンサーを設置します。
(センサーはAmazonで1個2000円程度で購入できるエジソンスマートのセンサーを利用。)
設置後は12時間動作がなければ通知をするなど、柔軟な設定が可能です。
AlexaはAmazonアカウントをスマホとデバイスで共通化し呼びかけにする事でデバイス側は自動で着信できるため高齢者側は操作不要でビデオ通話が可能です。

# 運用

運用開始後は毎日顔を合わせて会話できる事から表情などがより見えるようになり、通常と異なるトイレに行ってないなどの状況もわかるようになりました。
また、今回はここまでとしますが、
現在はWIFI(AD+EAP認証を構築してSSIDをだしています。)で在圏状況を確認したり、IoTとAIを活用して日々の生活と大きく異なるライフリズムの解析を行い異常時には通知を出す仕組みを構築したりしています。
またMineoは1.5Mbpsに速度がアップした事から実家訪問時にWIFIで動画を見たりと帰省時にも活用できる回線となりました。
UE5のニューラルネットワーク

会社の勉強会用に「UE5のニューラルネットワーク」というタイトルで
スライドを作成したのでドクセルに公開してみました。

ドクセルが１パワポのアップデート容量が50MBまでだったので
容量圧縮のためにスライド内の動画をYoutubeに逃がしたりと以外にやってみると大変でした。。。
.gifファイルも再生されないんですね。。。PDFに変換されるから？

<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/KQRQ2X/embed" data-aspect="0.5625"></script><div class="docswell-link"><a href="https://www.docswell.com/s/3359584/KQRQ2X-2025-04-03-222759">UE5のニューラルネットワーク by @3359584</a></div>
37歳の奮闘（転職）


最高の仲間たちから離れ、最高の業務から離れ、寂しい気持ちでいっぱいです。
一方で、今の会社の皆様も最高ですし、業務も最高です。
つまりは、前に進むしかないのです。。！
定年まで勤めあげたい。

国家試験を最短1年で取ってみようと考えています。
そう、ネスペ。何年かかるかな。業務を行いながらなので。

CCNAを丸覚えでクリアしなくてよかったと思うことでしょう。

では。
JavaScriptにおける再利用可能なコンポーネント設計：引数・状態・副作用の分離戦略


## 概要

「再利用できるコンポーネント」とは、**使い回し可能なUI部品**という意味だけではない。  
それは**“責務が単一で、入力（Props）・状態（State）・副作用（Effects）が明確に分離された構造”**である。

JavaScript（およびReact/VueなどのUIライブラリ）において、コンポーネントが肥大化する原因は、  
**処理の責任と関心ごとが混在していること**にある。

本稿では、**引数・状態・副作用の構造的分離による、拡張可能でテスタブルな再利用コンポーネント設計戦略**を解説する。

---

## 1. 責務の単一性（SRP）を軸に設計

```tsx
// ❌ 責務が混在：描画・ロジック・副作用
function UserCard({ userId }) {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetch(`/api/user/${userId}`).then(res => res.json()).then(setUser);
  }, [userId]);
  return <div>{user?.name}</div>;
}
```

```tsx
// ✅ 分離：データ取得と表示の責務を明確に
function useUser(userId) {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetch(`/api/user/${userId}`).then(res => res.json()).then(setUser);
  }, [userId]);
  return user;
}

function UserCard({ userId }) {
  const user = useUser(userId);
  return <div>{user?.name}</div>;
}
```

- ✅ ロジックの分離により、**テストや差し替えが可能**
- ✅ 表示コンポーネントは**純粋関数的に記述できる**

---

## 2. 入力（Props）設計の明確化

```tsx
function Button({ label, onClick, type = 'primary' }) {
  return <button className={`btn btn-${type}`} onClick={onClick}>{label}</button>;
}
```

- ✅ 引数は**明示的に列挙し、オブジェクトごとに渡さない**
- ✅ `label`, `onClick`, `type` などの責務は**明確で単純**

---

## 3. 状態（State）の封じ込め戦略

- ✅ 「内部状態」と「外部から渡す状態」は明確に分離する
- ✅ 入力が全てで決まるものは **stateless（純粋）コンポーネント** に

```tsx
function Counter({ count, onIncrement }) {
  return (
    <button onClick={onIncrement}>
      Count: {count}
    </button>
  );
}
```

```tsx
function CounterContainer() {
  const [count, setCount] = useState(0);
  return <Counter count={count} onIncrement={() => setCount(count + 1)} />;
}
```

- ✅ 再利用性を上げるには、**stateful → statelessへの分離**が基本戦略

---

## 4. 副作用の構造化と限定化

```ts
useEffect(() => {
  document.title = `Page ${page}`;
}, [page]);
```

- ✅ 副作用は `useEffect` や外部API呼び出しとして**明示的に分離**
- ✅ **表示・ロジック・副作用を物理的にファイル分離**することも検討

---

## 設計判断フロー

```text
① このコンポーネントは表示だけか？ → statelessに切り出し可

② 副作用はどこで起きているか？ → useEffect に限定し、他から切り離す

③ 状態は本当に必要か？ → propsで注入可能なものは外部化

④ テスト可能か？ → 表示とロジックを分離して、Mockが差し替えられる構造か

⑤ コンポーネントの役割は1文で説明できるか？ → 単一責務に絞る
```

---

## よくあるミスと対策

### ❌ 状態を持つコンポーネントが表示とAPI処理とイベント処理すべて抱える

→ ✅ **状態・副作用・ロジックをフック化 or containerに分離**

---

### ❌ 小さすぎるコンポーネント分割でprops地獄に

→ ✅ **責務と再利用性を基準に分割深度を調整**

---

### ❌ propsとしてオブジェクトや関数をそのまま渡して再レンダリング地獄

→ ✅ **useMemo / useCallback / 分解して渡すことで安定性確保**

---

## 結語

再利用可能なコンポーネント設計とは、**「どこでも使える汎用UI部品」ではない。**  
それは**“引数・状態・副作用の境界を設計として分離し、拡張性と保守性を担保する構造戦略”**である。

- 表示は表示、ロジックはロジック、副作用は副作用で切り分ける  
- 再利用性とは「どこでも使える」ではなく、「責務が明確で読みやすい」こと  
- 入力と出力を制御可能な設計が、保守性・テスタビリティを大きく高める

**JavaScriptにおける再利用可能なコンポーネント設計とは、  
“責務の分離を通じて、再利用・差し替え・検証可能性を最大化するための構造設計である。”**
JavaScriptにおけるタイミング制御設計：debounce, throttle, requestAnimationFrame の選定戦略


## 概要

高頻度で発火するイベント（スクロール、リサイズ、キー入力など）は、  
**そのまま処理するとパフォーマンスのボトルネック**になり得る。

このような場面で重要なのが、**イベントの発火頻度を意図的に制御する技術：debounce / throttle / requestAnimationFrame** である。

本稿では、それぞれの構文と設計意図を明確にし、  
**「いつ使うべきか」「何を制御すべきか」「どう設計すべきか」**にフォーカスして解説する。

---

## 1. debounce（デバウンス）

### 意図：**最後の1回だけ処理したい**

```ts
function debounce(fn, delay) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}
```

```ts
const onInput = debounce((e) => {
  console.log('Searching:', e.target.value);
}, 500);
```

- ✅ 入力フィールドの変化 → **最後の入力だけを処理したい時に有効**
- ✅ ネットワークや再描画コストの高い処理を**不要に走らせない**

---

## 2. throttle（スロットル）

### 意図：**一定間隔ごとに処理したい**

```ts
function throttle(fn, interval) {
  let lastTime = 0;
  return function (...args) {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn.apply(this, args);
    }
  };
}
```

```ts
const onScroll = throttle(() => {
  console.log('scrolling...');
}, 100);
```

- ✅ スクロールやリサイズ → **一定間隔でしか処理したくない**
- ✅ CPU負荷の軽減・描画フレームの安定化に寄与

---

## 3. requestAnimationFrame（rAF）

### 意図：**次の描画タイミングで最適に実行したい**

```ts
function onScroll() {
  requestAnimationFrame(() => {
    updateScrollPosition();
  });
}
```

- ✅ アニメーション、DOM描画の**フレーム最適化**
- ✅ ブラウザのレンダリングタイミングに合わせて実行されるため**スムーズなUIを実現**

---

## 4. 選定マトリクス

| イベント種別     | 処理の性質             | 推奨制御法           |
|------------------|------------------------|----------------------|
| 入力欄の検索     | 最終値のみ使いたい     | `debounce`           |
| スクロール監視   | 一定間隔で実行したい   | `throttle`           |
| ウィンドウリサイズ | 軽量処理だが高頻度      | `throttle` または `rAF` |
| カーソル追従     | 毎フレーム更新が理想   | `requestAnimationFrame` |

---

## 設計判断フロー

```text
① イベントがどの程度の頻度で発火するか？ → msオーダーなら制御必須

② 処理は「最後の1回」だけで良いか？ → debounce

③ 処理は「一定間隔ごと」に行うのが理想か？ → throttle

④ 描画パフォーマンスへの影響はあるか？ → requestAnimationFrame

⑤ 重い処理か？ → debounceでバースト回避 or throttleで制限
```

---

## よくあるミスと対策

### ❌ スクロールイベントに直接処理をバインドしてカクつき発生

→ ✅ **throttleまたはrAFで制限をかける**

---

### ❌ debounceでフォームバリデーションして、ユーザー体感が遅延

→ ✅ **即時バリデーション or throttleに変更する戦略を検討**

---

### ❌ throttleとrAFを混用し、更新がダブって逆効果

→ ✅ **一つの制御構文に統一し、挙動とフレーム同期を整理する**

---

## 結語

タイミング制御は「パフォーマンスのため」だけではない。  
それは**“処理の意図・タイミング・責務を設計として明示することで、ユーザー体験と開発効率を両立させる戦略”**である。

- debounce は「最後の一回」
- throttle は「一定間隔」
- requestAnimationFrame は「最適な描画タイミング」

**JavaScriptにおけるタイミング制御とは、  
“イベント頻度と処理責任のバランスを設計として表現し、性能と体験を同時に最適化する技術戦略である。”**
JavaScriptにおける非同期エラー制御と例外の伝播設計：async/awaitとcatchの責務分離

## 概要

非同期処理におけるエラーハンドリングは、  
**「try-catch で囲むかどうか」ではなく「どこで責任を受け持つか」** という設計の問題である。

`async/await` を採用することで制御フローは同期的に読みやすくなるが、  
それに伴って例外の伝播・スコープ・責務の境界が曖昧になりやすい。

本稿では、**非同期処理におけるエラーの構造化、catchのスコープ設計、try-catchの責務分離、再throwとロギングの設計判断**について、実践的に解説する。

---

## 1. async 関数と例外伝播の基本

```ts
async function fetchUser(id) {
  const res = await fetch(`/api/user/${id}`);
  if (!res.ok) throw new Error('User not found');
  return await res.json();
}
```

```ts
async function main() {
  try {
    const user = await fetchUser(1);
    console.log(user);
  } catch (e) {
    console.error('ユーザーの取得に失敗しました', e);
  }
}
```

- ✅ `await` でエラーが発生した場合は**通常のthrowと同様にcatchへ伝播**
- ✅ catch は**呼び出し元の責務で処理する**

---

## 2. 非同期関数内のtry-catch設計

```ts
async function safeLoad() {
  try {
    const user = await fetchUser();
    return user;
  } catch (err) {
    logger.warn('fetchUser failed:', err);
    throw err; // 再throwで責任を上に渡す
  }
}
```

- ✅ 非同期関数内でcatchして**ログやリカバリ**した後、必要に応じて `throw` を使って伝播
- ✅ catch内で完結させず、**責務があるレイヤに伝えることを設計的に決定**

---

## 3. catchブロックのスコープ最小化

```ts
// ❌ 不要に広いtryブロック
try {
  const user = await fetchUser();
  render(user); // ← ここでの例外もcatchされてしまう
} catch (e) {
  showError(); // 原因が不明瞭になる
}
```

```ts
// ✅ エラー発生の責務単位で分離
let user;
try {
  user = await fetchUser();
} catch (e) {
  logError(e);
  return;
}
render(user); // ← 正常系の責務として扱う
```

- ✅ **非同期処理部分のみ**をtryで囲み、**その後の処理は正常系に分離**

---

## 4. 再throw戦略とログ責務の分離

```ts
async function fetchWithRetry(url, maxAttempts = 3) {
  for (let i = 0; i < maxAttempts; i++) {
    try {
      return await fetch(url);
    } catch (err) {
      logger.info(`Attempt ${i + 1} failed`);
      if (i === maxAttempts - 1) throw err;
    }
  }
}
```

- ✅ catchの中で**ロギングやリトライは行うが、最終責任は外へ渡す**
- ✅ 「処理失敗」と「責任終了」を明確に分ける

---

## 5. ユーザー向け vs 開発者向けのエラー処理設計

```ts
async function loadPage() {
  try {
    const data = await fetchData();
    renderUI(data);
  } catch (e) {
    logError(e); // ← 開発者向け
    showErrorMessage('データの取得に失敗しました'); // ← ユーザー向け
  }
}
```

- ✅ 開発者に伝える情報（stack traceなど）と、ユーザーへの通知は**役割を分離**
- ✅ それぞれの責任レイヤで処理を適切に分ける

---

## 設計判断フロー

```text
① このasync関数でcatchすべきか？ → ロギング or 明確な代替がある場合のみ

② catchした後どうする？ → throwして伝播 or fallback処理する

③ try-catchの範囲は適切か？ → 非同期処理ごとに限定的に囲む

④ UI層での失敗はどう扱う？ → UXとデバッグ責務を分離する

⑤ 再throwしているか？ → 必要に応じて必ず責任転送する
```

---

## よくあるミスと対策

### ❌ catchブロック内でエラーの内容を握りつぶして無視

→ ✅ **ログ記録 or 再throw で必ず痕跡を残す設計**

---

### ❌ async関数の中でtry-catchが肥大化し、責務が曖昧に

→ ✅ **tryブロックの粒度を最小化し、例外の発生源を明確に**

---

### ❌ fetchの結果がエラーでも例外が発生しない（res.ok false）

→ ✅ **HTTPステータスは自前で検査し、明示的に throw する**

---

## 結語

非同期エラー制御とは、例外を「握り潰す」のではなく、  
**“非同期処理の失敗を構造化し、責務のある場所へ意図的に伝播させるための設計”**である。

- async関数の中で「何を責任として処理するか」を明確に分離  
- try-catchは構造的に最小粒度で設計し、読みやすさと安全性を両立  
- catchで何をすべきか、何をすべきでないかを明示することで、全体の保守性が向上する

**JavaScriptにおける非同期エラー制御とは、  
“例外の発生と伝播を責任設計として扱うことで、信頼性と透明性を同時に担保する戦略である。”**
JavaScriptにおけるエラーハンドリング設計：try-catch, throw, null許容戦略の最適化

## 概要

エラーハンドリングは「落ちたらcatchすればいい」ではない。  
それは**“予期される失敗をコントロール下に置き、予期されない例外を安全に隔離するための設計戦略”**である。

JavaScriptは例外処理が柔軟な分、**無秩序なtry-catchや雑なnullチェック**が多発し、  
保守性の低いコードになりがちである。

本稿では、**try-catchの責務分離、throw戦略、null/undefined許容の境界設計、エラーオブジェクトの設計**までを含む、構造的なエラーハンドリングの戦略を解説する。

---

## 1. try-catch の最小粒度原則

```ts
// ❌ 粗すぎる例外ハンドリング（原因不明）
try {
  const user = JSON.parse(json);
  const name = user.name.toUpperCase();
  saveToDB(name);
} catch (e) {
  console.error('Failed');
}
```

```ts
// ✅ 粒度を最小化
let user;
try {
  user = JSON.parse(json);
} catch (e) {
  throw new Error('Invalid JSON format');
}
```

- ✅ 例外は「どの処理で失敗したか」が明示されるように
- ✅ **一つのtryブロックには一つの責務**

---

## 2. throw戦略とカスタムエラー設計

```ts
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = 'ValidationError';
  }
}

function validateName(name) {
  if (!name) throw new ValidationError('Name is required');
}
```

- ✅ `throw` は構造化された情報を投げる
- ✅ `Error` クラスの継承により、**型や原因でcatchを分岐可能**

---

## 3. null / undefined の安全設計

```ts
// ❌ 曖昧なnull処理
if (user && user.profile && user.profile.avatar) {
  show(user.profile.avatar);
}
```

```ts
// ✅ オプショナルチェーン
show(user?.profile?.avatar);
```

- ✅ `?` を使うことで**意図的に「なければ無視」**を表現
- ✅ ただし、「なければ失敗すべき」文脈では明示的な `throw` を使う

---

## 4. 関数としての失敗表現（Either風）

```ts
function parseJSON(str) {
  try {
    return { ok: true, value: JSON.parse(str) };
  } catch (e) {
    return { ok: false, error: e };
  }
}
```

```ts
const result = parseJSON(input);
if (result.ok) {
  use(result.value);
} else {
  log(result.error);
}
```

- ✅ 例外を外に出さず、「結果として返す」ことで**呼び出し側に制御権**
- ✅ 副作用の少ないAPI設計に有効

---

## 5. UI/UXにおけるエラー分離（境界設計）

```ts
try {
  const user = await fetchUser();
  render(user);
} catch (e) {
  renderErrorMessage('ユーザーの取得に失敗しました');
}
```

- ✅ UIとロジックの責務を明確に  
- ✅ catchブロックは**ユーザーに示す最小限のUIエラーに限定**

---

## 設計判断フロー

```text
① このエラーは「予期される失敗」か？ → null/undefined or 値で返す

② 「例外」として投げるべきか？ → 開発者のバグ or 実行時異常の場合のみ

③ try-catch の粒度は適切か？ → 単一の責務だけを囲んでいるか

④ catch内でロギング + 再throwが必要か？ → 処理の境界を意識する

⑤ エラーオブジェクトは構造的か？ → name/type/message を設計済か
```

---

## よくあるミスと対策

### ❌ try 内部で複数の処理を抱え、catchでは何が原因か不明

→ ✅ **tryの粒度を責務単位で分割し、catchで明示**

---

### ❌ `throw new Error('X is missing')` をただの文字列で処理

→ ✅ **カスタムErrorクラスで分類と構造化を**

---

### ❌ すべてのnullを例外としてthrowし、UXが壊滅

→ ✅ **nullは"欠けてもよい"設計の場合、静かに無視 or fallbackする**

---

## 結語

エラーハンドリングは「エラーをキャッチする技法」ではない。  
それは**“失敗と異常を制御構造として設計し、責務とUXを守るための安全装置”**である。

- try-catch の粒度を絞り、catch の責務を明確に  
- throw は例外であり、エラーではない  
- null許容と例外制御を文脈ごとに設計し分離する

**JavaScriptにおけるエラーハンドリングとは、  
“失敗の責任と通知の設計を通じて、堅牢性と理解可能性を両立させるための戦略である。”**
JavaScriptでブラウザから通知を出す

## 1. やりたいこと


PCブラウザから通知を出したい


## 2. やり方


Notification APIで通知を出すことができます
https://developer.mozilla.org/ja/docs/Web/API/Notification


### 2-1. 通知許可を取る


ブラウザはユーザーが通知を許可したページのみ通知を出しますので、最初にrequestPermission()を実行して許可を得る必要があります

```javascript:javascript
if ("Notification" in window) {
  Notification.requestPermission().then(permission => {
    if (permission === "granted") {
      console.log("通知の許可が得られました");
    }
  })
}
```


既に許可済みのページの場合はブラウザが覚えていてtrueを返してくれるので、ユーザー自身が毎回許可を求められたりはしませんので、その点は心配要りません


### 2-2. 通知を出す


new Notificationで通知オブジェクトを新たに作ると通知を表示してくれます

許可が得られていないとエラーになるので、Notification.permissionが"granted"になっているときだけ通知を出すのが良さそうです


```javascript:javascript
if (Notification.permission === "granted") {
  new Notification(title, {
    body: until,
    tag: String(tag) + until,
    //icon: "/logo192.png",  // 任意でアイコンを設定できます
    requireInteraction: true,
  });
}
```


### 2-3. 通知を消す


通知するときに作ったNotificationオブジェクトのclose()メソッドを呼ぶと通知を消すことができます


```javascript:javascript
let notification;

// 通知を表示する関数
function showNotification(title, until, tag) {
  if (Notification.permission === "granted") {
    notification = new Notification(title, {
      body: until,
      tag: String(tag) + until,
      requireInteraction: true,  // ユーザーの操作まで通知が残る
    });

    // 任意のタイミングで自動的に通知を閉じる例
    setTimeout(() => {
      closeNotification();
    }, 10000); // 10秒後に通知を閉じる
  }
}

// 通知を閉じる関数
function closeNotification() {
  if (notification) {
    notification.close();
    notification = null; // メモリ管理のためにクリア
  }
}

// 使用例
showNotification("お知らせ", "これは通知の内容です", "通知ID");
```


# まとめ


簡単です
レッツトライ
JavaScriptにおけるユーティリティ関数設計：汎用性と責務のバランス戦略

## 概要

「ユーティリティ関数（utility）」は、よく使う処理を再利用可能にまとめるという発想に基づくが、  
**無差別に再利用可能にすることが目的ではない。**

それは**“汎用性と責務を適切にバランスさせ、ドメインロジックと分離することでアプリケーションの一貫性を支える構造”**である。

本稿では、**ユーティリティ関数の設計原則、ドメイン層との分離基準、命名・引数設計・テスト容易性の観点からの最適化戦略**を解説する。

---

## 1. ユーティリティ関数とは

- ✅ 汎用性が高く、**アプリケーション全体で再利用可能**
- ✅ 状態を持たず、**純粋関数であることが原則**
- ✅ ドメイン（業務）知識に依存しない、**技術的/構文的処理**

```ts
export function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}
```

---

## 2. ドメイン関数との分離

```ts
// ユーティリティ関数（純粋・再利用可）
export function padZero(num, length = 2) {
  return num.toString().padStart(length, '0');
}

// ドメイン関数（ビジネスルールあり）
export function formatInvoiceId(id) {
  return `INV-${padZero(id)}`;
}
```

- ✅ 汎用関数は**ドメイン知識から隔離**
- ✅ ビジネスルールは**アプリ層で閉じる**

---

## 3. 汎用性の設計判断

| 判定基準                     | 内容                                         |
|------------------------------|----------------------------------------------|
| 入力と出力が単純か？         | 引数・戻り値が明確で、**副作用がないか**     |
| 状態や依存に左右されないか？ | 内部で**外部関数やグローバル参照がないか**   |
| ビジネス文脈に依存していないか？ | アプリケーションの**文脈外でも使えるか** |

---

## 4. 命名規則と責務の粒度設計

```ts
// ✅ 良い命名
parseDate()     // パースする
formatCurrency() // 整形する
toSlug()         // 変換する

// ❌ 曖昧な命名
handleStuff()
processThing()
```

- ✅ 動詞 + オブジェクト形式で意図を明確に
- ✅ 責務は1つに → `isEmpty()` と `isBlank()` を同居させない

---

## 5. テスト容易性と構造

```ts
// utils/date.ts
export function getWeekDay(date) {
  return ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][date.getDay()];
}
```

```ts
test('getWeekDay returns correct abbreviation', () => {
  expect(getWeekDay(new Date('2023-05-14'))).toBe('Sun');
});
```

- ✅ グローバル状態に依存せず、**完全にピュアな関数**であること
- ✅ 構文・ユースケースの境界に立つよう設計

---

## 設計判断フロー

```text
① 関数はドメイン知識に依存していないか？ → ユーティリティへ分離可

② 状態や副作用は含まれていないか？ → 純粋関数に限定

③ 再利用性と読みやすさのバランスは取れているか？ → 命名で意図明示

④ 他のモジュールへの依存があるか？ → 依存を排除または注入に切り替える

⑤ 処理の粒度は細かすぎず、適切か？ → 役割ごとに関数を分割 or 集約
```

---

## よくあるミスと対策

### ❌ `utils.js` に全てを詰め込んで1000行以上の肥大化

→ ✅ **機能単位でモジュールを分割（utils/date.ts, utils/math.tsなど）**

---

### ❌ 関数内でDOMやlocalStorageを操作しており純粋性を失っている

→ ✅ **副作用は外部で処理し、ユーティリティ関数は値変換に徹する**

---

### ❌ ドメインロジックを抽象化しすぎて意味が不明瞭に

→ ✅ **「誰が使うのか」「何をするのか」が明確な名前と構造に修正**

---

## 結語

ユーティリティ関数とは、「どこでも使える便利な関数」ではない。  
それは**“汎用性と責務の分離を通して、再利用性と設計一貫性を担保する構造要素”**である。

- ドメイン知識から分離し、純粋性と独立性を保つ  
- 汎用性の名のもとに責務を曖昧にしない  
- テスト容易性と意図の明示が、設計としての完成度を高める

**JavaScriptにおけるユーティリティ設計とは、  
“再利用可能な構文を責任ある形で抽出し、設計の秩序と整合性を維持するための戦略である。”**
フォルダの写真を一括縮小

写真を一括縮小するスクリプト。

これもChatGPT＋ちょっと改造で作りました。
iPhoneでとった１M前後の写真が一気に50K程度に。

便利です！


```resize_image.py
from PIL import Image
import os

input_folder = "./"
output_folder = "./resized"

# 縮小後の最大サイズ（例：800px）
max_size = (800, 800)

# 出力用フォルダがなければ作成
os.makedirs(output_folder, exist_ok=True)

# フォルダ内の画像を処理
for filename in os.listdir(input_folder):
    if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        image_path = os.path.join(input_folder, filename)
        img = Image.open(image_path)
        
        # 画像の縮小（縦横比維持）
        img.thumbnail(max_size)
        
        # 保存
        output_path = os.path.join(output_folder, filename)
        img.save(output_path)

        print(f"{filename} を縮小しました！")

print("すべての画像のサイズ変更が完了しました🎉")

```
JavaScriptにおけるループ構造の最適化戦略：map, reduce, forの選定と設計意図

## 概要

ループ処理は「配列を回す」単純な構文ではない。  
それは**“データ変換・集約・副作用処理の意図を明示し、パフォーマンスと可読性のバランスを取るための設計戦略”**である。

`for` / `forEach` / `map` / `filter` / `reduce` などの構文選択は、  
**処理内容の意図や責務を読み取る「設計言語」としての役割**を持つ。

本稿では、**代表的なループ構文の使い分けと選定基準、設計的に意味のある選択方法、可読性と性能の最適バランス**を解説する。

---

## 1. `for` / `for...of`：最も低レベルなループ構文

```ts
for (let i = 0; i < items.length; i++) {
  process(items[i]);
}
```

```ts
for (const item of items) {
  process(item);
}
```

- ✅ 明確なインデックス制御や途中 break/continue が必要な場合に適切
- ❌ 副作用ベースの処理が多くなりがちで、**処理の意図が読みにくい**

---

## 2. `forEach`: 副作用ループに最適

```ts
items.forEach(item => {
  console.log(item); // 副作用
});
```

- ✅ ループの各要素に**副作用（ログ、描画、DOM更新など）を与える**
- ❌ **return や break が機能しない**ため、制御が限定的

---

## 3. `map`: 値の変換・新しい配列生成に最適

```ts
const names = users.map(user => user.name);
```

- ✅ **入力 → 出力の変換（1対1）** に最も適した構文
- ❌ 副作用や条件分岐には不向き（責務がずれる）

---

## 4. `filter`: 条件に合致する要素の抽出

```ts
const activeUsers = users.filter(user => user.active);
```

- ✅ 元配列から**条件に応じて絞り込む**用途に特化
- ✅ 副作用は避け、**純粋な述語関数を使う**のが原則

---

## 5. `reduce`: 累積処理・集約処理に強い

```ts
const total = prices.reduce((sum, price) => sum + price, 0);
```

- ✅ 数値の合計、グルーピング、オブジェクト集約など
- ❌ 初学者には**読み解きにくい抽象度**があるため、設計意図の明示が重要

---

## 6. 選定基準まとめ

| 処理の目的         | 推奨構文     | 理由                                 |
|--------------------|--------------|--------------------------------------|
| 副作用を発生させたい | `forEach`     | return不要・純粋な副作用向き         |
| 新しい配列が欲しい   | `map`         | 値変換の意図が明確                   |
| 条件で抽出したい     | `filter`      | 条件式での構造的な分離               |
| 合計や集約したい     | `reduce`      | 累積構造を表現できる                 |
| 高速処理が必要       | `for`         | JITに最も近く、低レイヤーで制御可能 |

---

## 設計判断フロー

```text
① 値を返す構文か？ → map / reduce / filter を優先

② 副作用のみ？ → forEach or forを選択

③ 集約 or 累積的処理？ → reduceが最適

④ 途中で break したい？ → for / for...of で制御可能性を取る

⑤ 曖昧な map/filter の混用をしていないか？ → 処理目的を明示化
```

---

## よくあるミスと対策

### ❌ `map` を使っているのに返り値を使っていない（副作用目的）

→ ✅ `forEach` に置き換えて意図を明確にする

---

### ❌ `forEach` で return を期待して break 書いても効かない

→ ✅ **break 可能な `for` へ置き換える**

---

### ❌ `reduce` で何でもやろうとして読みにくいコードに

→ ✅ **必要に応じて map + filter + reduce の分離を検討**

---

## 結語

ループ構文は「データを1件ずつ処理するため」ではない。  
それは**“データ処理の意図と責務を明示し、構文選択で表現するための設計戦略”**である。

- 目的と構造に応じた構文選択が、コード全体の明瞭さを支える  
- ループの中で「何をしているか」ではなく、「なぜその構文を使っているか」が設計の本質  
- 可読性と抽象度のバランスを見極め、責務を分離して設計する

**JavaScriptにおけるループ設計とは、  
“処理の意図と構造を構文として明文化することで、保守と共感性を最大化する戦略である。”**
JavaScriptにおける依存性注入とテスタブル設計：構成と責務の分離

## 概要

テスタブルなコードとは、テストコードを書きやすいコードではなく、  
**“構成可能であり、外部依存に左右されず、責務が明確な設計”**のことである。

その核心にあるのが「**依存性注入（DI: Dependency Injection）**」。  
これは外部依存を直接呼び出すのではなく、**「注入」される形で受け取る**ことで、  
テスト可能性、柔軟性、保守性を飛躍的に高める。

本稿では、JavaScriptにおける **依存性注入の基本と実践的適用方法、設計判断基準、テスタビリティの担保戦略** を解説する。

---

## 1. 依存性注入の基礎概念

```ts
// 依存を内包している（密結合）
function fetchUser() {
  return fetch('/api/user'); // ← 外部依存
}
```

```ts
// 依存を注入（疎結合）
function fetchUser(httpClient) {
  return httpClient('/api/user');
}
```

- ✅ **依存先（fetch）を外部から受け取る**
- ✅ テスト時に **モック関数に差し替え可能**

---

## 2. テスタブル構造の設計例

```ts
function createUserService(httpClient) {
  return {
    getUser: () => httpClient('/api/user'),
    saveUser: (data) => httpClient('/api/user', { method: 'POST', body: JSON.stringify(data) })
  };
}
```

- ✅ サービス構築関数として提供 → **依存注入可能なモジュール化**
- ✅ 責務ごとに構造が分離されているため、**単体テストが容易**

---

## 3. 依存性の種類と注入方式

| 依存対象       | 例                      | 注入方法                     |
|----------------|-------------------------|------------------------------|
| 外部API        | fetch, axios            | 引数 or DIコンテナ           |
| ストレージ     | localStorage, DB        | ラッパー関数の注入           |
| ロガー         | console.log, logger     | ロガーオブジェクトの注入     |
| 設定値         | APIエンドポイントなど   | `config` オブジェクトで注入 |

---

## 4. DIと責務分離のベストプラクティス

```ts
function createApp({ httpClient, logger }) {
  const service = createUserService(httpClient);

  return {
    run() {
      service.getUser().then(user => {
        logger.info('User loaded:', user);
      });
    }
  };
}
```

- ✅ **構築関数に依存を渡す設計**
- ✅ `createApp()` は構成と依存を受け取り、**実行に必要な責務のみを担う**

---

## 5. テスト戦略：モックとの親和性

```ts
test('fetchUser calls correct endpoint', async () => {
  const mockHttp = vi.fn().mockResolvedValue({ name: 'Taro' });
  const service = createUserService(mockHttp);

  const result = await service.getUser();
  expect(result.name).toBe('Taro');
  expect(mockHttp).toHaveBeenCalledWith('/api/user');
});
```

- ✅ 依存が注入されているため、**モックでのテストがシンプル**
- ✅ 振る舞いの確認が**ピュア関数的に行える**

---

## 設計判断フロー

```text
① この関数は外部依存（I/O、ストレージ、設定値）を含んでいるか？

② 依存はハードコードされているか？ → 注入可能に変更

③ テストで依存を差し替えられるか？ → ラッパー or ファクトリ化

④ 複数の責務を抱えていないか？ → ロジックと構成を分離

⑤ DIを受け取る構造（createX）の粒度は適切か？ → 責務単位で整理
```

---

## よくあるミスと対策

### ❌ `fetch()` や `console.log()` を直接埋め込み、差し替え不能に

→ ✅ **依存性は関数やオブジェクトとして注入し、交換可能に**

---

### ❌ クラスに依存を直接埋め込んでテスト困難に

→ ✅ **コンストラクタ引数や create関数で構成時に注入**

---

### ❌ 構成コードとロジックが一体化して再利用性が低下

→ ✅ **createService → useService のように組み立てと使用を分離**

---

## 結語

依存性注入とは、オブジェクト指向のためのパターンではない。  
それは**“コードを構成可能にし、責務と依存の境界を明確に分離するための戦略”**である。

- I/Oやロガーなど環境依存は「注入」して扱う  
- テスト可能性と保守性を上げるための前提として設計に取り入れる  
- 最終的には「構成」と「ロジック」の**明確な二分化**へと繋がる

**JavaScriptにおける依存性注入とは、  
“実行環境と実装責務の境界を設計として明示する技術戦略である。”**
JavaScriptにおける副作用制御：関数の純粋性と副作用の分離戦略

## 概要

副作用（side effect）は、プログラムにおける**見えない変化の根源**である。  
特にJavaScriptのような柔軟な言語では、副作用は**便利さと同時に予測困難な挙動の原因**ともなる。

本稿では、**純粋関数の原則、副作用の識別と分離、制御構造としての活用戦略**に焦点を当てる。  
テスト容易性や拡張性を高める上で、副作用をどのように扱うべきか、その設計視点を明確にする。

---

## 1. 純粋関数 vs 非純粋関数

```ts
// 純粋関数
function add(a, b) {
  return a + b;
}

// 非純粋関数（副作用あり）
function addAndLog(a, b) {
  const result = a + b;
  console.log(result); // ← 副作用
  return result;
}
```

- ✅ **純粋関数は入力に対して出力が常に一定**
- ❌ 非純粋関数は**外部とのやり取りを含み、テストが困難**

---

## 2. よくある副作用の例

| 種類             | 具体例                                       |
|------------------|----------------------------------------------|
| I/O              | `console.log()`, `alert()`, `fetch()` など   |
| DOM操作          | `document.querySelector()`, `appendChild()` |
| 状態変更         | グローバル変数の書き換え                    |
| 時間参照         | `Date.now()`, `setTimeout()` など            |
| ランダム性       | `Math.random()`                             |

---

## 3. 副作用の分離設計

```ts
// ✗ ロジックと副作用が混在
function updateAndRender(data) {
  const transformed = transform(data);
  document.body.innerHTML = render(transformed);
}

// ✓ 分離された構造
function update(data) {
  return transform(data);
}

function applyToDOM(html) {
  document.body.innerHTML = html;
}
```

- ✅ ロジックと出力（副作用）を**明確に切り分ける**
- ✅ 副作用部分は常に**境界として設計し、外側でまとめて扱う**

---

## 4. 副作用制御のためのレイヤー分離

```ts
// pure.ts
export function calculateTax(price) {
  return price * 0.1;
}

// effect.ts
import { calculateTax } from './pure.js';

const tax = calculateTax(1000);
console.log(`Tax is: ${tax}`);
```

- ✅ **ロジックと副作用が別ファイル** → テスト可能・再利用可能
- ✅ 副作用のある処理は最小限の**ゲートウェイとして設計**

---

## 5. フレームワークにおける副作用制御（React例）

```tsx
useEffect(() => {
  document.title = 'Loaded';
}, []);
```

- ✅ Reactでは副作用は `useEffect` に隔離  
- ✅ 「**純粋なレンダリング関数 + 副作用専用の構造**」を徹底している設計思想

---

## 設計判断フロー

```text
① この関数は常に同じ出力を返すか？ → 純粋関数として設計可能

② 外部と通信しているか？ → 副作用として分離・制御

③ テスト可能な構造か？ → 外部依存を渡す or 別モジュールに切り出す

④ UI更新とロジックが混在していないか？ → DOM操作を外に出す

⑤ 時間やランダム性を使っていないか？ → モック・依存注入に切り替える
```

---

## よくあるミスと対策

### ❌ `console.log()` を開発時から本番まで放置

→ ✅ **副作用は環境ごとに制御（ロガーインタフェースの抽象化）**

---

### ❌ DOM操作が関数内にベタ書きされ、再利用不能に

→ ✅ **DOM操作は呼び出し元が責任を持ち、関数は値だけ返す**

---

### ❌ グローバル状態を直接書き換えてテスト不能

→ ✅ **状態は関数の戻り値として受け渡す or ストア経由で制御**

---

## 結語

副作用を完全に排除する必要はない。  
むしろそれを**構造として認識し、制御下に置くことこそが設計の本質**である。

- 純粋関数をベースに、拡張しやすくテスト可能な設計を構築  
- 副作用は「悪」ではなく、「境界」であり、「責務」である  
- アーキテクチャとは、**副作用をどこまで許容するかの戦略選択**でもある

**JavaScriptにおける副作用設計とは、  
“振る舞いと環境との接点を明確にし、予測可能性を守るための設計制御である。”**
JavaScriptにおける状態管理戦略：グローバル vs ローカルの分離設計

## 概要

状態管理（state management）は「どこに変数を置くか？」という表層的な話ではない。  
それは**“責務ごとに状態を分離し、変更の伝播範囲を制御するための構造設計”**である。

JavaScriptにおけるアプリケーション開発では、状態を **ローカルに閉じるか、グローバルで共有するか** の判断が、保守性・可読性・テスト容易性すべてに関わってくる。

本稿では、**状態の分類・責務の設計・スコープの最適化・グローバル/ローカルの切り分け判断基準**を体系的に解説する。

---

## 1. 状態の分類と設計意図

| 種類             | 説明                                               | 例                                      |
|------------------|----------------------------------------------------|-----------------------------------------|
| ローカル状態     | 単一コンポーネント内に閉じる状態                  | フォーム入力値、表示/非表示など        |
| グローバル状態   | 複数箇所からアクセス・共有される必要のある状態    | ログイン情報、言語設定、テーマ設定など |

---

## 2. ローカル状態の構成（局所性と自律性）

```ts
function Component() {
  const [value, setValue] = useState('');
  
  return (
    <input value={value} onChange={e => setValue(e.target.value)} />
  );
}
```

- ✅ コンポーネント内部のみに関係する状態は**ローカルで閉じる**
- ✅ 状態の更新が他に影響を与えないため**可読性と保守性が高い**

---

## 3. グローバル状態の設計（共有と集中管理）

```ts
const globalState = {
  user: null,
  theme: 'dark'
};

function login(user) {
  globalState.user = user;
}
```

- ✅ 状態が**複数箇所で読み書きされる**ならグローバルへ昇格
- ✅ 状態の**集中管理（Store）**が必要になることも多い

---

## 4. 状態分離の原則：アクセス可能性 ≠ 必要性

- ❌ 「どこからでもアクセスできるからグローバルにする」  
→ ✅ **本当に“複数箇所から参照/更新”されているのかを見極める**

---

## 5. グローバル状態の構造設計パターン

```ts
// オブジェクトベースの集中管理
const store = {
  state: {
    user: null,
    token: null
  },
  setUser(user) {
    this.state.user = user;
  },
  reset() {
    this.state = { user: null, token: null };
  }
};
```

- ✅ 直接参照を避け、**アクセサ関数を通すことで変更制御が可能**
- ✅ 状態の責務が明示され、テストもしやすい構造になる

---

## 設計判断フロー

```text
① 状態は UI構成要素のみに関係しているか？ → ローカル状態で閉じる

② 状態は複数コンポーネント間で共有されるか？ → グローバル昇格

③ 状態の変化は、どこまで伝播させる必要があるか？ → 最小スコープで設計

④ グローバル状態の責務が混在していないか？ → ストア構造を分割

⑤ 状態アクセスが読み取り/書き込みの両方必要か？ → setterを分離する
```

---

## よくあるミスと対策

### ❌ 全ての状態をグローバルに定義し、変更が多発

→ ✅ **状態のアクセス範囲と責務を最小に絞る**

---

### ❌ ローカル状態が無秩序に肥大化

→ ✅ **複雑な構造は reducer や composable に分割**

---

### ❌ グローバル状態に直接アクセスしてバグ温床に

→ ✅ **アクセサ・アクション関数を介した構造に統一**

---

## 結語

状態管理とは「値を保存する」ためではない。  
それは**“状態の変化と伝播を構造として制御し、責務と影響範囲を最適化するための設計戦略”**である。

- UIローカルで閉じるべきものは閉じ、汚染を防ぐ  
- グローバル状態は厳密な責任範囲と更新ルールを定める  
- 状態の流れをコードに記述することで、設計が明確になる

**JavaScriptにおける状態管理とは、  
“状態を構造的に位置づけ、再現性と予測性を最大化するための設計技術である。”**
JavaScriptにおける非同期制御構文の統一戦略：Promise, async/await, Generatorの選定基準

## 概要

JavaScriptはシングルスレッドで動作するが、非同期処理の制御は不可欠であり、  
その選択肢として **Promise**, **async/await**, **Generator** の3構文が存在する。

しかし、これらは**単なる文法の違い**ではなく、  
**非同期の抽象度・制御粒度・フロー制御の設計方針**を表現するものだ。

本稿では、各構文の設計的意図と選定基準、統一戦略としてのガイドラインを提示する。

---

## 1. Promise構文：非同期処理の基本形

```ts
fetch('/api/user')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));
```

- ✅ **チェーン構造で非同期フローを設計**
- ✅ 複数ステップの非同期処理を構造化できる

---

## 2. async/await：同期的な見た目で非同期制御

```ts
async function loadUser() {
  try {
    const res = await fetch('/api/user');
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}
```

- ✅ コードの読みやすさが向上（直線的な制御フロー）
- ✅ try/catch による例外ハンドリングが自然

---

## 3. Generator関数：中断可能な非同期フロー構築

```ts
function* process() {
  const val1 = yield fetchData();
  const val2 = yield transformData(val1);
  return yield storeData(val2);
}
```

- ✅ 中間状態を持ちながら**一時停止と再開**が可能
- ✅ Redux-Sagaなどで**複雑な副作用制御**に用いられる

---

## 4. 特性の比較表

| 観点             | Promise             | async/await         | Generator               |
|------------------|----------------------|----------------------|--------------------------|
| 読みやすさ       | △（ネストしがち）     | ◎（同期風）          | ◯（制御構造が複雑）     |
| 例外処理         | `.catch()`            | `try/catch`          | 呼び出し側で制御        |
| 並列処理         | `.all()` で管理        | `await Promise.all()` | 制御が煩雑               |
| 中断と再開       | ❌                    | ❌                    | ✅ `yield` により可能    |
| フレームワーク採用 | 汎用（全て対応）      | 汎用（主流）          | 一部（Redux-Sagaなど）  |

---

## 5. 実装選定の戦略指針

### ✅ async/await を基本構文として採用  
- 非同期の直列処理を**読みやすく、明確な順序で**書ける  
- try/catch による例外処理が直感的

---

### ✅ Promiseは「並列処理」や「即値としての返却」に使う

```ts
await Promise.all([
  fetch('/a'),
  fetch('/b')
]);
```

- ✅ 並列時のフロー制御に優れ、**コレクションベース処理に最適**

---

### ✅ Generatorは「副作用の段階的実行」や「コルーチン設計」に限定

- Redux-Sagaなどで、**状態遷移や非同期副作用制御**に用いる

---

## 設計判断フロー

```text
① 単一の非同期処理か？ → async/await で十分

② 連続した非同期処理か？ → async/await + try/catch で構造化

③ 複数の非同期を同時に？ → Promise.all / Promise.allSettled を併用

④ 非同期状態の段階的制御が必要？ → Generatorの検討

⑤ 外部ライブラリとの親和性（例：Saga, RxJS）は？ → 専用構文へ寄せる
```

---

## よくあるミスと対策

### ❌ async 関数内でエラーを throw したが、catch されない

→ ✅ **try/catch で囲み、await は逐次例外処理すべき**

---

### ❌ Promiseチェーンが深くなり、ネスト地獄に

→ ✅ **async/await で順次処理に展開し直す**

---

### ❌ 非同期処理を forEach で処理してしまう

→ ✅ **for...of + await** を使用（`forEach` は await を待たない）

---

## 結語

非同期構文の選択は「書きやすさ」ではなく、  
**“フローの意味と制御の意図をどれだけ明確に表現できるか”**が判断基準となる。

- async/await をベース構文として採用し、読みやすく保守性の高い制御へ  
- Promise で並列処理を整理し、全体構造を最適化  
- Generator は高度な状態制御が必要な場合に限定して採用

**JavaScriptにおける非同期設計とは、  
“流れと例外を制御構造として設計することで、信頼性のある非同期システムを構築する戦略である。”**
JavaScriptにおけるイベント設計：カスタムイベントと通知機構の抽象化


## 概要

イベント駆動は「クリックを検知する」だけの仕組みではない。  
それは**“状態の変化を検出し、依存関係を分離しながら情報を伝播させるための非同期通知機構”**である。

JavaScriptでは、DOMイベントだけでなく、**カスタムイベント・Pub/Sub（Publish/Subscribe）・イベントバスなどを活用した抽象化された通知設計**が求められる場面が増えている。

本稿では、**イベントの構造設計、DOMイベントとの違い、カスタムイベントの使い方、通知機構の抽象化戦略**を整理して解説する。

---

## 1. DOMイベントの基本

```ts
document.querySelector('#btn')?.addEventListener('click', () => {
  console.log('Clicked');
});
```

- ✅ DOMに直接結びつく「UIに限定されたイベント」
- ✅ バブリング/キャプチャ/イベント委譲 などの概念と強く関係

---

## 2. カスタムイベントの基本構文

```ts
const event = new CustomEvent('user:login', {
  detail: { userId: 42 }
});

document.dispatchEvent(event);
```

```ts
document.addEventListener('user:login', (e) => {
  console.log('Login detected:', e.detail.userId);
});
```

- ✅ `CustomEvent` を用いてアプリケーション内部で意味のあるイベントを定義可能
- ✅ `detail` に**構造化されたデータを付加**できる

---

## 3. イベントによる依存関係の分離

```ts
// producer.js
function login(userId) {
  document.dispatchEvent(new CustomEvent('user:login', { detail: { userId } }));
}

// consumer.js
document.addEventListener('user:login', (e) => {
  updateUI(e.detail.userId);
});
```

- ✅ 発生源（producer）と反応側（consumer）を**直接結合せずに通信可能**
- ✅ **疎結合な構造**が、メンテナンス性と拡張性を向上させる

---

## 4. イベントバス（Event Bus）による抽象化

```ts
const EventBus = new EventTarget();

// 発火
EventBus.dispatchEvent(new CustomEvent('item:added', { detail: { id: 99 } }));

// 監視
EventBus.addEventListener('item:added', (e) => {
  console.log('Item added:', e.detail.id);
});
```

- ✅ グローバルな状態管理とは分離された通知ハブとして機能
- ✅ 状態変化・ユーザー操作・外部イベントなどを統合的に受け渡し可能

---

## 5. Pub/Subパターンの抽象化例

```ts
class PubSub {
  constructor() {
    this.subscribers = {};
  }

  subscribe(topic, callback) {
    if (!this.subscribers[topic]) this.subscribers[topic] = [];
    this.subscribers[topic].push(callback);
  }

  publish(topic, data) {
    (this.subscribers[topic] || []).forEach(cb => cb(data));
  }
}
```

```ts
const bus = new PubSub();

bus.subscribe('notify', (msg) => console.log('Received:', msg));
bus.publish('notify', 'Hello!');
```

- ✅ **シンプルでテスト可能なイベント通知抽象化**
- ✅ 通信の方向を一方向に限定できる → **管理しやすい設計**

---

## 設計判断フロー

```text
① UIイベントと内部通知が混在していないか？ → CustomEventで明確化

② ロジックと反応側が密結合していないか？ → イベント抽象化で分離

③ 状態変化の通知はどこから来ているか？ → EventBus/PubSubで一元化

④ モジュール間通信が直接参照になっていないか？ → イベント経由に切り替える

⑤ コンポーネントの独立性は保たれているか？ → イベントは発火/反応で責務分離
```

---

## よくあるミスと対策

### ❌ カスタムイベントを使わず、関数呼び出しでロジックが依存

→ ✅ **イベント通知で疎結合に設計する**

---

### ❌ UIイベントと内部ロジック通知が混在して読みにくい

→ ✅ **`data-action` によるセレクタと、`user:*` のようなイベント名空間で整理**

---

### ❌ `window` や `document` に直接バインドしすぎてテスト困難

→ ✅ **EventBusや抽象化PubSubクラスを用意して差し替え可能に**

---

## 結語

イベント設計とは「クリックを処理するもの」ではない。  
それは**“状態の変化と責務の連鎖を、構造として分離・通知するための非同期制御構造”**である。

- DOMを超えて通知を構造化する  
- UI層とロジック層を非同期で接続する  
- 発火と反応を明確に分け、責任範囲を定義する

**JavaScriptにおけるイベント設計とは、  
“変化の伝播を構造として抽象化することで、モジュールの独立性を保ち続ける戦略である。”**