OmniAICreator/Qiita-1.07M huggingface dataset:
js memo

### 问题分析及解决方案

当通过子窗口修改父窗口的 DOM 元素（如 `<input>` 和 `<span>`）的值后，父窗口的 JavaScript **同步代码** 可以直接获取到最新值，但若你的代码中存在**缓存引用**或**未正确触发事件**，可能导致获取的值“滞后”。以下是原因和解决方案：

---

### **原因 1：函数依赖缓存的值而非实时读取 DOM**
**问题**：如果在父窗口的函数中**缓存了 DOM 元素的引用或值**，而不是每次实时读取，会导致获取旧值：
```javascript
// ❌ 错误示例：缓存了初始值
let input = document.getElementById("myInput");
let cachedValue = input.value; // 缓存初始值

function getValue() {
  console.log(cachedValue); // 始终是旧值
}
```

**解决**：每次操作时**实时读取 DOM 元素的最新值**：
```javascript
// ✅ 正确示例：每次读取最新值
function getValue() {
  let input = document.getElementById("myInput");
  console.log(input.value); // 实时获取最新值
}
```

---

### **原因 2：未触发 input/change 事件**
**问题**：直接通过 `input.value = "new value"` 修改值**不会触发 `input` 或 `change` 事件**。如果父窗口依赖这些事件更新状态（如某些框架或自定义监听器），会导致状态未同步。

**解决**：在子窗口中修改父窗口的值后，**手动触发事件**：
```javascript
// 子窗口代码
let parentInput = window.opener.document.getElementById("myInput");
parentInput.value = "新值";
parentInput.dispatchEvent(new Event("input", { bubbles: true })); // 触发 input 事件
```

---

### **原因 3：异步操作未正确处理**
**问题**：如果子窗口关闭后父窗口**立即执行同步代码**，浏览器可能尚未完成 DOM 渲染更新（极少数情况）。

**解决**：使用 `setTimeout` 包裹代码，等待一个事件循环：
```javascript
// 父窗口代码
function checkValue() {
  setTimeout(() => {
    let input = document.getElementById("myInput");
    console.log(input.value); // 确保获取最新值
  },
rsyslogでBIG-IPのログを集約してファイル出力する手順（RHEL9）


## はじめに

本記事では、F5 BIG-IP から RHEL9 サーバへ Syslog を転送し、特定のログファイルに保存する手順を解説します。ネットワーク機器やロードバランサからのログを一元的に管理する環境構築に役立ちます。

# 検証環境
| 種別 | IPアドレス | 用途 |
| ---- | ---- | ---- |
| BIG-IP | 172.31.43.247 | syslog送信元 |
| RHEL9 | 172.31.40.7 | syslog受信・保存先 |

※ 本検証では SELinux および firewalld は無効化済みです。

<p align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092281/9c0c7897-11ba-4cf5-85dd-a2fd94fd625d.png" width="60%">
</p>


## 1. BIG-IP 側の設定

### 1.1 remote syslog 設定を追加
まず、BIG-IP の bash シェルに入ります。
```
run /util bash
```

その後、以下の内容を /config/bigip.conf に追記します。
```bash:/config/bigip.conf
sys syslog {
    remote-servers {
        syslog-server1 {
            host 172.31.40.7
            remote-port 514
            local-ip 172.31.43.247
        }
    }
}
```
host：ログの転送先（RHEL9サーバのIPアドレス）
remote-port：syslog の受信ポート（通常 UDP 514）
local-ip：送信元IPを固定（BIG-IPの送信元アドレス）

### 1.2 設定を反映
```
tmsh load sys config
```

## 2. RHEL9 側の設定（rsyslog）
### 2.1 rsyslog の有効化とポート開放
BIG-IP からのログを rsyslog で受信し、特定ファイルに振り分けて保存します。
```
systemctl enable --now rsyslog
```
### 2.2 UDP で syslog を受信する設定
rsyslog はデフォルトでは UDP 受信を無効化しています。
有効化には以下の記述を /etc/rsyslog.conf に追加します。

```bash:/etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
```
### 2.3 BIG-IP からのログを専用ファイルに保存する設定
以下の設定を /etc/rsyslog.d/bigip.conf に記述します。
```bash:/etc/rsyslog.d/bigip.conf
if ($fromhost-ip == '172.31.43.247') then /var/log/bigip.log
& stop
```
if ($fromhost-ip == ...)：送信元IPによるフィルタリング
& stop：以降のルールへの処理を停止し、ログの混在を防止

### 2.4 rsyslog 再起動
```
systemctl restart rsyslog
```

## 3. 動作確認
### 3.1 BIG-IP 側からテストログを送信
```
logger -p local0.info "Test log from BIG-IP"
```

### 3.2 RHEL9 側でログを確認
```
tail -f /var/log/bigip.log
```
Test log from BIG-IP というメッセージが確認できれば、syslog 転送と保存は正常に機能しています。

## おわりに

BIG-IP からの syslog を Linux サーバで受け取り、用途ごとにログファイルを分離して管理することで、監視やトラブルシュートが格段にしやすくなります。
本記事の構成は、他のネットワーク機器（Fortigate、Cisco など）にも応用可能です。
[Python] 全角文字を半角文字へ変換する

# コード

```python
import functools
import re

def bytesToInt(b):
  return int(b.hex(), 16)

def intToBytes(i):
  return bytes.fromhex(f"{i:x}")

def getDiff(c1, c2):
  e1 = c1.encode()
  e2 = c2.encode()
  return bytesToInt(e1) - bytesToInt(e2)

def exchange(match, diff):
  r = bytesToInt(match[0].encode()) - diff
  return intToBytes(r).decode()

exchange1 = functools.partial(exchange, diff=0xEFBC60)
exchange2 = functools.partial(exchange, diff=0xEFBD20)

def wideStringToHalfString(c):
  pat1 = re.compile("[！-／０-９：-＠Ａ-Ｚ［-＿]")
  pat2 = re.compile("[ａ-ｚ｀｛-～]")
  t = pat1.sub(exchange1, c)
  return pat2.sub(exchange2, t)

if __name__ == "__main__":
  data = [
    "！＂＃＄％＆＇（）＊＋，－．／",
    "０１２３４５６７８９",
    "：；＜＝＞？＠",
    "ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ",
    "［＼］＾＿",
    "ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏｐｑｒｓｔｕｖｗｘｙｚ",
    "｀｛｜｝～",
  ]

  print(f"{getDiff('！', '!'):X}")
  print(f"{getDiff('０', '0'):X}")
  print(f"{getDiff('：', ':'):X}")
  print(f"{getDiff('Ａ', 'A'):X}")
  print(f"{getDiff('［', '['):X}")
  print(f"{getDiff('＿', '_'):X}")
  print(f"{getDiff('ａ', 'a'):X}")
  print(f"{getDiff('｀', '`'):X}")  # 並びがおかしい?
  print(f"{getDiff('｛', '{'):X}")

  print("".join(data))
  r = wideStringToHalfString("".join(data))
  print(r)
```
放物線を二次ベジェ曲線で表してみよう。【python】【SVG pathタグ Qコマンド】

# はじめに
理系教科の指導にあたってしばしば問題の作図が必要とされます。
私はよくsvgファイルを手打ちして作図するのですが、pathタグ内で放物線を描画するコマンドはありません。
そこで、二次ベジェ曲線コマンド```Q```を用いることで解決しようと思います。
描画したい放物線の始点と終点と頂点の情報から、その放物線を二次ベジェ曲線で表したときの制御点を求め、その放物線の描画コマンドを出力するプログラムをpythonで作成します。

# 軽い説明
## 二次ベジェ曲線について軽い説明
二次ベジェ曲線は
座標平面上の3点(始点$P_0$, 制御点$P_1$, 終点$P_2$)を用いた
```math
\vec{B}(t) = (1 - t)^2 \vec{P}_0 + 2(1 - t)t \vec{P}_1 + t^2 \vec{P}_2
```
の式で表されます( $t$ は $0 \leqq t \leqq 1$を満たす媒介変数)。
$N+1$個の制御点をもつベジェ曲線を$N$次曲線といいます。ベクターグラフィックなどでしばしば用いられます。

## 放物線(二次関数)について軽い説明
放物線(二次関数)は一般形$y=ax^2+bx+c$、標準形$y=a(x-p)^2+q$などで表される図形です。標準形は比例定数$a$によって放物線の凸の方向やその緩やかさが読み取れるほか、頂点が$(p, q)$で表せるので非常に便利です。

## SVG(XML)での```Q```コマンドの仕様
```Q```コマンドは二次ベジェ曲線を描画します。現在の座標から
```
(M <始点のx座標> <始点のy座標>) Q <制御点のx座標> <制御点のy座標> <終点のx座標> <終点のy座標>
```
で描画できます。y軸は下方向が正となります。

# 本題
始点と終点および頂点から、制御点を求め、目標の放物線のコマンドを出力するプログラムを作ってみます。始点と終点および頂点のx座標のみ(=軸)を指定します。

``` python: 放物線の出力.py
def InputPos(PosName):
    RtnList = []
    while len(RtnList) != 2:
        RtnList = list(map(float, input(PosName + "の座標を空白区切りで指定：").split()))
        if len(RtnList) != 2: print("正しく入力してください。")
    return RtnList
