/* Page prose (ja) */
"ClassicModernInPractice" = "# 実践におけるクラシックとモダン\n\n## 概念マップ\n\nほとんどすべてのクラシックツールには、直接対応するモダンな対応物があります。古いコードを読むとき、あるいはそれを移行するとき、これが変換表です。\n\n* completion handler、`(Result<T,E>) -> Void`、➡️ `async throws -> T` 関数。結果は戻り値として*返って*きます。エラーは `throw` します。\n* `DispatchQueue.global().async { }` ➡️ `Task { }` / 協調プール。*どのキュー*かではなく、*作業*を記述します。\n* バッチのための `DispatchGroup` / `semaphore.wait()` ➡️ `async let`（固定集合）または `TaskGroup`（動的集合）。結合は構造的で、釣り合わせるカウンターはありません。\n* 共有状態を守るために使うシリアルキュー ➡️ **`actor`**。分離は規律ではなく型によって強制されます。\n* `DispatchQueue.main.async { }` ➡️ **`@MainActor`**。メインスレッドであることがシグネチャの一部です。\n* 手作業の `isCancelled` チェックを伴う `Operation` ➡️ 協調的な **`Task` キャンセル**（`Task.isCancelled` / `try Task.checkCancellation()`）。キャンセルはタスクツリーを自動的に下方へ伝播します。\n* 何度も発火する delegate やコールバック ➡️ **`AsyncStream`**（または単発のための **continuation**）。イベントは、`break` で抜け出せる `for await` ループになります。\n\n強調しておく価値のある 2 つのこと。\n\n第一に、**`async let` と `TaskGroup` はどちらも `DispatchGroup` を置き換えます**。取得を前もって知っている場合（ここでの 2 つのように）は `async let` を選び、数が実行時に決まる場合は `TaskGroup` を選びます。\n\n第二に、**actor は静かなヒーローです**。クラシックモデルで最もバグを生みやすいもの（共有状態を守るシリアルキューやカウント 1 のセマフォで、すべてのアクセスをそこ経由で回すよう忘れずに覚えておかねばならなかったもの）が、コンパイラが取り締まってくれる型になります。\n\n---\n\n## クラシックモデルを今なお使うのはいつか\n\nモダンモデルは新しいコードのデフォルトです。しかし「クラシックは死んだ」というのは誤りで、不要な書き直しへと導いてしまうでしょう。次のようなときは GCD と `Operation` を使い（あるいは残し）ましょう。\n\n* **古い API を呼び出しているとき。**  \n多くのフレームワーク（そして自分自身の古いコード）は、今でも completion handler や delegate を渡してきます。それらと*相互運用*します。まず世界全体を変換する必要はありません（きれいなやり方はそれらをラップすることです。次のページを参照）。\n* **とても細かい単位のディスパッチ制御が必要なとき。**  \n正確な QoS を持つ特定のカスタムシリアルキュー、ファイルやタイマーのための `DispatchSource`、並行キュー上のバリアブロック。これらは今でも正当であり、時には最も直接的なツールです。協調プールはスレッドの詳細を意図的に隠します。本当にそうした詳細が必要なとき、GCD はすぐそこにあります。\n* **`async`/`await` より前の OS バージョンを対象にしているとき。**  \nSwift の並行処理は iOS 13 以降（およびそれに相当する macOS 10.15、tvOS 13、watchOS 6）で動作します。iOS 13 は 2019 年に出荷されたので、この理由は今では稀ですが、デプロイメントターゲットがまだそのラインより下に届くなら、GCD が移植性のある選択肢です。\n* **コードがすでに動いていて、まだ移行していないとき。**  \n動いている GCD はバグではありません。安定したコードを単に近代化するためだけに書き直すのは、ユーザーに見える利点のないままリスクを増やします。すでに変更を加えている場所で移行し、あちこち一度にではありません。\n\nこれについて正直であることが大切です。目標は*正しく、保守しやすい*コードであって、それ自体が目的の 100% モダンなコードベースではありません。\n\n[前へ](@previous)  |  5 / 8 ページ  |  [次へ: 実践的な移行戦略](@next)";
