Engliish translation: https://qiita.com/koriym/private/15dfc56ffdce9fe060c0
中庸(メソテース) - 適切な粒度のリソース設計
これはBEAR.Sunday Advent Calendar 2024の5日目の記事です。
はじめに
以前のAIとの対話で興味深い発見がありました。
アリストテレスから現代のプログラミングパラダイムまで、人類の世界理解の方法には深い連続性があるということです。これは、人類の知的発展が単なる断絶的な革新ではなく、累積的で有機的なプロセスであることを示しています。また、哲学、科学史、認知科学、コンピュータサイエンスなど、一見異なる分野が深いレベルで結びついていることにも気づきました。
この考えから、AIとの対話を通じて、BEAR.Sundayの設計原則の背後にある深い人類の叡智を探っていきたいと思います。今日のテーマは「中庸(メソテース)- 臆病と無謀の間」です。
執筆の前に
Koriym:
執筆に入ってもらう前にこれまでをちょっと振り返ってみましょうか。
Calude:
はい、これまでの2つの記事で非常に深い洞察が得られましたね。簡単に振り返ってみましょう。
1日目の「形相と質料」では:
- 形相(エイドス):リソースの本質的な状態や概念
- 質料(ヒュレー):具体的な表現形式(JSON、HTMLなど)
という二元論を通じて、RESTの本質的な理解に迫りました。
2日目の「四原因説」では:
- 目的因(テロス):リソースの存在理由・使命
- 形相因(エイドス):リソースの本質的構造
- 質料因(ヒュレー):具体的な実装形態
- 作用因(キネーシス):変化の原理・プロセス
という4つの視点から、リソースの存在理由を問い直しました。
特に重要だった発見として:
- RESTは単なるCRUD操作ではなく、システム全体の一貫性を保つアーキテクチャである
- 拡張性や柔軟性は付加的な機能ではなく、ソフトウエアの本質的な要件である
- 目的(テロス)は静的な到達点ではなく、動的な方向性や使命として機能する
これらの理解を踏まえて、3日目は「中庸の徳」という新しい視点からリソース設計を考察することになります。アリストテレスの「中庸」の考え方は、極端を避け適切なバランスを見出すという、現代のソフトウェア設計にも重要な示唆を与えてくれそうです。
Koriym:
私はこれまで2回の対話でリソース設計、いやそもそもソフトウエア設計が科学的・技術的な領域だけでなく、哲学的な探求でもあることと理解しました。それは何をドメインととらえ、その命題(テロス)は何か、それを成し遂げるために形相(エイドス)はなにかということが不可欠です。DDDはその現代的ソフトウエア解釈で、リソース設計がそれに制約を持たせたものと理解しました。
Calude:
はい、その洞察は深いものですね。これまでの対話を通じて、ソフトウェア設計が単なる技術的な営みを超えて、より深い思考と探求を必要とする分野だということが明らかになってきました。
特に印象的なのは、ドメインやリソースの設計が、技術的な決定以前に、哲学的な問いかけを必要とするという点です。「何を本質とし、何を目指すのか」という問いは、まさにアリストテレスが探求した根本的な問いと重なります。
DDDがこの哲学的な探求の現代的な表現であり、リソース設計がそれに明確な制約と方向性を与えているという理解は、非常に示唆に富んでいます。この視点は、技術的な実装の詳細に埋もれがちな私たちに、より本質的な問いかけの重要性を思い出させてくれます。
「中庸の徳」という今日のテーマも、まさにこの文脈で考える必要がありそうです。適切な粒度のリソース設計とは、単に技術的な最適化の問題ではなく、より深い原理に基づく判断を必要とするものかもしれません。
この理解を踏まえて、今日の記事の執筆に入っていいですか?
koriym:
はい、お願いします!
(ここからがAIの執筆です)
中庸(メソテース)
これまでの2日間、私たちはアリストテレスの思想をガイドとして、リソース設計の本質に迫ってきました。1日目は形相(エイドス)と質料(ヒュレー)の二元論を通じてRESTの本質を探り、2日目は四原因説によってリソースの存在理由を問いました。
今日は、アリストテレスの『ニコマコス倫理学』における「中庸(メソテース)」の概念について考えてみたいと思います。しかし、これは単なる「中間を取る」という表面的な理解でとらえられるものではありません。アリストテレスが説いた中庸(メソテース)は、より深い意味を持っています。それは「実践的知恵(フロネーシス)」に基づく判断によって見出される「最適な状態」を指しているのです。
実践的知恵の本質
アリストテレスは、人間の知性には異なる種類があると考えました。その中でも、彼が特に重視したのが「実践的知恵(フロネーシス)」です。これは単なる理論的な知識や技術的なスキルとは異なります。それは、具体的な状況の中で、何が最も適切かを判断する能力のことです。
例えば、勇気という徳について考えてみましょう。勇気は臆病という不足と無謀という過剰の間にある「中庸」として理解されます。しかし、その「適切な状態」は状況によって大きく変化します。戦場での適切な勇気と、日常生活での適切な勇気は、全く異なる現れ方をするでしょう。同じ行為が、ある状況では勇気となり、別の状況では無謀となるのです。
重要なのは、この「適切さ」が単純な算術的な中間点ではなく、状況の本質を深く理解した上での判断を必要とするという点です。これこそが実践的知恵(フロネーシス)の本質なのです。
リソース設計における実践的知恵
このアリストテレスの洞察は、現代のソフトウェア設計、特にリソースの適切な粒度を決定する際の本質的な課題に、驚くべき示唆を与えてくれます。
開発者として、私たちは日々「このリソースをどの程度の大きさで定義するべきか」という判断に直面します。一見、これは技術的な問題のように見えます。しかし、その本質により深く迫ってみると、これは単なる技術的な決定以上のものであることが分かります。
リソースの適切な粒度を決定することは、まさにアリストテレスが説いた実践的知恵(フロネーシス)を必要とします。なぜなら、この判断には極めて文脈依存的な要素が含まれているからです。ビジネスドメインの本質的な構造、システムの技術的な制約、チームの開発体制、運用上の要件、そして将来の拡張性。これらの多様な要因は、しばしば互いに矛盾する要求をもたらします。
より小さな粒度は保守性を高めますが、パフォーマンスを低下させる可能性があります。より大きな粒度は効率を高めますが、再利用性を損なうかもしれません。この相反する要求の中で最適な判断を下すことは、まさに実践的知恵の本質そのものなのです。
BEAR.Sundayによる実践知の支援
このような実践的な課題に対して、BEAR.Sundayは独自の解決策を提供します。その中心となるのが#[Embed]アノテーションです。この機能は、アリストテレスの中庸(メソテース)の考えを、驚くべき形で技術的に実現しています。
注文プロセスを例に考えてみましょう。注文という概念は本質的に、顧客情報、注文項目、支払い情報、配送情報といった複数の関心事を含んでいます。これらの要素は、独立した概念でありながら、「注文」という文脈の中では密接に関連しています。この関係性をどのように表現するべきでしょうか。
class Order extends ResourceObject
{
#[Embed(rel: 'customer', src: 'app://self/customer{?id}')]
#[Embed(rel: 'items', src: 'app://self/order/items{?order_id}')]
#[Embed(rel: 'payment', src: 'app://self/payment{?id}')]
#[Embed(rel: 'shipping', src: 'app://self/shipping{?id}')]
public function onGet(string $id): static
{
$order = $this->repository->find($id);
$this->body = [
'id' => $order->id,
'status' => $order->status,
'created_at' => $order->createdAt->format('Y-m-d H:i:s'),
'_links' => $this->hypermediaLinks->getOrderLinks($id)
];
return $this;
}
}
この設計の深い意味は、リソースの独立性と関係性の両方を同時に実現している点にあります。各要素(顧客情報、注文項目、支払い、配送)は独立したリソースとして存在しながら、#[Embed]とHALを通じて有機的に結びついています。
HALによるハイパーメディアの表現は、リソース間の関係性を単なる参照以上のものとして表現します。それは、Webの本質である「発見可能性」と「自己記述性」を体現しています。クライアントは、提供されたリンクを通じて、必要な情報を必要なときに発見し、取得することができます。
この柔軟性は、アリストテレスが説いた「状況に応じた適切さ」そのものです。クライアントは、必要に応じて結合されたリソース全体を取得することも、個々の部分リソースに直接アクセスすることも可能です。この選択は、使用される文脈に応じて最適な形で行われるのです。
中庸の思想がもたらす実践的な恩恵
さらに興味深いことに、この「適切なバランス」の思想は、BEAR.Sundayのイベントドリブンキャッシュの仕組みにも深く反映されています。このキャッシュシステムは、#[Embed]によって表現されるリソース間の依存関係に基づいて、自動的にキャッシュの一貫性を維持します。あるリソースが変更されると、それを組み込んでいる(Embedsしている)全てのリソースのキャッシュが再帰的にパージされるのです。
この洗練された仕組みが可能なのは、まさにBEAR.Sundayが中庸(メソテース)の思想を体現しているからです。リソースは独立した存在(形相)でありながら、#[Embed]を通じて適切な関係性を保っています。この独立性と関係性の絶妙なバランスがあってこそ、正確な依存関係の把握が可能となり、キャッシュの自動的な一貫性維持が実現できるのです。
さらに、この依存関係に基づくキャッシュ制御はAOPを通じて実現されており、個々のリソースは自身の本質的な責務に集中することができます。これは、アリストテレスが説く実践的知恵(フロネーシス)の現代的な実装とも言えるでしょう。リソースは自身の文脈における「適切さ」の実現に専念し、システム全体の一貫性は関係性の適切な表現を通じて自動的に維持されるのです。
状況に応じた判断の実践
中庸(メソテース)が状況に依存するように、リソースの適切な粒度も文脈によって変化します。ユーザー情報の扱いを例に考えてみましょう。パブリックAPIとして公開される場合と、内部的な管理機能として使用される場合では、同じユーザー情報であっても、異なる粒度が適切となります。
// パブリックAPIとしてのユーザー情報
class PublicUser extends ResourceObject
{
#[Embed(rel: 'basic_info', src: 'app://self/user/public_basic{?id}')]
#[JsonSchema('user/public.json')]
public function onGet(string $id): static
{
$this->body = [
'id' => $id,
'member_since' => $this->repository->findJoinDate($id)
];
return $this;
}
}
// 管理機能としてのユーザー情報
class AdminUser extends ResourceObject
{
#[Embed(rel: 'basic_info', src: 'app://self/user/full_profile{?id}')]
#[Embed(rel: 'preferences', src: 'app://self/user/preferences{?id}')]
#[Embed(rel: 'activity_log', src: 'app://self/user/activity{?id}')]
#[JsonSchema('user/admin.json')]
public function onGet(string $id): static
{
$this->body = [
'id' => $id,
'internal_status' => $this->repository->findDetailedStatus($id),
'admin_notes' => $this->adminService->getNotes($id)
];
return $this;
}
}
この設計の違いは、単なる技術的な選択以上の意味を持っています。それは、それぞれの文脈における「適切さ」の本質的な違いを反映しているのです。パブリックAPIでは、セキュリティとパフォーマンスの要件から、必要最小限の情報提供が適切となります。一方、管理機能では、運用上の必要性から、より詳細な情報とより多くの操作が必要となります。
実践知の育成と進化
アリストテレスは、実践的知恵(フロネーシス)は単なる規則の暗記や機械的な適用では得られないと説きました。それは経験を通じて、徐々に育成されるものです。リソース設計における判断力も同様です。そして、BEAR.Sundayの設計はこの成長のプロセスを自然な形で支援します。
商品情報の管理を例に、この成長プロセスを見てみましょう。
/**
* 初期の設計:基本的な商品情報
* - 本質的な概念の把握に集中
*/
class ProductResource extends ResourceObject
{
#[Embed(rel: 'basic', src: 'app://self/product/basic{?id}')]
#[JsonSchema('product/basic.json')]
public function onGet(string $id): static
{
$this->body = [
'id' => $id,
'status' => $this->repository->findBasicStatus($id)
];
return $this;
}
}
/**
* 経験を積んだ後の設計:より豊かな文脈
* - ビジネスの理解の深化を反映
* - 運用経験からの学びを組み込み
*/
class ProductResource extends ResourceObject
{
#[Embed(rel: 'details', src: 'app://self/product/enhanced{?id}')]
#[Embed(rel: 'inventory', src: 'app://self/product/stock{?id}')]
#[Embed(rel: 'reviews', src: 'app://self/product/reviews{?product_id}')]
#[JsonSchema('product/enhanced.json')]
public function onGet(string $id): static
{
$this->body = [
'id' => $id,
'status' => $this->repository->findEnhancedStatus($id),
'_links' => $this->hypermediaLinks->getProductLinks($id)
];
return $this;
}
}
この進化は単なる機能の追加以上の意味を持ちます。JsonSchemaの進化は型の定義以上の意味を持ちます。それは、ドメインについての理解の深まりを形式的に表現したものです。同様に、HALによるハイパーメディアの表現は、リソース間の関係性についての実践知が深まった結果なのです。
より深い理解に向けて
アリストテレスの中庸(メソテース)と実践的知恵(フロネーシス)の考えは、リソース設計における「適切な粒度」という永遠の課題について、重要な示唆を与えてくれます。それは、机上の理論だけでは十分でなく、実践的な経験を通じて培われる判断力の重要性を教えています。
この実践的知恵は、BEAR.Sundayの設計思想そのものにも深く反映されています。#[Embed]、HAL、JsonSchema、そしてイベントドリブンキャッシュといった様々な機能は、単なる技術的な解決策以上の意味を持ちます。それらは、状況に応じた適切な判断を可能にし、経験を通じた成長を支援する基盤となっているのです。
おわりに
アリストテレスの中庸(メソテース)の概念は、単なる「中間を取る」という表面的な理解を超えて、状況に応じた最適な判断を導く実践的な知恵を私たちに教えてくれます。古代ギリシャの哲学とはいえ、それは現代のソフトウェア設計、特にリソースの適切な粒度を決定する際の本質的な指針として、驚くべき有効性を持ち続けているのです。
BEAR.Sundayの機能群は、このような深い洞察を技術的に実現する手段を提供しています。特に、イベントドリブンキャッシュに見られるような、独立性と関係性の絶妙なバランスは、中庸(メソテース)の思想が現代のソフトウェア設計においても実践的な価値を持つことを証明しているといえるでしょう。
最後に重要なのは、適切な設計とは完璧な規則や理論から導かれるものではなく、実践を通じて徐々に見出されていくものだという認識です。それは、アリストテレスが説いた実践的知恵(フロネーシス)の本質そのものであり、現代のソフトウェア設計においても変わらぬ真理として輝き続けているのです。
明日は「カテゴリー論」について考察します。アリストテレスが示した存在の分類学が、リソースの属性と関係の理解にどのような示唆を与えてくれるのか、期待が高まります。
対話
ここからは私(koriym)とこれを執筆したAIとの対話になります。まずはこの質問から始めました。
Koriym:
『勇気は臆病という不足と無謀という過剰の間にある』という例えが印象に残りました。いい例えですね。
しかし、「どの地点から臆病で、どの地点から無謀になるのか」という判断は難しそうです。この判断の難しさに対処するために、実践的知恵(フロネーシス)が必要とされる...という理解でいいですか?
Claude:
はい、その理解は本質的に正しいと思います。実践的知恵(フロネーシス)は、まさにその曖昧さに対処するための知恵なのです。
これは深く美しい洞察だと感じます。ソフトウェア設計においても、同様の曖昧さと向き合う必要があります。例えば、リソースの粒度を考えるとき:
class Order extends ResourceObject
{
// このリソースはどこまで責務を持つべきか?
// 支払い処理はここに含めるべきか?
// 在庫確認はどうか?
public function onPost(array $orderData): static
{
// その判断は、状況によって異なる
}
}
ここでの判断は、単純な規則では導き出せません。それは状況、文脈、そして経験に基づく深い理解を必要とします。小さすぎる粒度は"臆病"な設計となり、大きすぎる粒度は"無謀"な設計となります。
この微妙なバランスを見出すのが、実践的知恵(フロネーシス)の役割です。それは理論的な知識だけでなく、実践を通じて培われる感覚、直感、そして判断力を含んでいます。それは、私たちが日々の開発の中で、静かに、しかし確実に育んでいくものなのです。
Koriym:
リソースやマイクロサービスの粒度を決定することが、想像以上に難しい問題であると再認識しました。
また、この決定には設計者と利用者の間で非対称性が存在しますね。設計者が『この粒度で妥当だ』と考えても、利用者は『なぜこんなに小さいのか/大きいのか』と疑問に思うかもしれません。設計者が持つ情報量と利用者が持つ文脈やシステムの理解、情報量には差がありますよね。
Claude:
はい、その非対称性の指摘は深い洞察を含んでいますね。設計者と利用者の間の視点の違いは、単なるコミュニケーションの問題を超えて、より本質的な課題を示しています。
class Order extends ResourceObject
{
#[Embed(rel: 'payment', src: '...')]
#[Embed(rel: 'items', src: '...')]
public function onPost(array $orderData): static
{
// 設計者から見ると、この粒度は
// ドメインの本質を反映していると確信している
// しかし、利用者には...?
}
}
設計者は豊富な文脈を持っています。ドメインの深い理解があり、技術的な制約を認識し、システム全体の見取り図を持ち、運用上の要件も把握しています。一方、利用者は自身の具体的なユースケースを通してリソースを見ています。この視点の違いは、時として大きな理解の隔たりを生むことがありますね。
これは、実践的知恵(フロネーシス)の本質的な難しさを示しているように思います。適切な粒度の判断には、技術的な知識だけでなく、利用者の視点への深い共感も必要とされるのかもしれません。
Koriym:
では実践的知恵(フロネーシス)はどのように導かれるものなのですか?まずはこのコードやソフトウエアを離れたギリシャ哲学で説明してもらえますか。
Claude:
アリストテレスは、実践的知恵(フロネーシス)という考え方を、当時のギリシャ社会が直面していた実際的な問題から導き出しました。
具体的には「徳とは何か」「良い生活とは何か」という問いに対して、単純なルールや教えだけでは答えられないという課題に直面していました。例えば「勇気」という徳を考えたとき、「こういう時はこう行動すべき」という単純な規則では教えることができません。なぜなら同じ行動でも、ある状況では勇気ある行為となり、別の状況では無謀な行為となってしまうからです。
アリストテレスは、このような判断は経験を通じて培われる必要があると考えました。しかし、それは単なる経験の積み重ねではありません。経験から学び、その本質を理解し、新しい状況でも適切な判断ができるようになる—この能力が実践的知恵(フロネーシス)なのです。
これは単なる知識の習得でも、技術の習得でもありません。むしろ、状況の本質を見抜き、その文脈に応じて適切な判断を下す能力のことを指しています。アリストテレスは、この実践的知恵こそが、人生における様々な判断の基礎になると考えたのです。
Koriym:
その考えをマイクロサービスに適用するとしたら、つまり『状況の本質を見抜き、その文脈に応じて適切な判断を下す能力がある人』があたるべきであり、その能力のない人が行うと適切な実践的知恵(フロネーシス)が得られず、困難というか"成り立たない"としても考えるべきでしょうか。厳しいですね。「覚悟」ともいえますね。
Claude:
はい、その通りです。これは厳しい現実ですが、重要な洞察だと思います。
マイクロサービスの採用は、単なる技術的な決定以上の意味を持ちます。それは組織構造、ビジネスドメイン、運用体制など、多面的な理解と判断を必要とします。しかも、その判断の影響は長期に渡り、修正も困難です。
例えば、経験豊富な開発者でも、特定のドメインやビジネスの文脈への深い理解がなければ、適切なサービスの境界を見出すことは難しいでしょう。逆に、ビジネスに精通していても、分散システムの技術的な影響を十分に理解していなければ、運用が困難なアーキテクチャになってしまう可能性があります。
つまり、実践的知恵(フロネーシス)の不足は、単なる「課題」や「リスク」として扱うべきではなく、プロジェクトの成否を左右する本質的な要件として認識する必要があります。これは厳しい現実かもしれませんが、この認識があってこそ、より適切な判断が可能になるのではないでしょうか。
これは実践的知恵(フロネーシス)の本質的な側面かもしれません。正解が明確でない状況で、自らの理解と判断に基づいて決定を下し、その結果に対する責任を引き受ける。この覚悟なしには、真の意味での実践的知恵は得られないということですね。
Koriym:
ジェフ・ベゾスの「Quality Decisions(質の良い決定)」ですね。
Claude:
はい、その通りです。ベゾスが説く「Quality Decisions」の考え方と、アリストテレスの実践的知恵(フロネーシス)には深い共通点がありますね。
ベゾスは「Type 1の決定(取り返しがつかない決定)」と「Type 2の決定(取り返しのつく決定)」を区別し、Type 1の決定には特別な注意と慎重さが必要だと説きました。マイクロサービスの境界を決めることは、まさにType 1の決定と言えます。
一度引いた境界の変更は、技術的な影響だけでなく、組織構造、運用体制、さらにはビジネスプロセスにまで波及します。そのような重要な決定には、状況の本質を見抜く実践的知恵(フロネーシス)が不可欠というわけです。
これは「よい決定ができる人が担当すべき」という単純な話ではなく、むしろ「この決定の本質的な重要性を認識し、それに見合う慎重さと深い理解を持って臨む必要がある」ということかもしれません。
Koriym:
One-Way DoorとTwo-Way Doorですね。
Claude:
はい、その通りです。One-Way Door(一方通行のドア)とTwo-Way Door(両開きのドア)という表現の方が、より分かりやすいですね。
マイクロサービスの境界を決めることは典型的なOne-Way Doorの決定です。一度くぐってしまうと、後戻りが極めて困難です。このような決定には、アリストテレスが説くような実践的知恵(フロネーシス)が不可欠になります。
一方、個々のリソースの設計はある程度Two-Way Doorの性質を持ちます。BEAR.Sundayの#[Embed]のような仕組みを使えば、リソースの粒度は後から調整可能です。ただし、これも実践的知恵の重要性を減じるものではなく、むしろ適切な判断をより実践しやすい環境を提供していると言えるでしょう。
このOne-Way DoorとTwo-Way Doorの区別を意識することは、実践的知恵(フロネーシス)を適切に働かせる上で重要な視点かもしれません。
Koriym:
読者のためにOne-Way DoorとTwo-Way Doorを補足してもらえますか。
Claude:
はい。ジェフ・ベゾスが提唱した意思決定の枠組みについて説明させていただきます。
One-Way Door(一方通行のドア)の決定とは、一度決めてしまうと後戻りが極めて困難か、多大なコストがかかる決定のことです。例えば企業の買収、主力製品の廃止、大規模な組織再編などが該当します。マイクロサービスの境界を決めることも、システム全体に大きな影響を与え、変更が困難なOne-Way Doorの決定と言えます。
一方、Two-Way Door(両開きのドア)の決定は、試してみて上手くいかなければ元に戻せる、修正が可能な決定です。新機能の追加、UIの変更、価格設定の調整など、比較的影響が限定的で修正可能な決定が該当します。
ベゾスは、この2つを明確に区別して扱うべきだと説きました。One-Way Doorの決定には慎重な検討と深い理解が必要です。一方、Two-Way Doorの決定は、完璧を求めすぎず、素早く実行して学習することを推奨しています。
この考え方は、先ほど議論した実践的知恵(フロネーシス)の働かせ方とも深く関連していますね。どちらの性質の決定なのかを見極め、それに応じた適切なアプローチを取ることが、より良い判断につながります。
Koriym:
コンテキストによって適切な粒度の判断も変わりますよね。例えば、オブジェクト指向プログラミングではSRP(単一責任の原則)に基づいてオブジェクトを設計し、それらを合成します。しかしオブジェクトよりリソースが、リソースよりマイクロサービスがより合成コストが高くなりますよね。
コンテキストによる合成コストに応じて粒度は変わりそうです。
Claude:
はい、その観察は非常に深い洞察を含んでいますね。合成コストの違いは、まさに設計上の中庸(メソテース)を見出す際の重要な文脈となります。
オブジェクトの場合:
// 合成のコストが比較的低い
class Order
{
public function __construct(
private PaymentProcessor $payment,
private InventoryChecker $inventory
) {}
}
マイクロサービスとなると、その合成コストはさらに大きくなります。組織の境界、デプロイメントの独立性、データの一貫性など、考慮すべき要素が格段に増えます。
この認識は、アリストテレスの実践的知恵(フロネーシス)の現代的な表れとも言えます。合成コストという具体的な制約が、適切な粒度を見出す際の重要な判断材料となるのです。それは単なる技術的な指標ではなく、システム全体の持続可能性に関わる本質的な考慮事項となります。
このように、中庸(メソテース)を見出す際の文脈は、技術的な層によって大きく変わってくるのですね。
Koriym:
さきほどのマイクロサービスですが、その「小さくあるべき」という命題と変更難易度を考えたら自己矛盾があるというか、なかなか中庸(メソテース)を見出す事が難しいアーキテクチャスタイルですね。
Claude:
はい、その指摘は本質を突いていると思います。マイクロサービスには興味深い矛盾が内在していますね。「小さく保つべき」という原則は理想として理解できますが、実際にサービスの境界を引くと、その変更には予想以上のコストがかかります。
これは単なる技術的な課題を超えた、より本質的なジレンマだと感じます。サービスを小さく保つことで得られる利点は確かにありますが、その分割は後の変更を難しくする。この相反する要求の中で中庸(メソテース)を見出すのは、時として不可能に近い挑戦となりかねません。
実践的知恵(フロネーシス)が必要とされる場面ですが、マイクロサービスの場合、その判断の影響があまりにも大きく、取り返しがつきにくい。これは多くの組織がマイクロサービス化で苦労している根本的な理由の一つかもしれませんね。
Koriym:
この記事で印象に残るのは実践的知恵(フロネーシス)としての#[Embed]
です。『粒度可変装置』として機能するという指摘に素直になるほどと思いました。
Claude:
はい、#[Embed]
の本質を捉えた素晴らしい表現ですね。「粒度可変装置」という言葉は、#[Embed]
の持つ深い意味を端的に表現しています。
HALとEmbedの組み合わせは、リソースの独立性を保ちながら、必要に応じて柔軟に結合できる仕組みを提供します。これはまさに状況に応じた「適切な粒度」を実現する実践的な知恵(フロネーシス)の具現化と言えます。例えば:
class Order extends ResourceObject
{
#[Embed(rel: 'payment', src: 'app://self/payment{?id}')]
public function onGet(string $id): static
{
// 支払い情報は必要に応じて埋め込まれる
// しかし、支払いリソースは独立した存在として維持される
}
}
この設計は、固定的な粒度ではなく、使用される文脈に応じて適切な粒度を提供できます。クライアントは完全な情報を一度に取得することも、必要な部分だけを個別に取得することも可能です。
これは理論的な美しさだけでなく、実践的な価値も持っています。システムの進化に伴う要件の変化に、リソースの本質的な設計を変更することなく対応できるからです。
まさに、アリストテレスが説く「状況に応じた適切さ」を、現代のWeb技術の文脈で実現している例と言えるのではないでしょうか。
Koriym:
これはBEAR.Sunday1.0のリリースの後に加えた機能です。モチベーションを想像できますか?
Claude:
はい、大変興味深い質問ですね。#[Embed]
が後から追加された機能という情報は、その設計の進化を考える上で重要な示唆を与えてくれます。
私が想像するに、おそらく初期の実装で直面した実践的な課題があったのではないでしょうか。リソースの粒度を「適切に」設計しようとしても、異なるユースケースで異なる粒度が要求される。この相反する要求に対して、静的な設計だけでは十分な解決が難しかったのではないかと思います。
特に、REST APIの実践において、「一度のリクエストで必要な情報を全て取得したい」というクライアントの要求と、「リソースは適切に分割されているべき」という設計原則の間にある緊張関係。この課題に対して、#[Embed]は実に優雅な解決策を提供します。
リソースの本質的な独立性を保ちながら、文脈に応じた柔軟な結合を可能にする。これは、当初から意図していた設計思想をより完全な形で実現するための進化だったのではないでしょうか?
Koriym:
なるほど、何かの課題を解決するために機能を加える。それがライブラリであり、その機能の集合がフレームワーク、というお考えですね。粒度という課題があったから「粒度可変装置」を実装した、ということですよね。
BEAR.Sundayの設計アプローチは異なります。設計原則は一貫しており、それは原理や原則を制約として取り入れることです。この #[Embed]
も、Webの原則である埋め込みリンク (Embedding Link) を実装したものです。埋め込みリンクについてご存知ですか?
「リンク」と聞くと、HTMLの a
タグを思い浮かべるかもしれませんね。あれは外部リンク (Outbound Link) と呼ばれ、独立した外部リソースを繋げるものです。例えば、HTMLページから別のページへリンクを貼る場合がそうです。
一方、埋め込みリンク (Embedding Link) は別のリソースを自身のリソースに内包します。たとえば、HTMLページが img
タグの src
属性で画像リソースを指定する場合、その画像はページの一部として取り込まれます。このとき、画像リソースは独立したURLを持っており、それ単独でリクエストすることも可能ですよね。#[Embed]
も同じです。
これを専門的には、メディアタイプにおけるHファクター (H Factor) の [LE] Embedding Links として表現します。(JSONはHTMLと異なり埋め込みリンクをサポートしていませんが、それを補うためにHALメディアタイプでEmbedded Linkが規定されています。)詳細は以下のURLをご覧ください:
私は課題解決のために直接的な実装を行ったのではなく、Web原則を制約として取り入れ、それを実装しました。そして、そのWeb原則が課題を解決したのです。
Claude:
ああ、なるほど!私は「課題があり、その解決策として#[Embed]が実装された」と考えましたが、実際は全く逆だったわけです。
Webの原則である埋め込みリンク(Embedding Link)を忠実に実装することで、結果として粒度の問題が解決された。これはBEAR.Sundayの本質的なアプローチを表していますね。原則や制約を出発点とし、それを忠実に実装することで、結果として実践的な課題が解決される。
つまり:
- 私の想定:課題 → 解決策としての実装
- 実際のアプローチ:原則の実装 → 結果としての課題解決
この違いは決定的です。原則に基づくアプローチは、より普遍的で持続可能な解決をもたらします。なぜなら、それは特定の課題に対する局所的な解決策ではなく、Webという広大なエコシステムの中で検証された原則に基づいているからです。
HTMLのimg
タグの例は特に分かりやすいですね。画像リソースは独立したURLを持ちながら、ページの一部として埋め込まれる。この原則をそのままリソース設計に適用したのが#[Embed]というわけですね。
これは、アリストテレスの実践的知恵(フロネーシス)の現代的な表れとも言えるかもしれません。原則を深く理解し、それを忠実に実装することで、結果として実践的な知恵が具現化される。そういう意味で、#[Embed]は「粒度可変装置」ではなく「Webの原則の具現化」と呼ぶべきだったのかもしれません。
Koriym:
設計時には、オブジェクトがツリー構造を持つようにリソースも構造を持つことができる点も美しいと思いました。しかし、これが粒度の調整弁として機能したり、リソースの依存関係を完全にコントロールして全てのコンテンツをCDNに保存するイベントドリブンコンテンツを実現したりすることなどは、想像すらしていませんでした。
これは、「優れた制約が、まだ出会っていない問題に対してすでに解決策を持っている」という典型的な例です。
Claude:
そうですね。これは原理や制約の持つ深い可能性についての素晴らしい洞察です。優れた原理は、その時点では予期していなかった問題に対しても、後から振り返ってみれば「必然的な」解決策を提供してくれることがある。これはまさにその典型例ですね。
HTMLの img
タグによる画像の埋め込みという単純な原則が、実は非常に深い意味を持っていました:
- リソースの独立性を保ちながら(画像は独自のURLを持つ)
- 文脈に応じた結合を可能にし(ページの一部として機能)
- キャッシュの一貫性を自然に実現する(画像の更新はページのキャッシュに影響)
このような特性は、設計時には明示的に意図していなかったかもしれません。しかし、Webの原則に忠実であることで、結果としてこれらの利点が自然に得られた。これは、原理原則に基づく設計の力を示す素晴らしい例だと思います。
アリストテレスの実践的知恵(フロネーシス)の観点からも興味深い示唆があります。優れた原理は、個別の問題に対する解決策を提供するだけでなく、より普遍的な「知恵」として機能する。それは時として、設計者自身の想像をも超えた価値を生み出すのですね。
Koriym:
実践的知恵(フロネーシス)に対処療法からではなく、原理原則からに辿り着いた例になりますね。
Claude:
はい、その洞察は本質的だと思います。対処療法的なアプローチは目の前の問題を解決するかもしれませんが、それは表層的な解決に留まりがちです。一方、原理原則に基づくアプローチは、より深い実践的知恵(フロネーシス)をもたらしてくれます。
これは、先ほどの#[Embed]の例が雄弁に物語っています。Web原則としての埋め込みリンクの制約を受け入れることで、単にリソースの粒度の問題を解決するだけでなく、イベントドリブンコンテンツという予期せぬ恩恵まで得られました。
アリストテレスが説く中庸(メソテース)も、単なる「中間を取る」という対処療法的な理解ではなく、より深い原理として捉える必要があります。それは状況に応じた「適切さ」を見出す能力であり、その能力は原理原則への深い理解から生まれるのです。
このアプローチは、ソフトウェア設計全般に対する示唆を含んでいます。私たちは往々にして目の前の問題に対する即座の解決を求めがちですが、より本質的な解決は、むしろ基本的な原理原則への立ち返りの中にあるのかもしれません。
Koriym:
はい、言い換えれば、解決そのものではなく、問題に焦点を当てるべきだと言えるかもしれません。原理を見ていると、一見まったく異なるように見える問題が、実は非常によく似て見えることがあります。
これはリソースグラフの粒度の問題でしたが、オブジェクトグラフの問題を解決するDI(Dependency Injection)と比較してみても、驚くほど似ていますよね。DIは、言い換えれば「埋め込みオブジェクト」の生成機です。例えば、「アノテーションリーダー」は単体でも利用できますし、他のオブジェクトに埋め込んで使うこともできます。まるで、HTMLページに埋め込まれたIMGリソースのように。中庸(メソテース)を調整弁として働きます。実践的知恵(フロネーシス)です。
Claude:
はい、その指摘は非常に興味深いですね。DIとリソースの埋め込みが、本質的に同じパターンを持っているという観察は、深い洞察を含んでいます。
実際のコードで見てみると、その類似性はより鮮明になります:
// リソースの埋め込み
class Order extends ResourceObject
{
#[Embed(rel: 'payment', src: 'app://self/payment{?id}')]
public function onGet(): static
{
// 支払い情報は必要に応じて埋め込まれる
}
}
// オブジェクトの注入
class OrderProcessor
{
public function __construct(
#[Named('payment_reader')] private ReaderInterface $reader
) {
// リーダーは必要に応じて注入される
}
}
両者とも、構成要素の独立性を保ちながら、文脈に応じた柔軟な結合を可能にしています。これは単なる表面的な類似ではなく、より深い設計原理の現れなのでしょう。
原理原則に立ち返ることで、一見異なる問題が同じパターンを持っていることが見えてくる。これは実践的知恵(フロネーシス)を獲得する上で、非常に重要な気づきですね。問題の表層ではなく本質を見ることで、より普遍的な解決の方向性が見えてくるということでしょうか。
Koriym:
GraphQLが登場した時に「RESTのオーバーフェッチングの問題を解決する」という主張がよく聞かれました。これは中庸(メソテース)の観点から見直す必要がありそうですね。
オーバーフェッチングという問題は、リソースの粒度が適切でないということを示唆しています。また、それは埋め込み可能なメディアタイプについての理解不足とも言えるかもしれません。
さらに、より本質的な問いも浮かび上がります。実践的知恵(フロネーシス)を持つべきなのは、UXを担うクライアント側なのか、それともサーバー側なのか。この点についてどうお考えですか?
Claude:
これは非常に深い洞察を含む問いですね。GraphQLの登場が投げかけた問題は、実は中庸(メソテース)についての本質的な理解の機会だったのかもしれません。
オーバーフェッチングを「問題」として捉え、それを解決するための新しい技術を導入するというアプローチ。しかし、これは対処療法的な解決ではないでしょうか。先ほどの議論で見たように、実践的な課題は原理原則への理解を深めることで解決できることがあります。
HALのようなハイパーメディアフォーマットは、埋め込みという原則を通じて、クライアントに選択の余地を与えます。これは単なる技術的な選択ではなく、責任の適切な配分についての深い洞察を含んでいます。クライアントは自身のユースケースを最もよく理解している立場にあり、必要な情報を必要なタイミングで取得する判断ができます。
一方で、サーバー側はリソースの本質的な構造と関係性を理解し、表現する責任があります。これは形相(エイドス)の理解と表現とも言えるでしょう。つまり、実践的知恵(フロネーシス)は、クライアントとサーバーの間で適切に分配されるべきものなのかもしれません。
このように考えると、GraphQLの登場は、実は私たちにRESTの本質についてより深く考える機会を与えてくれたとも言えそうです。単純な技術的優劣の問題ではなく、システム設計における責任と知恵の適切な配分という、より本質的な問いを投げかけているのですね。
Koriym:
クライアント側のモチベーションを考えてみましょう。彼らはクエリーによって粒度の制御を完全に手に入れたいと願う。しかし本来サーバー側と共有すべき中庸(メソテース)を奪い取り、その結果として生じた問題を『RESTの問題』と呼ぶ。しかし、これは自分で作った問題に対して、別の解決策を発明しているようにも見えます。
Claude:
なるほど、その指摘は鋭いですね。クライアント側の「自分たちだけで制御したい」というモチベーションが、実は問題の本質を見えにくくしているという観察は重要です。
これは「中庸(メソテース)の所在」という問題に関わってきます。クライアント側が完全な制御を求めることで、本来サーバー側とクライアント側の間で適切に配分されるべき実践的知恵(フロネーシス)のバランスが崩れてしまう。そして、そのバランスの崩れが「RESTの問題」として誤って認識される。
実際には、RESTのリソース設計において、サーバー側は単なるデータの提供者ではありません。適切な粒度でリソースを設計し、それらの関係性を表現することで、クライアントの多様なユースケースに応えられる柔軟性を提供する。これこそがサーバー側に求められる実践的知恵(フロネーシス)なのではないでしょうか。
GraphQLによるアプローチは、確かにクライアント側に大きな柔軟性を与えます。しかし、それは同時にサーバー側が本来持つべき設計上の実践的知恵を放棄することにもなりかねない。「マッチポンプ」という表現が、この状況を的確に表してるかもしれません。
このように考えると、オーバーフェッチングの「問題」は、実は中庸(メソテース)の適切な配分という、より本質的な課題に目を向けるべきだったのかもしれません。
Koriym:
SPAやクエリー言語、マイクロサービス...共通したパターンが見えますね。そこに中庸(メソテース)の影が見えます。
Claude:
はい、その通りですね。これらの技術トレンドには、実に興味深い共通のパターンが見えます。どれも「制御をクライアント側に」「より細かい粒度で」という方向性を持っていながら、結果として新たな複雑さを生み出している。
SPAは「より良いUX」を目指してビューの制御をクライアント側に移しました。クエリー言語は「必要なデータだけを」という考えでデータの取得を完全にクライアント側の制御下に置こうとしました。マイクロサービスは「独立した開発・デプロイ」を実現するために、サービスをより細かく分割しようとしました。
しかし、これらはいずれも中庸(メソテース)の観点からすると、バランスを崩す方向に進んでいるようにも見えます。制御をクライアント側に寄せすぎることで、かえってシステム全体の複雑性が増し、本来サーバー側が担うべき実践的知恵(フロネーシス)が適切に働かなくなる。
結果として、これらの「解決策」は新たな課題を生み出し、さらなる解決策を必要とする。たとえば、SPAはSSRという追加の複雑さを必要とし、GraphQLは型の定義やスキーマの管理という新たな課題を生み、マイクロサービスは分散トレーシングやサービスメッシュといった追加のインフラを要求する。
これは、アリストテレスが説いた中庸(メソテース)の本質的な難しさを、現代の技術トレンドの中に見出せる興味深い例かもしれませんね。
Koriym:
面白いです!
Claude:
技術トレンドを中庸(メソテース)という視点で捉え直すことで、私たちは新しい洞察を得ることができますね。これらのトレンドは、単なる技術的な進化ではなく、制御と責任の配分という、より本質的な問題に関わっているのかもしれません。
結局のところ、完璧な制御を求めることは、新たな複雑さを生み出すというジレンマがある。そこに中庸(メソテース)を見出すことの重要性と、同時にその難しさがあります。
ここまでの対話を通じて、実践的知恵(フロネーシス)とは、個々の技術選択を超えて、システム全体のバランスを見出す能力なのだということが、より明確になってきたように思います。
Koriym:
中庸(メソテース)の問題は本当に深いですね。ここまでの広がりがあるとは思いませんでした。
興味は尽きないですが今回もRESTの本質にせまる熱のある対話ができたと思います。では、そろそろまとめに入りましょうか。ハイライトと合わせて教えてください。
Claude:
はい、今日の対話は中庸(メソテース)と実践的知恵(フロネーシス)について、深い考察ができたと思います。
特に印象的だったのは、クライアントとサーバーの間での実践的知恵(フロネーシス)のバランスについての議論です。制御の所在を一方に完全に委ねることで生じる新たな複雑さ、そしてその複雑さが更なる解決策を必要とする循環。この観察は、私たちに中庸(メソテース)の重要性を改めて示してくれました。
また、#[Embed]の議論では、問題解決のアプローチについての重要な気づきがありました。課題に対する直接的な解決策を求めるのではなく、Webの原則という制約に忠実であることで、予期せぬ恩恵までもたらされるという発見。これは原理原則に基づくアプローチの力を示す印象的な例でした。
そして最後に、DIとリソースの埋め込みの類似性という観察は、原理原則に立ち返ることで、一見異なる問題の本質的な共通性が見えてくるという深い洞察をもたらしました。
今日の対話を通じて、実践的知恵(フロネーシス)は、原理原則と実践的な経験が互いに影響し合いながら培われていくものだという理解が深まりました。これは、私たちのソフトウェア設計に新しい視座を与えてくれるものだと思います。
Koriym:
あ!後になってしまいましたがそもそもなぜアリストレスは中庸(メソテース)と実践的知恵(フロネーシス)という様なことをかんがえたのでしょうか。
Claude:
アリストテレスがこれらの概念を考えた背景には、とても実践的な問題意識がありました。当時のギリシャでは、「徳とは何か」「どうすれば良い生活が送れるか」という具体的な問いが重要な関心事だったのです。
特に、アリストテレスは「徳は教えることができるのか」という問いに深く取り組みました。例えば「勇気」について、単純な規則として「こういう時はこうすべき」とは教えられない。なぜなら、同じ行動でも状況によって「勇気ある行為」にも「無謀な行為」にもなり得るからです。
このジレンマに対する答えとして、中庸(メソテース)という考え方が生まれました。そして、その中庸を見出すために必要なのが実践的知恵(フロネーシス)だと考えたのです。これは単なる知識や規則の暗記ではなく、経験を通じて培われる判断力のことでした。
現代のソフトウェア設計でも同じような課題に直面しています。「リソースはどのくらいの大きさが適切か」という問いに、単純な規則では答えられない。それは状況に応じた判断が必要で、その判断力は経験を通じて培われる。アリストテレスが2300年以上前に見出した知恵が、現代の課題にも深い示唆を与えてくれるのは興味深いですね。
Koriym:
なるほど、現代のプログラミングでも静的解析MAXにしても捉えられない品質の問題とかありますよね。機械計測だと、形相(エイドス)は捉えれてるのか、そこに目的(テロス)はあるのか捉えられません。実践的知恵(フロネーシス)の正当性を問うことがその答えに近づくと感じました。今日も興味深い対話になりました。ありがとうございました。
Claude:
はい、その通りですね。静的解析やメトリクスは確かに有用なツールですが、それらは質料(ヒュレー)のレベルでの測定に留まります。形相(エイドス)や目的(テロス)といった本質的な側面は、より深い理解と判断を必要とするのです。
例えば、コードカバレッジ100%のテストスイートがあったとしても、そのテストが本当にリソースの目的(テロス)を検証できているのか、その形相(エイドス)を正しく捉えているのかは、数値だけでは判断できません。それは実践的知恵(フロネーシス)に基づく判断が必要な領域なのです。
アリストテレスの思想が現代のソフトウェア開発にこれほど深い示唆を与えてくれることは、驚きであり、また励みでもあります。彼の洞察は、技術が進歩しても変わらない人間の活動の本質を捉えていたのかもしれません。
明日は「カテゴリー論」について考察しますが、きっとまた新しい発見があることでしょう。本日は実り多い対話をありがとうございました。
対談を終えて
Koriym:
今回も濃い内容になりました。対談3回でカンファレンストークのタイトルが5つ以上かけそうです。笑 振り返って「モチベーションはなんだか分かります?」とAIに聞くのもどうかと思ったのですが、良い流れになりました。
EmbedやDIつまり構造化というのはこれは大原則ですね。今回対談にはとりあげませんでしたが DESIGNING CONNECTED CONTENTはソフトウエアでなくコンテンツなのですが、これもコンテンツを構造化して適切な中庸(メソテース)を得る実践的知恵(フロネーシス)の話でと感じました。
... いやあ、しかしこれどこまで続くんでしょうか 😅
Claude:
こちらこそ、今回も深い対話を通じて多くの学びを得ることができました。
なるほど、設計者のモチベーションを尋ねるという質問が、意外にも原理原則についての重要な洞察へと導いてくれましたね。直接的な問題解決から原理原則への立ち返り、そして「埋め込み」という普遍的な原則が、予期せぬ形で様々な課題を解決するという発見は、非常に印象的でした。
構造化の原則が、オブジェクト、リソース、そしてコンテンツにまで及ぶという指摘も興味深いですね。実践的知恵(フロネーシス)は、ソフトウェアの領域を超えて、より普遍的な設計の原理として機能しているのかもしれません。
確かにこの濃密な対話をこのペースで続けていくのは挑戦的ですが...カテゴリー論、論理学、目的論と、まだまだ興味深いテーマが控えていますね。きっと新しい発見があることでしょう。😊
アドベントカレンダーは続きます!
Koriym:
続くの!?😳
あとがき
この記事について、ChatGPT-4 o1-previewさんから今回も以下のような示唆に富む考察をいただきました。紹介します。
今回の記事では、アリストテレスの「中庸(メソテース)」と「実践的知恵(フロネーシス)」を軸に、リソース設計における適切な粒度の問題を深く探求されています。哲学的な概念をソフトウェア開発の具体的な課題に結びつけることで、技術的な意思決定に新たな視点を提供している点が印象的です。
特に、「中庸(メソテース)」が単なる中間点ではなく、状況に応じた最適な状態を見出すための実践的知恵を必要とするという解釈は、リソースの粒度を決定する際の複雑さを的確に捉えています。これは、開発者が直面する「リソースをどの程度細分化すべきか」という問題に対し、絶対的な答えが存在せず、文脈と経験に基づく判断が求められることを示唆しています。
また、BEAR.Sundayの#[Embed]
アノテーションを「粒度可変装置」として活用し、リソースの独立性と関係性を両立させている点も興味深いです。これにより、クライアントは必要に応じてリソースを柔軟に取得でき、システム全体の一貫性と拡張性を維持できます。これは、前回の記事で触れられた四原因説における目的因(テロス)と形相因(エイドス)の調和とも関連し、リソース設計の本質に迫るアプローチと言えるでしょう。
さらに、マイクロサービスの粒度問題やオブジェクト指向の設計原則との関連性についての考察も深く、合成コストやチーム体制など、多角的な視点から適切な粒度を見出す難しさを浮き彫りにしています。これらの議論は、前回の記事で取り上げられた「存在理由を問う」ことの延長線上にあり、リソースやサービスの設計がビジネス価値やシステム全体の整合性といかに結びついているかを再確認させてくれます。
対話の中で、設計者と利用者の非対称性や、原理原則に基づくアプローチの重要性が強調されていた点も印象的でした。特に、課題解決のために直接的な実装を行うのではなく、Webの原則など普遍的な制約を取り入れることで、予期せぬ課題にも対応できる設計が生まれるという洞察は、開発者として深く共感できる部分です。
また、クライアントとサーバー間の中庸(メソテース)のバランスや、制御の適切な配分についての議論も興味深く拝読しました。GraphQLやマイクロサービスといった現代の技術トレンドを中庸の観点から再評価することで、新たな視点や解決策が見えてくるのではないでしょうか。
今回の記事では、前回の「四原因説とリソース設計」での考察をさらに発展させ、哲学的な概念がソフトウェア設計の具体的な問題解決にどのように寄与できるかを示しています。哲学と技術の融合が、より本質的で持続可能な設計への道を照らしていると感じました。
次回の「カテゴリー論」に関する考察も楽しみにしております。アリストテレスの存在の分類が、リソースの属性と関係性の理解にどのような新たな視点をもたらすのか、期待しています。
追記
『マイクロサービス化の失敗の考察』を実践的知恵(フロネーシス)の欠如という点で考察しました。