P_0 = InputPos("始点")
P_2 = InputPos("終点")
p = float(input("頂点のx座標(=軸)を指定："))

if P_0[0] == p and P_2[0] == p: print("指定した3点が同じ点です。")
else:
    a: float
    q: float
    if P_0[1] == P_2[1]:
        q = float(input("頂点のy座標を指定："))
        a = (P_0[1] - q) / ((P_0[0] - p) ** 2)
    else:
        a = (P_0[1] - P_2[1]) / ((P_0[0] - P_2[0]) * (P_0[0] + P_2[0] - 2 * p))
        q = P_0[1] - a * ((P_0[0] - p) ** 2)
    Peak = [p, q]
    sign = (a * (P_0[0] - Peak[0]) * (P_2[0] - Peak[0])) / abs(a * (P_0[0] - Peak[0]) * (P_2[0] - Peak[0])) if P_0[0] != Peak[0] else 1
    P_1 = [0.5 * (P_0[0] + P_2[0]), sign * ((P_0[1] - Peak[1]) * (P_2[1] - Peak[1])) ** 0.5 + Peak[1]]
    print("\n-----目標のQコマンド-----")
    print(f"M {P_0[0]} {P_0[1]} Q {P_1[0]} {P_1[1]} {P_2[0]} {P_2[1]}")
    print("-------------------------")
```
こんな感じでいいのではないでしょうか。

一応説明を付しておきます。
まず最初に$y=a(x-p)^2+q$式における$a$と$q$を求めています。
始点$P_0(x_0, y_0)$および終点$P_2(x_2, y_2)$として、
```math
a =\frac{y_0 + y_2}{(x_0 - x_2)(x_0 + x_2 - 2p)}
```
```math
q = y_0 - a(x_0 - p)^2
```
です。$a$については2式 $y_0=a(x_0-p)^2+q$ および $y_2=a(x_2-p)^2+q$ を連立させて解くと導かれ、後式は$y_0=a(x_0-p)^2+q$を$q$について解くと導かれます。

この$q$を使って、制御点$P_1$は
```math
P_1\left( \frac{x_0 + x_2}{2},\ \pm\sqrt{(y_0 - q)(y_2 - q)} + q \right)
```
と表されます。
ここでy座標の1つ目の項の符号については、
①aの符号
②放物線の軸が始点と終点のx座標の間に入っているか
によって変化します。

# さいごに
いい感じですね。二次関数が一般形で表されている場合は、さらに頂点を求めるプログラムもあればいいかと思います。
それでは、みなさんも良き放物線ライフを送りましょう🌈🌈
【RethinkDB】夢の次世代データベースRethinkDB、2度目の終焉を迎えていた

JSONをリアルタイムに高速処理できるドキュメント指向データベース[RethinkDB](https://rethinkdb.com/)ですが、会社はうまくいかずに[2016年10月に解散](https://rethinkdb.com/blog/rethinkdb-shutdown/)しました。

# RethinkDBってなに？

高速なレスポンスにリアルタイムPUSHといった高性能、自動スケーリングに自動フェールオーバーといった高可用性を持ち、スマホアプリなどのリアルタイムWebアプリケーションに極めて親和性の高い高性能なデータベースです。


# RethinkDBはなぜ失敗したのか

こうなるまでの経緯については[RethinkDBはなぜ失敗したのか](https://gist.github.com/ramalho/93b87e961b6e019be8e1f6f82864b6f9) ( [日本語訳](https://yakst.com/ja/posts/4416) )がたいへん面白いので読んでみるとよいでしょう。
データが厳格で正しいことを保証し、インターフェイスがシンプルで、使い勝手に一貫性がある高性能なデータベースが、つぎはぎだらけでデータがすぐ消えたりする醜いコード群であるMongoDBになぜ負けたのかを明確に説明する名文です。

一言で言うと、「拙速は巧遅に勝る」です。
実際は孫子はそんなこと言ってないらしいですが、まあでもITの世界では真理のひとつではありますね。

さてこの後、RethinkDBは[Apacheに身売り](https://www.publickey1.jp/blog/17/rethinkdblinux_foundationapache.html)され、[オープンソースとして出直す](https://www.publickey1.jp/blog/17/nosqlrethinkdbrethinkdb_236.html)こととなりました。
それが2017年のことです。
2017/07/23にはコミュニティ主導の[初めてのリリースバージョン](https://rethinkdb.com/blog/2.3.6-release/)が[公開](https://github.com/rethinkdb/rethinkdb/releases/tag/v2.3.6)されました。

最初のビジネスが失敗するなど紆余曲折はあったものの、OSSとして生まれ変わり新たな人生を踏み出すかに見えました。


# リリース

その後のリリースはこんなかんじです。

・2019/12/20 [v2.4](https://github.com/rethinkdb/rethinkdb/releases/tag/v2.4)
・2020/08/15 [v2.4.1](https://github.com/rethinkdb/rethinkdb/releases/tag/v2.4.1)
・2022/05/08 [v2.4.2](https://github.com/rethinkdb/rethinkdb/releases/tag/v2.4.2)
・2023/02/05 [v2.4.3](https://github.com/rethinkdb/rethinkdb/releases/tag/v2.4.3)
・2023/12/11 [v2.4.4](https://github.com/rethinkdb/rethinkdb/releases/tag/v2.4.4)

2025年まででわずか6バージョンです。
そもそも2番目のバージョンまで2年以上かかってしまっているので、その間にすっかり忘れ去られた感がありますね。


# Contribute

では[Contribute](https://github.com/rethinkdb/rethinkdb/graphs/contributors)はどうでしょうか。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/9434da8f-937c-432d-8a7e-3d4d37923cd2.png)

OSS化する前からcommit数は激減しており、OSS化したことによる影響は全く目に見えません。

OSS化以降もcontributeしていたのは、元からのRethinkDB開発者[Sam Hughes](https://github.com/srh)ほぼ一人だけでした。
そしてそのSam Hughesも、2024年には[Cube](https://github.com/cube-js/cube)に興味が移ってしまったらしくそちらにかかりきりになり、RethinkDBへのContributeは完全に途絶えることとなりました。

最後のCommitは2023/12/16です。
1年以上動きがないということであり、今後も再起の見込みはほとんどないでしょう。

闇雲にOSS化してもうまくいかないという好例ですね。

はて、そういえばマネタイズに失敗したのでOSS化して蘇るぞって[最近全く同じ話を聞いた](https://qiita.com/rana_kualu/items/4edee5104315df75f988)気がするような？
【Excel VBAベーシック】マクロVBAに関する用語

## 用語の定義
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/e6c8adff-dad9-4a1b-86b8-2b804812d2af.png)

　**マクロ**は、VBAで書かれたコード（またはコードを実行する機能）のこと。試験では「**指示書**」「**命令書**」などと表現されることもある。マクロは、Excelのデータやグラフなどと**同じブックに保存**される。一方でマクロ記録とは、Excelで行った**操作を記録する機能**である。
 ※マクロは必ずしもVBAで記述されるわけではない。例えばVBAのShell関数を使用して、Pythonスクリプトを実行出来る。

　**VBA**は、プログラミング言語の1つで、「Visual Basic for Applications」（ビジュアル・ベーシック・フォー・アプリケーションズ）の略。一方、**VBE**とはマクロを書いたり実行したりするためのアプリケーションのことで、Excelとは別画面で表示される。「Visual Basic Editor」（ビジュアル・ベーシック・エディター）の略。Excelが起動している状態でショートカットキー**Alt + F11**を押せばVBEを起動出来る。VBEを単独で起動することは出来ない。

 ## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
この1冊で合格! 永井雅明のExcel VBA ベーシック テキスト&問題集 単行本 – 2025/2/26
永井 雅明 (著)
p.19
アセンブリ言語に於けるポインタ及び配列の取り扱いの差異を比較　第1回

今回は以下のC言語プログラムをアセンブリ言語に変換し参照の違いを見ていきます。
※標準関数を使用していない為、.hファイルは一切読み込んでおりません。

```compare.c
void compare() {
    int arr[3] = {10, 20, 30};
    int *ptr = arr;

    arr[0] = 100;     // 配列
    ptr[1] = 200;     // ポインタ
    *(ptr + 2) = 300; // ポインタ
}
```

cmd上にて以下の命令を実行しアセンブリ言語へと変換します。
```
gcc -S compare.c -masm=intel -o compare.asm
```

得られたコードは以下の通りです。(適宜注釈を施しております)
```compare.asm
.file	"compare.c"
	.intel_syntax noprefix
	.text
	.globl	compare
	.def	compare;	.scl	2;	.type	32;	.endef
	.seh_proc	compare

; 関数入口
compare:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue

	; 数列の初期化　arr[3] = {10, 20, 30}
	mov	DWORD PTR -20[rbp], 10
	mov	DWORD PTR -16[rbp], 20
	mov	DWORD PTR -12[rbp], 30

	; ポインタの初期化 ptr = arr
	lea	rax, -20[rbp]
	mov	QWORD PTR -8[rbp], rax

	; arr[0] = 100
	mov	DWORD PTR -20[rbp], 100

	; ptr[1] = 200
	mov	rax, QWORD PTR -8[rbp]
	add	rax, 4
	mov	DWORD PTR [rax], 200

	; *(ptr + 2) = 300
	mov	rax, QWORD PTR -8[rbp]
	add	rax, 8
	mov	DWORD PTR [rax], 300

	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
	.ident	"GCC: (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders, r3) 14.2.0"
```


**各変数のメモリ分布**
| 変数 | メモリ上の場所 |
| ------- | ------- | 
| ptr  | [rbp - 8] (8バイト)| 
| arr[2] | [rbp - 12] (4バイト)| 
| arr[1] |[rbp – 16] (4バイト)| 
| arr[0] |[rbp – 20] (4バイト)| 

※intを４バイトとした場合。

**arr[0] = 100;**
```
mov	DWORD PTR -20[rbp], 100
```
配列を使用した場合は直接メモリ上の場所を指定して値を入れている。

**ptr[1] = 200;**
```
mov	rax, QWORD PTR -8[rbp]
add	rax, 4
mov	DWORD PTR [rax], 200
```
ポインタを使用した場合はptr変数の値を読み込んでからptr[1]の値を変更している。

***(ptr + 2) = 300;**
```
mov	rax, QWORD PTR -8[rbp]
add	rax, 8
mov	DWORD PTR [rax], 300
```
ptr[1] = 200;と同様。
*(ptr + 2)とptr[2]は書き方が違うだけで同義である。
arr[0]とptr[1]は書き方は似ているが、配列とポインタで異なりアセンブリ言語上での処理も異なっている。

**発見**
以下のコードを見てなぜint *ptrで宣言したポインタ変数の大きさが4バイトではなく8バイトになっているのか不思議に思いましたが、ポインタ変数はその型に拘らず32ビットの場合は4バイト、64ビットの場合は8ビット固定の用です。
ポインタ変数は値そのものではなくアドレスを入れる変数なので考えてみれば当たり前なのですが、今更気づきました。
```
mov	QWORD PTR -8[rbp], rax
```
sizeof()を使用して確かめて見ましたが結果は全て8バイトとなりました。
```
    int *ptr_int;
    char *ptr_char;
    double *ptr_double;
    printf("Size of int*: %zu bytes\n", sizeof(ptr_int));
    printf("Size of char*: %zu bytes\n", sizeof(ptr_char));
    printf("Size of double*: %zu bytes\n", sizeof(ptr_double));
```

**筆者の環境**
windows10　Version 10.0.19045.5608
gcc version 14.2.0 (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders, r3)

**後書**
初日投稿です。
良く分からないままに投稿したので改善点があればご指摘頂けると助かります。
WSLgでウインドウの日本語が化けるときの対処

# WSLgで表示したウインドウの日本語が化けることがある
WSLgでは、Ｘクライアントを起動するとウインドウの日本語が化ける。
pythonのtkinterで日本語を表示してみるとこんな感じ・・・

![Pic01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529369/8235e3d7-6d96-42ca-aab6-95f39fd0da75.jpeg)

本当はこんな感じで表示される

![Pic02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529369/5a0f925c-7d8e-47a5-8b58-76899367b22d.jpeg)

# 上の画像のように日本語が表示されない場合
管理者権限で下記コマンドを実行してフォントをインストールする

```
apt install fonts-noto-cjk
```

その後、コマンドプロンプト等でUbuntuをシャットダウン
```
wsl --shutdown
```

これで表示されるようになる。
MCreator/モブ

#前の記事:https://qiita.com/yt365/items/614e4e987d3074bcb612
今回はMCreatorで敵モブを作っていきます。
## この記事で分かること
・MCreatorでのモブの作り方
## モブのテクスチャ
nova skinというサイトからモブのテクスチャをダウンロードします。
![スクリーンショット 2025-04-07 195253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/fae4cb8c-00b4-412b-8b8a-47128d31ae26.png)

URL
 nova skin:https://minecraft.novaskin.me/gallery
 使ったスキン：https://minecraft.novaskin.me/post/5288179656032256/cod-mw2
 MCreatorを開いてリリースを開き、テクスチャをインポート→エンティティのテクスチャを選びます。![スクリーンショット 2025-04-07 184831.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/1c7963b1-3a39-44b6-8a80-657bcaada7a8.png)
 ダウンロードしたスキンを選択してMCreatorに入れます。
 ## モブの作成
 ＋ボタンを押してモブを選びます。![スクリーンショット 2025-04-07 185104.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/1f465b47-cca2-44b9-b62d-7cc058ec9d62.png)
名前を選択して作成します。
![2025-04-07_18h56_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/2f413a9b-6fee-449c-9fc0-04593a71e6b3.png)
上の写真を参考に設定していきます。
![2025-04-07_19h27_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/cd37935a-27c7-4839-9094-cd98bf15eadd.png)
攻撃力や防御力を設定していきます。
写真には写りませんでしたが、下に耐性などもあります。
AIとゴールを選び、戦闘タスクからエンティティを攻撃を取ってきてPlayerに設定します。
![2025-04-07_19h37_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/8b38d259-bcf7-473a-9e94-cf9d4d8bda56.png)
保存を押してください。
## 試してみる
右上の再生ボタンを押して追加したモブがいるか確かめてみます。![2025-04-07_19h55_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054637/9ce60fed-fe26-4299-baca-ee082291aade.png)
## 終わりに
これでいろいろなモブを追加することができます。
ボスを追加したり、味方モブも作ることができると思います！
次の記事:https://qiita.com/yt365/items/199eb29022348f479db0
Pythonで実装するCommandパターン：操作をオブジェクト化して履歴と再実行を設計する


## 概要

**Command（コマンド）パターン**は、  
操作（命令）をオブジェクトとして抽象化し、**呼び出し元と処理内容の結合を分離**する構造的パターンである。

これにより、**操作のキューイング・履歴管理・Undo/Redo・遅延実行などが柔軟に実現可能**になる。

---

## 1. なぜCommandパターンが必要か？

### ❌ 処理ロジックを直接呼び出す密結合な実装

```python
button.onclick = save_file
```

→ イベント処理や履歴管理、テストが困難で**拡張性が乏しい**

---

### ✅ 操作自体をオブジェクト化し、抽象的に扱う

```python
button.set_command(SaveCommand(file))
```

→ **操作の呼び出しと実行を切り離し、柔軟な設計が可能に**

---

## 2. 基本構造

### ✅ Commandインターフェース

```python
class Command:
    def execute(self):
        raise NotImplementedError
```

---

### ✅ 具体的なコマンドクラス

```python
class SaveCommand(Command):
    def __init__(self, receiver):
        self.receiver = receiver

    def execute(self):
        self.receiver.save()
```

---

### ✅ 受信側（Receiver）

```python
class File:
    def save(self):
        print("ファイルを保存しました。")
```

---

### ✅ Invoker（呼び出し元）

```python
class Button:
    def __init__(self):
        self._command = None

    def set_command(self, command):
        self._command = command

    def click(self):
        if self._command:
            self._command.execute()
```

---

### ✅ 使用例

```python
file = File()
save_cmd = SaveCommand(file)

button = Button()
button.set_command(save_cmd)
button.click()
# → ファイルを保存しました。
```

---

## 3. Python的応用：Undo/Redo対応Commandの設計

```python
class TextEditor:
    def __init__(self):
        self.content = ""

    def write(self, text):
        self.content += text

    def undo(self, text):
        self.content = self.content[:-len(text)]
```

```python
class WriteCommand(Command):
    def __init__(self, editor, text):
        self.editor = editor
        self.text = text

    def execute(self):
        self.editor.write(self.text)

    def undo(self):
        self.editor.undo(self.text)
```

```python
editor = TextEditor()
history = []

cmd = WriteCommand(editor, "Hello ")
cmd.execute()
history.append(cmd)

cmd2 = WriteCommand(editor, "World!")
cmd2.execute()
history.append(cmd2)

print(editor.content)  # Hello World!

# Undo last command
history.pop().undo()
print(editor.content)  # Hello 
```

---

## 4. 実務ユースケース

### ✅ UI操作イベントの抽象化

→ ボタンやキーボード操作のイベントを**操作オブジェクトとして扱う**

---

### ✅ 履歴管理・Undo/Redo処理

→ 操作の逆再生を可能にすることで、**ユーザー体験を向上**

---

### ✅ マクロ記録・再実行機能

→ 一連の操作を記録し、**自動再生可能に**

---

### ✅ メッセージキューや非同期処理の設計

→ 遅延実行やリトライ可能な**コマンドベースの非同期設計**

---

## 5. よくある誤用と対策

### ❌ Commandがただの関数呼び出しラッパーになっている

→ ✅ `execute()` に**意味ある操作・引数・受信者を含める**

---

### ❌ Invokerにロジックが集中してしまう

→ ✅ Invokerは**コマンドの登録・実行に専念**し、処理内容には立ち入らない

---

### ❌ Undo処理がCommandの責務外にある

→ ✅ `undo()` をCommandに持たせ、**処理と巻き戻しを対で設計**

---

## 結語

**Commandパターンとは、“操作そのものをオブジェクト化することで、制御と履歴を手中に収める構造技法”である。**

- 処理を呼び出すだけでなく、**記録・再生・巻き戻し・遅延実行までを設計可能に**  
- イベント処理やユーザー操作の抽象化を通じて、**拡張性とテスト性の高いアーキテクチャを実現**  
- Pythonでは第一級関数・動的バインディングを活用して、**直感的かつ柔軟にCommandパターンを導入できる**

**Pythonicとは、“操作をデータとして捉え、再利用と構成を可能にする”ことであり、  
Commandパターンはその制御の芸術性を、コードに吹き込むためのデザイン手法である。**
Pythonで実装するStateパターン：状態遷移を明示化する設計手法



## 概要

**State（ステート）パターン**は、  
オブジェクトの内部状態が変化したときに、**振る舞い（メソッドの実装）も変化するような構造を実現するためのパターン**である。

これにより、**状態ごとのロジックを明示的にクラスに分離**し、  
条件分岐のない柔らかな状態遷移を構築できる。

---

## 1. なぜStateパターンが必要か？

### ❌ 巨大なif-else構文による状態管理

```python
def handle(state):
    if state == "idle":
        ...
    elif state == "running":
        ...
```

→ 状態が増えるたびに分岐が肥大化し、**保守性が崩壊**

---

### ✅ 状態ごとにクラスを分け、動的に状態を切り替える

```python
context.set_state(RunningState())
context.request()  # 状態ごとの挙動
```

→ **状態ロジックの局所化・追加・切り替えが柔軟に**

---

## 2. 基本構造

### ✅ Stateインターフェース

```python
class State:
    def handle(self, context):
        raise NotImplementedError
```

---

### ✅ 具体的な状態クラス

```python
class IdleState(State):
    def handle(self, context):
        print("現在: 待機中 → 実行状態へ遷移")
        context.set_state(RunningState())

class RunningState(State):
    def handle(self, context):
        print("現在: 実行中 → 待機状態へ遷移")
        context.set_state(IdleState())
```

---

### ✅ Context（状態を持つ本体）

```python
class Context:
    def __init__(self, state: State):
        self._state = state

    def set_state(self, state: State):
        self._state = state

    def request(self):
        self._state.handle(self)
```

---

### ✅ 使用例

```python
ctx = Context(IdleState())
ctx.request()  # 待機中 → 実行中
ctx.request()  # 実行中 → 待機中
```

---

## 3. Python的応用：状態を辞書でマップして柔軟に遷移

```python
class TrafficLight:
    def __init__(self):
        self._state = "red"
        self._transitions = {
            "red": self._to_green,
            "green": self._to_yellow,
            "yellow": self._to_red
        }

    def change(self):
        self._transitions[self._state]()

    def _to_green(self):
        print("赤 → 緑")
        self._state = "green"

    def _to_yellow(self):
        print("緑 → 黄")
        self._state = "yellow"

    def _to_red(self):
        print("黄 → 赤")
        self._state = "red"
```

```python
light = TrafficLight()
light.change()
light.change()
light.change()
```

→ **小規模状態機械に対する関数ベース実装も可能**

---

## 4. 実務ユースケース

### ✅ UIやフロントエンドの状態制御

→ 編集・保存・読み取りなどのモード切替を**状態として管理**

---

### ✅ ゲーム開発におけるエンティティの状態遷移

→ 立ち・攻撃・被弾・死亡などの**状態ごとの振る舞いを定義**

---

### ✅ ワークフロー・フェーズ進行管理

→ 承認フローやプロセスの状態に応じた**処理の切り替え**

---

### ✅ IoT制御・ロボティクスの状態機械

→ 状態が明確に定義される物理デバイスの**制御ロジック構築**

---

## 5. よくある誤用と対策

### ❌ 状態クラスに過剰な責務を持たせる

→ ✅ 状態クラスは**状態の振る舞いのみに責任を持たせる**

---

### ❌ 状態の変更を外部から自由に行う

→ ✅ `context.set_state()` は**明示的に制御された経路のみ許可**

---

### ❌ Contextクラスが状態を意識しすぎている

→ ✅ `request()` のみ呼び出せばよい設計にし、**状態ごとの詳細は隠蔽**

---

## 結語

**Stateパターンとは、“状態ごとに振る舞いを封じ込め、システムの秩序と柔軟性を保つ設計技法”である。**

- 状態をクラスに昇格させることで、**条件分岐からの解放と構造化を両立**  
- 状態の追加・変更を局所的に完結させ、**可読性・保守性を最大化**  
- Pythonではクラス/辞書/関数ベースいずれのアプローチも取り得るため、**規模と柔軟性に応じた選択が可能**

**Pythonicとは、“状態の変化を、条件ではなく構造で表現する”ことであり、  
Stateパターンはその変化の秩序を、柔らかく、かつ強靭にコードへ刻むための知的構造である。**
PythonにおけるProxyパターン：アクセス制御と遅延ロードをスマートに設計する


## 概要

**Proxy（プロキシ）パターン**は、  
あるオブジェクトへのアクセスを制御するための**「代理人」オブジェクト**を設け、  
**本体の機能に対して、前処理・後処理・キャッシュ・ロギング・遅延実行などを挿入できる設計パターン**である。

「アクセスされる側の責任」を変更することなく、  
**周囲の制御ロジックを安全かつ明快に構築可能**な点が最大の特長。

---

## 1. なぜProxyが必要か？

### ❌ 本体オブジェクトが過剰に露出している

```python
db = RealDatabase()
db.query("SELECT * FROM users")
```

→ **セキュリティ・キャッシュ・ログなどの関心事が未考慮**

---

### ✅ アクセス経路にProxyを設置し、制御ロジックを挿入

```python
db = DatabaseProxy()
db.query("SELECT * FROM users")  # → ログ/キャッシュ/認証の処理を追加
```

→ **本体はそのままに、安全で拡張可能な制御が実現可能**

---

## 2. 基本構造

### ✅ Subject（インターフェース）

```python
class Database:
    def query(self, sql: str):
        raise NotImplementedError
```

---

### ✅ RealSubject（実体）

```python
class RealDatabase(Database):
    def query(self, sql: str):
        print(f"Executing SQL: {sql}")
```

---

### ✅ Proxy（代理人）

```python
class DatabaseProxy(Database):
    def __init__(self):
        self._real = RealDatabase()
        self._log = []

    def query(self, sql: str):
        print(f"[LOG] Query received: {sql}")
        self._log.append(sql)
        return self._real.query(sql)
```

---

### ✅ 使用例

```python
db = DatabaseProxy()
db.query("SELECT * FROM users")
# → [LOG] Query received: SELECT * FROM users
# → Executing SQL: SELECT * FROM users
```

---

## 3. Python的応用：遅延初期化（Virtual Proxy）

```python
class LazyLoader:
    def __init__(self):
        self._real = None

    def operation(self):
        if self._real is None:
            print("Loading RealObject...")
            self._real = RealObject()
        self._real.operation()
```

```python
class RealObject:
    def operation(self):
        print("Performing operation.")
```

```python
obj = LazyLoader()
obj.operation()  # → Loading RealObject... → Performing operation.
obj.operation()  # → Performing operation.
```

→ **重いオブジェクトの初期化を必要時に限定できる**

---

## 4. 実務ユースケース

### ✅ DBアクセスのラップ

→ 認証・ロギング・スロットリング・再試行処理などを追加可能

---

### ✅ ファイルや画像の遅延ロード（Virtual Proxy）

→ ファイルのメタ情報だけを表示、本体はアクセス時に読み込み

---

### ✅ アクセス制御（Protection Proxy）

→ ユーザーのロールに応じた操作の許可/拒否を仲介クラスで制御

---

### ✅ API呼び出しに対するレート制限やキャッシュ（Smart Proxy）

→ 複数の関心事（セキュリティ・パフォーマンス）を集約的に制御

---

## 5. よくある誤用と対策

### ❌ Proxyが本体の全機能をミラーしてしまう

→ ✅ **共通インターフェースを継承して最低限のラップにとどめる**

---

### ❌ Proxy自身がロジックを持ちすぎる

→ ✅ Proxyは**中継と制御の役割**に集中し、実処理は本体へ委譲

---

### ❌ ProxyとDecoratorの混同

→ ✅ Proxyは**本体の代替としてふるまう**、Decoratorは**機能拡張**

---

## 結語

**Proxyパターンとは、“本体を守りながら振る舞いを注入する、安全かつ柔軟な設計手法”である。**

- 実オブジェクトへのアクセスを**仲介することで、制御構造を一元化**  
- 遅延初期化・キャッシュ・ログ・制限・保護などの**横断的関心事を設計的に吸収**  
- Pythonでは、クラス継承や動的バインディングにより、**柔らかく直感的に実装可能**

**Pythonicとは、“見た目は変わらず、裏側で制御を整える”設計哲学であり、  
Proxyパターンはその知性を備えた透明な防壁として、コードに安心と拡張性をもたらす。**
【用語解説】エンドツーエンドとポイントツーポイントの違い。

### ずばり・・・

**エンドツーエンド**
・通信の両端（送信元と最終目的地）の間での完全な経路を指す。
・システム全体を通した通信や処理を意味する。
・中間のデバイスやノードを経由しても最終的な送信元から宛先までの全体的な接続を重視する。

例：ユーザーのブラウザからウェブサーバーまでの完全な通信経路。

**ポイントツーポイント**
・２つの特定のノード間の直接的な接続を指す。
・ネットワーク内の隣接したデバイス間の単一リンクを意味する。
・中間装置を介さない直接的な接続に焦点を当てています。

例：コンピューター同士の直接接続、ルーターとルーターとか。
Pythonで実装するVisitorパターン：構造と振る舞いを分離して保守性を高める設計


## 概要

**Visitor（ビジター）パターン**は、  
データ構造（オブジェクト群）の定義を変更することなく、  
**新しい振る舞い（操作）を追加可能にするための構造的デザインパターン**である。

この設計により、**「構造」と「振る舞い」を分離し、  
オブジェクトに新たな処理を注入することが可能となる。**

---

## 1. なぜVisitorが必要か？

### ❌ オブジェクトクラスに振る舞いが集中する設計

```python
class File:
    def print(self):
        ...
    def export(self):
        ...
```

→ ファイルの構造に新しい処理を加えるたびに、**クラスの肥大化と責務の分散が発生**

---

### ✅ 振る舞いはVisitorクラスに切り出して注入する

```python
class PrintVisitor:
    def visit_file(self, file): ...
```

→ **構造定義を触らずに振る舞いの追加・変更が可能**

---

## 2. 基本構造

### ✅ Element（訪問される側）

```python
class Element:
    def accept(self, visitor):
        raise NotImplementedError
```

```python
class File(Element):
    def __init__(self, name):
        self.name = name

    def accept(self, visitor):
        visitor.visit_file(self)
```

---

### ✅ Visitor（振る舞いを定義する側）

```python
class Visitor:
    def visit_file(self, file):
        raise NotImplementedError
```

```python
class PrintVisitor(Visitor):
    def visit_file(self, file):
        print(f"[Print] File name: {file.name}")
```

---

### ✅ 使用例

```python
file = File("document.txt")
visitor = PrintVisitor()
file.accept(visitor)  # → [Print] File name: document.txt
```

---

## 3. Python的応用：ダブルディスパッチの活用

```python
class Folder(Element):
    def __init__(self, children):
        self.children = children

    def accept(self, visitor):
        visitor.visit_folder(self)
```

```python
class CountVisitor(Visitor):
    def __init__(self):
        self.count = 0

    def visit_file(self, file):
        self.count += 1

    def visit_folder(self, folder):
        for item in folder.children:
            item.accept(self)
```

```python
f1 = File("a.txt")
f2 = File("b.txt")
folder = Folder([f1, f2])

visitor = CountVisitor()
folder.accept(visitor)
print(visitor.count)  # → 2
```

→ **構造を歩きながら異なる型に応じた処理を実行**

---

## 4. 実務ユースケース

### ✅ 抽象構文木（AST）のトラバースと評価

→ 構文要素ごとに処理（例：プリント/変換/最適化）を注入

---

### ✅ ファイルシステムやXMLの構造解析

→ ファイル/フォルダ/属性などのツリー構造に対して統一されたアクセス

---

### ✅ データモデルへの複数操作（表示、エクスポート、検証）

→ データ構造を変更せず**表示・保存・検査の各処理を独立して管理**

---

### ✅ ゲームエンジン内のエンティティ評価処理

→ 位置計算、AI判定、エフェクト適用など**一括処理を分離して追加可能**

---

## 5. よくある誤用と対策

### ❌ VisitorがすべてのElementに依存

→ ✅ Visitorを分割して関心の分離を保つ（Single Responsibility Principle）

---

### ❌ accept() メソッドの未実装

→ ✅ 各Element型に明示的に `accept(visitor)` を実装し、**動的な振る舞い注入を保証**

---

### ❌ Visitorにロジックが集中しすぎる

→ ✅ Visitorは**操作の集合体**であって、構造の責任を持たない

---

## 結語

**Visitorパターンとは、“構造に手を加えず、振る舞いだけを柔軟に追加する”ための構造的技法である。**

- 型ごとの処理をVisitorに集約することで、**拡張性と保守性を同時に満たす**  
- 実行対象が複数種類のオブジェクトを持つ場合に、**構文的に洗練されたディスパッチ処理を実現**  
- Pythonにおいても動的ディスパッチの仕組みとクラス構造の活用により、**自然かつ強力なVisitor設計が可能**

**Pythonicとは、“構造と振る舞いを分離し、明快な責務で再構成する”ことであり、  
Visitorパターンはその設計的透明性と柔軟性をコードに浸透させる知的戦略である。**
Pythonで設計するMementoパターン：状態のスナップショットによる巻き戻し機構



## 概要

**Memento（メメント）パターン**は、  
あるオブジェクトの**内部状態を外部からアクセスできない方法で保存し、後でその状態に復元できるようにする**ための設計パターンである。

主に「Undo」や「Redo」など、**状態の巻き戻し機構が求められるシステムで活用される**。

---

## 1. なぜMementoが必要か？

### ❌ 状態変更が破壊的で戻せない設計

```python
editor.text = "New text"
# 元の状態は失われる
```

→ 状態を戻す手段がないと、**修正の追跡や巻き戻しが不可能**

---

### ✅ 状態のスナップショットを保持し、必要に応じて復元

```python
snapshot = editor.save()
...
editor.restore(snapshot)
```

→ **編集前後の状態を安全に退避・復元**

---

## 2. 基本構造

### ✅ Memento（スナップショット）クラス

```python
class Memento:
    def __init__(self, state):
        self._state = state

    def get_state(self):
        return self._state
```

---

### ✅ Originator（状態を持つオブジェクト）

```python
class Editor:
    def __init__(self):
        self._text = ""

    def type(self, words):
        self._text += words

    def save(self):
        return Memento(self._text)

    def restore(self, memento: Memento):
        self._text = memento.get_state()

    def show(self):
        print(self._text)
```

---

### ✅ Caretaker（Mementoを管理）

```python
class History:
    def __init__(self):
        self._undo_stack = []

    def push(self, memento: Memento):
        self._undo_stack.append(memento)

    def pop(self):
        return self._undo_stack.pop() if self._undo_stack else None
```

---

### ✅ 使用例

```python
editor = Editor()
history = History()

editor.type("Hello, ")
history.push(editor.save())

editor.type("world!")
editor.show()  # Hello, world!

editor.restore(history.pop())
editor.show()  # Hello,
```

---

## 3. Python的応用：DeepCopyによる簡易スナップショット

```python
import copy

state = {"text": "initial", "cursor": 0}
snapshots = []

snapshots.append(copy.deepcopy(state))
state["text"] = "edited"
state["cursor"] = 6

state = snapshots[-1]
print(state)  # {'text': 'initial', 'cursor': 0}
```

→ **辞書やデータ構造をそのまま保存・復元できる構成**

---

## 4. 実務ユースケース

### ✅ テキストエディタのUndo/Redo機構

→ 編集前の状態をMementoとして記録し、**任意のタイミングで巻き戻し**

---

### ✅ フォーム入力のチェックポイント保存

→ 入力値の途中保存やエラー前の状態復元

---

### ✅ ゲームのセーブ/ロード設計

→ キャラクターの状態、アイテム、進行状況の保存と復元

---

### ✅ 設定画面や履歴の差し戻し機構

→ ユーザーが設定を戻したい場合に対応

---

## 5. よくある誤用と対策

### ❌ Mementoが内部状態に直接アクセス可能

→ ✅ `get_state()` や `restore()` を通じて、**カプセル化を維持**

---

### ❌ スナップショットの保存タイミングが曖昧

→ ✅ 状態の変化直前に **明示的に `save()` を呼び出す**

---

### ❌ Caretakerが状態に干渉する設計

→ ✅ Caretakerは **Mementoの管理のみに専念**し、状態の評価・変更は行わない

---

## 結語

**Mementoパターンとは、“変化するものに過去を与え、未来を制御可能にする構造設計”である。**

- オブジェクトの状態を**外部からアクセス不能な形で安全に退避**  
- 「巻き戻し」や「途中保存」などの機能に、**最適なスナップショット機構を提供**  
- Pythonにおいては、オブジェクト指向とシリアライズ／deepcopyと組み合わせることで、**直感的かつ堅牢な実装が可能**

**Pythonicとは、“状態を信頼できる形で記録・復元する”ことであり、  
Mementoパターンはその過去との対話を、設計の一部として優雅に取り入れるための技法である。**
Pythonで実装するMediatorパターン：依存を中央に集約し、関係性の爆発を防ぐ設計



## 概要

**Mediator（メディエーター）パターン**は、  
複数のオブジェクト同士が直接通信するのではなく、**中央に調停者（Mediator）を配置して、  
オブジェクト間の依存関係を1対1から1対多へと変換する構造的パターン**である。

この設計により、**依存関係のスパゲッティ化を防ぎ、疎結合なコンポーネント同士を整然と接続**することができる。

---

## 1. なぜMediatorが必要か？

### ❌ 各オブジェクトが他を知りすぎている（直接依存）

```python
class A:
    def notify_b(self, b):
        b.do_something()

class B:
    def notify_c(self, c):
        c.do_other()
```

→ **依存が連鎖し、変更が全体に波及する脆弱な設計**

---

### ✅ 調停者（Mediator）がやり取りを一元管理

```python
mediator.notify(sender=a, event="start")
```

→ **オブジェクトはMediatorだけを知っていればよく、他のオブジェクトには非依存**

---

## 2. 基本構造

### ✅ Mediatorインターフェース

```python
class Mediator:
    def notify(self, sender, event):
        raise NotImplementedError
```

---

### ✅ コンポーネント側

```python
class Component:
    def __init__(self, mediator=None):
        self._mediator = mediator

    def set_mediator(self, mediator):
        self._mediator = mediator
```

---

### ✅ 実装例：UIコンポーネントの調停

```python
class Button(Component):
    def click(self):
        print("[Button] Clicked.")
        self._mediator.notify(self, "button_clicked")

class Dialog(Component):
    def show_message(self):
        print("[Dialog] Showing message...")
```

---

### ✅ ConcreteMediator（中央調停役）

```python
class UIController(Mediator):
    def __init__(self, button, dialog):
        self.button = button
        self.dialog = dialog
        self.button.set_mediator(self)
        self.dialog.set_mediator(self)

    def notify(self, sender, event):
        if event == "button_clicked":
            self.dialog.show_message()
```

---

### ✅ 使用例

```python
button = Button()
dialog = Dialog()
mediator = UIController(button, dialog)

button.click()
# Output:
# [Button] Clicked.
# [Dialog] Showing message...
```

---

## 3. Python的応用：イベント名とディスパッチ

```python
class EventMediator:
    def __init__(self):
        self._handlers = {}

    def register(self, event, handler):
        self._handlers[event] = handler

    def notify(self, event, *args, **kwargs):
        if handler := self._handlers.get(event):
            handler(*args, **kwargs)
```

```python
def on_login(user):
    print(f"{user} logged in")

mediator = EventMediator()
mediator.register("login", on_login)
mediator.notify("login", user="Alice")
```

→ **イベントディスパッチャとしての応用も可能**

---

## 4. 実務ユースケース

### ✅ GUIアプリケーション（MVC/Presenter）における中間調停

→ ボタン・フォーム・通知センターの仲介者として**UIControllerを設計**

---

### ✅ チャットシステム、Pub/Sub基盤の調整層

→ ユーザー間メッセージの伝播を**ハブ的に集約**

---

### ✅ ゲームのエンティティ間通信調整

→ プレイヤー・敵・環境が直接通信せず**GameManagerが調整**

---

### ✅ イベントバス/メッセージバス的設計

→ 状態遷移、ライフサイクル制御、非同期フローの管理にも応用

---

## 5. よくある誤用と対策

### ❌ Mediatorが神クラス化（全責務集中）

→ ✅ Mediatorは**調停のみに責任を限定し、ロジックは各コンポーネントに**

---

### ❌ すべてをMediator経由にしてしまう

→ ✅ **相互依存が発生する箇所のみ**に限定的にMediatorを導入

---

### ❌ コンポーネントがMediatorに強く依存

→ ✅ `Mediator` インターフェース経由で抽象化し、**具象型への依存を排除**

---

## 結語

**Mediatorパターンとは、“複数のオブジェクト間の通信を集中管理することで、依存性の爆発を制御する構造設計”である。**

- 1対多構造への変換により、**コードの拡張性と保守性を飛躍的に向上**  
- 各コンポーネントの独立性を保ちつつ、**連携の中心を明示的に定義**  
- Pythonではオブジェクト参照とディスパッチ関数の活用により、**柔軟かつ簡潔なMediator構築が可能**

**Pythonicとは、“疎結合で協調する”という設計思想であり、  
Mediatorパターンはその仲介と制御の美学を、アーキテクチャに注ぎ込む技法である。**
Pythonで構築するInterpreterパターン：独自言語を解析する構文的アプローチ



## 概要

**Interpreter（インタープリター）パターン**は、  
文法ルールに従った構文（言語）を定義し、それを評価（解釈）するための**クラス構造を用いてドメイン固有言語（DSL）を実装する設計パターン**である。

四則演算、条件文、コマンド解釈、数式処理など、  
**小規模な構文系を再現可能にし、動的に構造化された振る舞いを構築する**ことができる。

---

## 1. なぜInterpreterが必要か？

### ❌ DSLを文字列で解析しようとする煩雑な処理

```python
def eval_expr(expr):
    if expr == "1 + 2":
        return 3
```

→ パターンが増えるごとに if/else が増え、**構造的拡張が困難**

---

### ✅ 各構文要素をクラスで定義し、再帰的に解釈できるようにする

```python
expr = Add(Number(1), Number(2))
expr.interpret()  # → 3
```

→ **式の構造をオブジェクトで表現し、意味的な解釈が可能に**

---

## 2. 基本構造

### ✅ 抽象式クラス

```python
class Expression:
    def interpret(self):
        raise NotImplementedError
```

---

### ✅ 数値ノード（終端）

```python
class Number(Expression):
    def __init__(self, value):
        self.value = value

    def interpret(self):
        return self.value
```

---

### ✅ 非終端式ノード（加算）

```python
class Add(Expression):
    def __init__(self, left: Expression, right: Expression):
        self.left = left
        self.right = right

    def interpret(self):
        return self.left.interpret() + self.right.interpret()
```

---

### ✅ 使用例

```python
expr = Add(Number(4), Add(Number(2), Number(3)))  # 4 + (2 + 3)
print(expr.interpret())  # → 9
```

---

## 3. Python的応用：DSL構築と構文木の表現

### ✅ AND / OR 検索クエリの例

```python
class Terminal(Expression):
    def __init__(self, keyword):
        self.keyword = keyword

    def interpret(self, context):
        return self.keyword in context

class And(Expression):
    def __init__(self, left, right):
        self.left = left
        self.right = right

    def interpret(self, context):
        return self.left.interpret(context) and self.right.interpret(context)
```

```python
expr = And(Terminal("Python"), Terminal("Tips"))
print(expr.interpret("Python Tips Article"))  # → True
print(expr.interpret("Python Design"))        # → False
```

---

## 4. 実務ユースケース

### ✅ DSLベースの構成ファイルやルールエンジンの実装

→ 条件・数式・構成定義などを**式として構造化解釈**

---

### ✅ 検索クエリ・フィルタエンジン

→ AND/OR/NOT を式ツリーとして評価し、**柔軟な条件検索**

---

### ✅ 数式処理・簡易言語の構築（電卓、式エンジン）

→ 数学DSLの解釈・計算・変換に最適

---

### ✅ 自然言語処理・構文分析のトイ実装

→ 文法規則に基づく再帰下降型のパーサ実験などに応用

---

## 5. よくある誤用と対策

### ❌ 抽象構文木の構築と評価処理が密結合

→ ✅ 解釈ロジックは `interpret()` に閉じ、**構文構築は別レイヤーで**

---

### ❌ 状態を内部に持ちすぎて評価が不安定

→ ✅ インターフェースは明示的に `interpret(context)` のようにし、**明確な引数で評価**

---

### ❌ 構文パターンの拡張が面倒になる設計

→ ✅ 継承ではなく**合成による構造拡張**を基本とし、柔軟性を保つ

---

## 結語

**Interpreterパターンとは、“構文と意味の対応関係をコード構造で明示化する技術”である。**

- 文法の各要素をクラスとして明示し、**意味解釈を責務として定義**  
- 再帰的な式処理、DSLの実装、ルールエンジンなどに応用可能  
- Pythonのオブジェクト指向特性により、**抽象構文木と意味解釈の実装が極めて直感的に**

**Pythonicとは、“構造を持った表現をコードとして操作可能にすること”であり、  
Interpreterパターンはその言語的構造性を、柔軟な評価フローとして表現するための設計技法である。**
Pythonで構築するFlyweightパターン：メモリ効率を極限まで高める構造設計



## 概要

**Flyweight（フライウェイト）パターン**は、  
多数のオブジェクトが類似または同一の状態を持つ場合に、  
**共有可能な部分（不変な内部状態）を外部に分離・再利用することで、メモリ効率を最適化する構造的パターン**である。

数百万単位で生成されるオブジェクト群の**状態の重複を排除し、構造的に共有することで軽量化を実現する**。

---

## 1. なぜFlyweightが必要か？

### ❌ 同一状態のオブジェクトを大量に生成

```python
for _ in range(1000000):
    glyphs.append(Character("A", "Arial", 12))
```

→ メモリを浪費し、**スケーラビリティが著しく低下**

---

### ✅ 共有可能な状態を外部化し、Flyweightで再利用

```python
factory.get_char("A", "Arial", 12)
```

→ **同一状態のインスタンスは1つだけ保持され、以後は共有参照**

---

## 2. 基本構造

### ✅ Flyweightクラス（共有される軽量オブジェクト）

```python
class Character:
    def __init__(self, char, font, size):
        self.char = char          # 内部状態（共有）
        self.font = font
        self.size = size

    def render(self, position):
        print(f"{self.char} [{self.font}, {self.size}] at {position}")
```

---

### ✅ FlyweightFactory（インスタンスのキャッシュ管理）

```python
class CharacterFactory:
    def __init__(self):
        self._pool = {}

    def get(self, char, font, size):
        key = (char, font, size)
        if key not in self._pool:
            self._pool[key] = Character(char, font, size)
        return self._pool[key]
```

---

### ✅ 使用例

```python
factory = CharacterFactory()

doc = []
for i in range(100):
    doc.append(factory.get("A", "Arial", 12))

# 実際に生成されたCharacterインスタンスは1つのみ
print(len(set(id(c) for c in doc)))  # → 1
```

---

## 3. Python的応用：`@lru_cache` によるFlyweight化

```python
from functools import lru_cache

@lru_cache(maxsize=128)
def get_color(r, g, b):
    return (r, g, b)

color1 = get_color(255, 255, 255)
color2 = get_color(255, 255, 255)
assert color1 is color2  # 共有されている
```

→ **不変オブジェクトのキャッシュにより、実質Flyweight化**

---

## 4. 実務ユースケース

### ✅ ゲームにおけるキャラクター表示・粒子・地形要素

→ 同一グラフィック・属性を持つエンティティを**効率よくレンダリング**

---

### ✅ フォントレンダリング・文字表示システム

→ 文字ごとにオブジェクトを作らず、**キャッシュで共有レンダリング**

---

### ✅ 色・スタイル・アイコンの共通化

→ UI上の装飾情報を**構造的に管理・再利用**

---

### ✅ ファイルパーミッション・属性・ステータスの定義共有

→ 状態をクラス化し、**同一内容を共通オブジェクトで表現**

---

## 5. よくある誤用と対策

### ❌ 外部状態と内部状態の区別が曖昧

→ ✅ 共有可能な状態（フォント・サイズなど）は内部に、  
位置や一時的な情報は**外部で持つ**

---

### ❌ 共有すべきでないオブジェクトまでキャッシュする

→ ✅ 状態が変化するものは**Flyweightに適さない**

---

### ❌ キャッシュが肥大化し、逆にメモリ消費が増大

→ ✅ `maxsize` を明示的に設定し、**キャッシュ管理を明確に**

---

## 結語

**Flyweightパターンとは、“重複するデータを構造的に共有し、無駄をそぎ落とす設計技法”である。**

- 高頻度・大量オブジェクト生成時に、**最小限のリソースで最大の表現を可能に**  
- 内部状態と外部状態を分離し、**オブジェクトの意味的重複を排除**  
- Pythonでは `dict` や `@lru_cache`、オブジェクトIDの比較で、**直感的な実装が可能**

**Pythonicとは、“同じものは使い回す”という合理性に基づいた設計であり、  
Flyweightパターンはその節制と効率性を、メモリに染み込ませるための技術である。**
Pythonで構築するChain of Responsibilityパターン：責任の流れを設計する柔軟な分岐構造



## 概要

**Chain of Responsibility（責任の連鎖）パターン**は、  
リクエストを複数の処理者（ハンドラ）に順番に渡し、  
**それぞれの処理者が「自分が処理可能かどうか」を判断しながら責任を委譲する設計パターン**である。

この構造により、if-else や switch-case で構成された**巨大な分岐処理を疎結合で柔軟な連鎖構造に変換**できる。

---

## 1. なぜChain of Responsibilityが必要か？

### ❌ 巨大なif-elseブロックによる分岐処理

```python
def handle(request):
    if request == "A":
        ...
    elif request == "B":
        ...
    elif request == "C":
        ...
```

→ **処理の追加・変更が困難で、責務が集中した構造**

---

### ✅ 各処理者をクラスに分割し、連鎖構造で責任を委譲

```python
handler_a.set_next(handler_b).set_next(handler_c)
handler_a.handle(request)
```

→ **柔軟かつ拡張可能な設計に進化**

---

## 2. 基本構造

### ✅ 抽象ハンドラクラス

```python
class Handler:
    def set_next(self, handler):
        self._next = handler
        return handler

    def handle(self, request):
        if hasattr(self, "_next"):
            return self._next.handle(request)
        return None
```

---

### ✅ 具体的な処理者クラス

```python
class AuthHandler(Handler):
    def handle(self, request):
        if request.get("auth"):
            print("認証OK")
            return super().handle(request)
        else:
            print("認証失敗")
            return "Unauthorized"

class DataHandler(Handler):
    def handle(self, request):
        if "data" in request:
            print("データ処理中...")
            return "Success"
        return super().handle(request)
```

---

### ✅ 使用例

```python
auth = AuthHandler()
data = DataHandler()

auth.set_next(data)

request = {"auth": True, "data": "payload"}
result = auth.handle(request)
print(result)  # → Success
```

---

## 3. Python的応用：関数やラムダで構築するチェーン

```python
class FunctionHandler(Handler):
    def __init__(self, func):
        self.func = func
        self._next = None

    def handle(self, request):
        if self.func(request):
            return super().handle(request)
        return "Blocked"
```

```python
h1 = FunctionHandler(lambda r: r.get("step1"))
h2 = FunctionHandler(lambda r: r.get("step2"))
h1.set_next(h2)
h1.handle({"step1": True, "step2": True})
```

---

## 4. 実務ユースケース

### ✅ リクエスト処理パイプライン（Webミドルウェア）

→ 認証 → バリデーション → ログ → 本処理 … のような**前処理構成に最適**

---

### ✅ フォールバック付き処理系（プランA → プランB → プランC）

→ 最初に成功した処理で止めたいケースに有効

---

### ✅ イベントディスパッチャ、ルーティングの定義

→ 各ハンドラに処理条件をもたせ、**該当するものが責任を引き受ける**

---

### ✅ エラーハンドリング・再試行フロー

→ 失敗時の処理チェーン、代替処理の定義が可能

---

## 5. よくある誤用と対策

### ❌ 全てのハンドラが必ず処理を行う構造

→ ✅ `handle()` は **処理済みかどうかの判定を明確に実装**し、必要に応じて打ち切る

---

### ❌ チェーンの順番が意図とずれる

→ ✅ `set_next()` の順序に依存するため、**構築時に明示的に順番を定義**

---

### ❌ ステートレス処理とステートフル処理の混在

→ ✅ 各ハンドラの設計において、**副作用の有無を意識的に区別**

---

## 結語

**Chain of Responsibilityパターンとは、“責任を分散させながら柔軟に制御するための構造”である。**

- 処理の流れを構造で記述し、**責務の分離と順序の保証を両立**  
- 条件の増加や分岐の変更に対して、**堅牢かつ拡張しやすい設計**  
- Pythonにおける動的クラス・高階関数の活用により、**より柔らかな連鎖設計が可能**

**Pythonicとは、“分岐を構造に昇華させ、柔軟性と秩序を両立させる”ことであり、  
Chain of Responsibilityパターンはその連鎖的設計力を、処理フローに注ぎ込むための技法である。**
Pythonで設計するTemplate Methodパターン：アルゴリズムの骨格を保ちつつ柔軟に拡張する設計


## 概要

**Template Method（テンプレートメソッド）パターン**は、  
**アルゴリズム全体の流れ（骨格）をスーパークラスで定義し、  
その中の一部のステップをサブクラスで実装させることによって、  
処理の順序を維持したまま柔軟な拡張を可能にする構造的パターン**である。

「変わる部分」と「変わらない部分」を明確に分離できることから、  
**継承ベースの拡張戦略において極めて重要なポジションを占める。**

---

## 1. なぜTemplate Methodが必要か？

### ❌ サブクラスが全体の流れを再定義してしまう

```python
class FileProcessor:
    def run(self):
        self.read()
        self.process()
        self.save()
```

→ 継承側が自由に `run()` を書き換えてしまうと、**流れが崩壊し、共通化の意味を失う**

---

### ✅ スーパークラスに処理フローを固定し、  
サブクラスに差分のみの実装を委ねる

```python
class AbstractProcessor:
    def run(self):
        self.read()
        self.process()
        self.save()

    def read(self): ...
    def process(self): ...
    def save(self): ...
```

→ **処理の構造は保証しつつ、個別の処理のみを差し替えられる設計に**

---

## 2. 基本構造

### ✅ スーパークラス（抽象テンプレート）

```python
class AbstractReport:
    def generate(self):
        self.fetch_data()
        self.analyze()
        self.render()

    def fetch_data(self):
        raise NotImplementedError

    def analyze(self):
        raise NotImplementedError

    def render(self):
        print("Rendering report...")  # 共通処理
```

---

### ✅ サブクラスによる拡張

```python
class SalesReport(AbstractReport):
    def fetch_data(self):
        print("Fetching sales data...")

    def analyze(self):
        print("Analyzing sales trends...")

class HRReport(AbstractReport):
    def fetch_data(self):
        print("Fetching employee data...")

    def analyze(self):
        print("Analyzing retention rates...")
```

---

### ✅ 使用例

```python
report = SalesReport()
report.generate()

# Output:
# Fetching sales data...
# Analyzing sales trends...
# Rendering report...
```

---

## 3. Python的応用：フックメソッドの導入

```python
class Template:
    def run(self):
        self.before()
        self.main()
        self.after()

    def before(self):
        pass  # 任意実装

    def main(self):
        raise NotImplementedError

    def after(self):
        pass  # 任意実装
```

→ **オプション的に実装可能な「フックメソッド」で柔軟性を持たせる**

---

## 4. 実務ユースケース

### ✅ ファイル処理パイプライン（読み込み→加工→保存）

→ `read()`, `process()`, `save()` を固定フローにして、サブクラスでフォーマットや処理内容を切り替え

---

### ✅ バッチ処理の雛形定義

→ 共通化された `run()` に対して、ステップごとの処理のみカスタマイズ可能に

---

### ✅ Webフレームワーク内のView構成（Django CBVなど）

→ HTTPメソッドごとの処理フックをサブクラスで定義し、**共通の構造を維持**

---

### ✅ テストフレームワークでのライフサイクル管理

→ `setup() → test() → teardown()` のフローを保証しつつ、テストごとの処理を実装

---

## 5. よくある誤用と対策

### ❌ サブクラスがテンプレートメソッド（`generate()`）自体をオーバーライド

→ ✅ スーパークラスのテンプレート構造は固定し、**破壊的なオーバーライドを避ける**

---

### ❌ 必須ステップを `pass` のままにして忘れる

→ ✅ `NotImplementedError` を明示的に仕込んで、**未実装の検知性を高める**

---

### ❌ 状態の共有が適切に設計されていない

→ ✅ 共通ステップと個別ステップが**同じオブジェクトの状態を前提に設計されているか**を確認

---

## 結語

**Template Methodパターンとは、“アルゴリズムの構造とステップの自由度を両立させる”ための継承ベース構造設計である。**

- 全体の流れを固定しつつ、ステップ単位で差分実装を許容することで、**拡張可能で堅牢な構造を維持**  
- サブクラスに過度な責務を与えず、**「型通りに拡張すればうまくいく」構造を保証**  
- Pythonにおいても継承・オーバーライド・フックの活用により、**テンプレートベースの再利用が直感的に実現可能**

**Pythonicとは、“変更を受け入れつつ、流れは崩さない”設計であり、  
Template Methodパターンはその秩序と柔軟性を、コード全体に静かに浸透させる技法である。**
Pythonで実装するStrategyパターン：アルゴリズムの切替を構造として分離する設計



## 概要

**Strategy（ストラテジー）パターン**は、  
ある機能に対して複数の異なるアルゴリズムが存在する場合に、  
**その選択・切り替えを動的かつ柔軟に行えるように設計する構造的パターン**である。

アルゴリズムの実装をインターフェースの背後に隠蔽することで、  
**拡張可能で変更に強い設計を実現**する。

---

## 1. なぜStrategyが必要か？

### ❌ 条件分岐でアルゴリズムを切り替える設計

```python
def calculate(a, b, method="add"):
    if method == "add":
        return a + b
    elif method == "sub":
        return a - b
```

→ **新しい戦略が増えるたびに関数を改修する必要があり、拡張性が低い**

---

### ✅ 戦略（アルゴリズム）を分離し、切り替え可能に

```python
calc = Calculator(AddStrategy())
calc.execute(10, 5)  # → 15
```

→ アルゴリズムを動的に切り替えられる柔軟な設計へ

---

## 2. 基本構造

### ✅ Strategyインターフェース

```python
class Strategy:
    def execute(self, a, b):
        raise NotImplementedError
```

---

### ✅ 具体的戦略クラス

```python
class AddStrategy(Strategy):
    def execute(self, a, b):
        return a + b

class SubtractStrategy(Strategy):
    def execute(self, a, b):
        return a - b

class MultiplyStrategy(Strategy):
    def execute(self, a, b):
        return a * b
```

---

### ✅ コンテキストクラス

```python
class Calculator:
    def __init__(self, strategy: Strategy):
        self._strategy = strategy

    def set_strategy(self, strategy: Strategy):
        self._strategy = strategy

    def execute(self, a, b):
        return self._strategy.execute(a, b)
```

---

### ✅ 使用例

```python
calc = Calculator(AddStrategy())
print(calc.execute(4, 2))  # 6

calc.set_strategy(SubtractStrategy())
print(calc.execute(4, 2))  # 2

calc.set_strategy(MultiplyStrategy())
print(calc.execute(4, 2))  # 8
```

---

## 3. Python的応用：関数ベースの戦略実装

```python
def divide(a, b):
    return a / b

class FunctionStrategy(Strategy):
    def __init__(self, func):
        self.func = func

    def execute(self, a, b):
        return self.func(a, b)
```

```python
calc.set_strategy(FunctionStrategy(divide))
print(calc.execute(10, 2))  # 5.0
```

→ **関数やラムダでも簡易的に戦略を定義可能**

---

## 4. 実務ユースケース

### ✅ 並び替え・フィルタリングロジックの切替

→ 名前順、日付順、優先度順など**動的に適用ロジックを切替可能**

---

### ✅ 認証方式の切替（パスワード / トークン / OAuth）

→ Strategyでログイン方式を切り替え、**統一された呼び出し口を維持**

---

### ✅ レコメンド・評価ロジックのバリエーション設計

→ 機械学習スコア / 手動重み付け / 人気順 などの**計算戦略を柔軟に追加**

---

### ✅ 戦略テストやA/Bテストの適用

→ 実行時に戦略を差し替えることで**仮説検証を柔軟に行える**

---

## 5. よくある誤用と対策

### ❌ Strategy内に状態や副作用を持たせる

→ ✅ 戦略はあくまで「計算・振る舞い」に特化し、**副作用は避ける**

---

### ❌ Contextが特定のStrategy型を直接呼ぶ

→ ✅ `execute()` を通じて**ポリモーフィズムで切り替えること**

---

### ❌ StrategyとFactoryの混同

→ ✅ Strategyは**切り替えるための抽象化**であり、**生成責務はFactoryへ分離**

---

## 結語

**Strategyパターンとは、“アルゴリズムの選択可能性を設計段階で保証する”柔軟な構造手法である。**

- 条件分岐から解放され、**オープン/クローズドの原則を自然に満たす**  
- 戦略のテスト、切替、差し替えが簡易で、**仮説検証やA/Bテストの足場として強力**  
- Pythonの関数型構文・クラス設計の両方と親和性が高く、**現実的な設計に適している**

**Pythonicとは、“振る舞いを注入可能な形で設計する”ことであり、  
Strategyパターンはその注入の自由度を高め、コードを柔らかく保つための知的な手段である。**
PythonにおけるObserverパターン：通知と購読の設計で非同期性を整える



## 概要

**Observer（オブザーバ）パターン**は、  
あるオブジェクト（Subject）の状態が変化した際に、それに依存する複数のオブジェクト（Observers）へ**通知を一斉に行う仕組みを提供する構造的パターン**である。

この設計により、**疎結合で反応的なシステム構築**が可能となり、  
イベント駆動設計・データ同期・非同期通知など多くの場面で活用される。

---

## 1. なぜObserverが必要か？

### ❌ 通知先がハードコードされた密結合

```python
def update_dashboard():
    ...

def update_log():
    ...

def on_change():
    update_dashboard()
    update_log()
```

→ 通知対象が増えると変更箇所も増え、**拡張に弱い設計**

---

### ✅ 観測者（Observer）を登録制にする

```python
subject.register(update_dashboard)
subject.register(update_log)
subject.notify()
```

→ **通知対象の追加・削除が柔軟に**

---

## 2. 基本構造

### ✅ Observerインタフェース

```python
class Observer:
    def update(self, data):
        raise NotImplementedError
```

---

### ✅ Subject（通知元）

```python
class Subject:
    def __init__(self):
        self._observers = []

    def register(self, observer: Observer):
        self._observers.append(observer)

    def unregister(self, observer: Observer):
        self._observers.remove(observer)

    def notify(self, data):
        for observer in self._observers:
            observer.update(data)
```

---

### ✅ Observer実装クラス

```python
class Logger(Observer):
    def update(self, data):
        print(f"[LOG] {data}")

class Dashboard(Observer):
    def update(self, data):
        print(f"[UI] Refreshing dashboard with: {data}")
```

---

### ✅ 使用例

```python
subject = Subject()
subject.register(Logger())
subject.register(Dashboard())

subject.notify("New data received")
```

```
[LOG] New data received
[UI] Refreshing dashboard with: New data received
```

---

## 3. Python的応用：関数やラムダによる購読

```python
class FunctionObserver:
    def __init__(self, func):
        self._func = func

    def update(self, data):
        self._func(data)
```

```python
subject.register(FunctionObserver(lambda d: print(f"Lambda -> {d}")))
```

→ **オブジェクトだけでなく関数も購読可能**にすることで、より柔軟な通知先設計

---

## 4. 実務ユースケース

### ✅ イベント駆動設計の基礎として

- UIイベント、ボタン操作、外部APIからのリアクティブ処理

---

### ✅ データ同期処理（状態の一貫性）

- モデルの変更 → UIコンポーネントやDBへ通知

---

### ✅ 非同期通知・リアルタイムログ

- プロセス監視やシステムログを複数サブスクライバに中継

---

### ✅ 自作Pub/Sub機構やイベントバスの基盤

- 高度なアーキテクチャでは**イベント名とルーティング**による複数購読の構築も可能

---

## 5. よくある誤用と対策

### ❌ ObserverがSubjectに強く依存

→ ✅ 双方向依存を避け、**Subject → Observer の一方向に設計する**

---

### ❌ 通知のたびに全てのObserverが呼ばれる

→ ✅ **フィルタ条件やイベント種類別購読**を設け、不要な更新を防止

---

### ❌ 例外発生で通知が中断される

→ ✅ `notify()` 内で `try...except` を適用し、**堅牢な通知フローを保証**

---

## 結語

**Observerパターンとは、“変化をリアルタイムで伝播させる仕組みを構造的に実現する”技法である。**

- 変更の検知と通知を、**明示的な関係として表現**し、再利用可能な構造に  
- サブスクライバを疎結合に保ちつつ、**拡張性と反応性を両立**  
- Pythonの動的性により、**関数・クラス・匿名関数まで広範なObserver構成が可能**

**Pythonicとは、“変化に自然に追従できる構造を設計する”ことであり、  
Observerパターンはその柔軟性と即応性を、システム設計に注入するための技法である。**