八杯目の夜。
扉を押すと、いつもと違う香りが出迎えた。
潮気を含んだ、凛とした空気。煙くはない。先週のラスティネイルの薬草の甘さでもない。海風のようで、けれどどこか温かい。
カウンターの向こうで、マスターが見慣れないボトルを手にしていた。グラスはもう用意されている。
いつもの席に座った。何も言わない。マスターも何も聞かない。八回目だ。もうそういう間柄になっている。
マスターがグラスにウイスキーを注いだ。琥珀色。先週のラスティネイルは二つの酒を重ねたカクテルだったけれど、今夜は一本のボトルだけ。
「……今夜はこれですか」
おまかせで、とは言わなかった。自分で選ぼうともしなかった。ただ——何を出されたのか、知りたかった。
「余市(よいち)。シングルカスクでございます」
「シングルカスク?」
「一つの樽だけで完結した原酒です。他の樽とブレンドしていません」
一口。力強いが透明感がある。潮の香りの奥に、蜂蜜のような丸い甘さ。先週のラスティネイルは「二つを重ねた」複雑さだったけれど、これは一つの樽の中にすべてがある。
「シンプルなのに、奥がある……」
「必要なものだけで完結しているからでしょう」
来店——伝言ゲームのような矢印
視線がカウンターの上を滑っていった。取り置きボトル。
もう「カウンターの端」とは呼べない。数えてみた。私の席から三つ目の位置。手を伸ばせば——もしかしたら、届くかもしれない距離。
麻布は前回からずれたまま。琥珀色が覗いている。七回目までは「近づいている気がする」と思っていた。でも今夜は、「気がする」じゃない。確実に近い。
口には出さなかった。ただ、視線を戻した。
扉がゆっくりと開いた。
ネクタイを緩めながら入ってくる男性。スーツの上着は腕にかけている。革靴。PCバッグ。残業帰りの空気。
前回の手順書さんとは対照的だった。あの人は扉を勢いよく開けて、座る前にPCを取り出していた。この人は静かに入ってきて、カウンターの両隣を確認してから一つ席を空けて座った。
ネクタイさん、と心の中で呼んだ。前のお客さんたちはTシャツだったりパーカーだったりしたけれど、この人はスーツにネクタイ。ネクタイを緩める仕草が、長い一日の終わりを物語っている。
「いらっしゃいませ。今夜は何をお召し上がりになりますか」
ネクタイさんはメニューに目を通してから答えた。「ハイボールをお願いします。……あの、ここはコードの相談もできると伺ったんですが」
落ち着いた声だった。急いでいない。困っているというよりも、何かを確認したいという温度。先週の手順書さんの切迫感とは、全く違う空気。
ハイボールを一口飲んで、ネクタイさんがPCを開いた。画面をマスターに向ける。
「弊社の注文管理システムなんですが——今度、顧客データモデルを再設計することになりまして」
「個人顧客と法人顧客を分ける改修です。影響範囲を調べたら——」
ネクタイさんが画面をこちらにも見えるように少し傾けた。コードが映っている。
「こういう書き方が、コードベース全体に散らばっていること がわかったんです」
画面に映っているのは——矢印。-> という記号が横に並んでいる。四つ、五つ。コードの中身はわからないけれど、「矢印がたくさんある」ことはわかる。
| |
「Customer の構造を変えると、関係ないはずの場所まで芋づる式に壊れることがわかって。上司に報告したら『全部直せばいいじゃない』と言われたんですが——その『全部』がどれだけの規模になるか」
ネクタイさんの声には怒りも焦りもなかった。ただ、静かな疑問。「これでいいのか」という確認。
矢印が何本も並ぶコードを見て、ふと思った。
「伝言ゲームみたい」
ネクタイさんが振り返った。「……伝言ゲーム?」
「注文から顧客を辿って、顧客から住所を辿って、住所から都市を辿って——何段階も経由しないとデータに届かないんでしょう?」
「ええ、まさにそうです」
「うちのシステムも似たようなものかも」
口をついて出た。前にエンジニアに画面を見せてもらったときの記憶。「注文から顧客、顧客から住所って何段階も辿るんですよ」と説明されて、「ふーん」で済ませたあの日。
「矢印がずらっと並んでたわ。うちのエンジニアは当たり前だって言ってたけど」
マスターの視線が一瞬だけ、カウンターの下のほうに落ちた。何かを確認したように。それからすぐにネクタイさんに向き直った。
テイスティング——覗かないという作法
マスターがネクタイさんの画面をしばらく無言で見つめた。それから口を開いた。
「この shipping_label メソッドは、配送ラベルを作るためのものですね」
「はい」
「しかしここには——注文の中の、顧客の中の、住所の中の都市名。四つの層の奥にある情報を、一番外側から直接覗きに行っています」
「必要な情報を辿れば取れますので。不便はなかったんですが……」
「伝言ゲームっていうより、覗き見に近くない?」
思わず口を挟んでいた。自分でも驚いたけれど、言ってしまったものは仕方ない。
「Aさんが知りたいことを、BさんやCさんを経由して聞くんじゃなくて——直接、Bさんの引き出しを開けて中身を見てる感じがする」
ネクタイさんが少し考えて頷いた。「近いです。OrderReport が Customer の中の Address の中身まで直接知っている。Customer に許可を取らずに、中の構造を全部前提にしたコードです」
「覗き見……」
その言葉を反芻していたら、以前聞いた名前がふと浮かんだ。
「これって——もしかして、Feature Envy? 他のクラスのデータを羨んでるってやつ」
マスターが穏やかに首を振った。「似ていますが、少し違います」
間違えた。でも——名前を出せたこと自体に、少しだけ驚いている自分がいた。Feature Envy なんて言葉、半年前の私は知りもしなかった。
「Feature Envy は、自分のものではないデータを使いたがること。今夜の問題は——知るべきでない相手の構造に、立ち入ってしまっていることです」
ネクタイさんが静かに言った。「……Law of Demeter。デメテルの法則ですね」
マスターが小さく頷いた。
「デメテル? ギリシャ神話の?」
「ええ。収穫の女神の名を冠したプロジェクトで生まれた法則です」
マスターがカウンターの上にコースターを一枚置いた。ネクタイさんの空になったハイボールのグラスを下げながら。
「直接の友人とだけ話せ。見知らぬ者とは話すな——そういう法則です」
直接の友人とだけ話せ。見知らぬ者とは話すな。
何かが頭の中で動いた。前回の「手順ではなく構造で」。その前の「間に立つだけの存在は要らない」。点が少しずつ線になりつつある。でも、まだ全体は見えない。
「お客さま」。マスターがネクタイさんに向き直った。「この OrderReport が壊れるのは、どのような変更が起きたときでしょう」
ネクタイさんが画面を見直した。指がコードの行をなぞる。
「たとえば Customer が address メソッドを primary_address に変えたら——OrderReport が壊れます。Customer の内部構造を直接知っているから」
「Order のことも、Address のことも——本来、OrderReport が知る必要のない相手の事情です」
マスターが余市のボトルをカウンターに戻しながら、続けた。
「私はカウンターの中にいます。お客さまが何を召し上がりたいかは、直接お聞きします」
一拍の間。
「しかし——隣のお客さまがどなたと来店されたか、その方が何を頼まれたか、そのグラスの中身は何であるか。それを覗くことは、いたしません」
ネクタイさんが顔を上げた。「直接の相手以外の内部に触れるな、ということですか」
「ええ。知る必要のないことを知ってしまえば——それが変わったとき、すべてが壊れます」
ブレンド——知らないことは、壊れない
「では」。マスターがネクタイさんに問いかけた。「この OrderReport は、Order に何を聞けばよいのでしょう」
ネクタイさんが考え込んだ。指が画面の上で止まっている。先週の手順書さんはキーボードを早打ちしていたけれど、この人の手は静かだ。
「……配送先の住所がほしいだけです。Customer から辿る必要は、本来ない」
「そうです。OrderReport は Order に、配送先をくださいと伝えればいい。Order がどうやって Customer から住所を引き出すかは——Order の仕事です」
ネクタイさんが呟いた。「Tell, Don’t Ask……聞くのではなく、伝える」
それから不意に、苦笑した。
「皮肉ですよね」
「と言いますと?」
「弊社は組織の階層を厳密に守る文化です。部長が担当者のデスクに直接行くことは絶対にない。必ず課長を通す」
ネクタイさんが画面に目を落とした。「——なのに、コードではそのルールを完全に無視していました」
「あ、それわかる」
思わず声が出た。うちは大企業じゃないけど、報告ラインを飛ばされると困るのは同じだ。
「うちも小さい会社だけど、部下が私を飛ばして取引先に直接連絡したら——困るもの。なんで、コードだとそれがまかり通るんだろう」
ネクタイさんが静かに答えた。「慣習ですかね。動いてるから、誰も疑問に思わなかった」
——動いてるから。
その言葉が耳に引っかかった。自分も何度も使った言葉だ。でも今は、その言葉の軽さが少しだけわかる。
「Moo であれば——handles が使えます」
マスターがネクタイさんのPCに視線を送った。ネクタイさんがキーを叩き、新しいファイルを開く。マスターが横から指示する内容を、ネクタイさんが書き換えていく。
| |
「各クラスが、直接の隣人にだけ委譲しています」
マスターが画面を指しながら説明した。
「Customer が Address の format を formatted_address として公開し、Order がそれを shipping_address として引き受ける。OrderReport は Order だけを知っていればいい」
ネクタイさんが画面を見つめている。指がコードをゆっくりなぞった。
「Customer の中に Address があることを、OrderReport は知らない……。Order の中に Customer があることすら」
「ええ。知る必要がありません」
ここで、私の中に引っかかるものがあった。
「あれ……でも。前に来たお客さんの話を思い出したんだけど」
マスターとネクタイさんが私を見た。
「何もしないで通すだけのクラスがダメだって言ってたわよね。Middle Man って。これも——通してるだけじゃないの?」
ネクタイさんが首を傾げて、それから答えた。
「Middle Man は、何の仕事も持たずにただ転送するだけのクラスです。今回の Order は注文金額を持っていて、Customer との関係も管理していて——自分の存在理由がある。handles は、その上で問い合わせにも答えられるようにしているだけで」
「……空っぽの中間管理職と、自分の仕事をしつつ窓口も兼ねる人の違い?」
ネクタイさんが目を見開いた。「まさにそうです。弊社でいえば、管理部門が何も判断せずメールを転送するだけなのが Middle Man。営業部が自分の仕事をしながら顧客窓口も担うのが handles です」
なるほど。前回聞いた話と、今夜の話が繋がった。間に立つこと自体が悪いんじゃない。間に立って何もしないのが問題だった。
「でも」。もう一つ、気になることがあった。「結局は同じデータに辿り着くんでしょう? 部長が直接行っても、課長を経由しても、結果は同じじゃない?」
ネクタイさんが少し考えてから答えた。
「結果は同じです。でも——たとえば担当者が異動したとき。部長が直接デスクに行く仕組みだと、部長のルーティンが壊れます。課長を経由していれば、課長が新しい担当者を見つけて調整するだけで済む」
マスターが頷いた。「影響範囲が局所化されます。Address の構造が変わっても、修正するのは Customer の handles だけ。Order や OrderReport は何も変わりません」
「ああ……さっきは Customer を変えたら全部壊れるって言ってたけど、handles があれば Customer の中だけで吸収できるってこと」
「ええ」
マスターがグラスを拭いた。穏やかだけれど、はっきりとした声で。
「知らないことは、壊れません」
ラストオーダー——まだ、早いですよ
ネクタイさんがPCを閉じた。落ち着いた動作で。何かのメモを保存してから画面を閉じたのが見えた。
「弊社のコードベースで、矢印の連鎖が三段以上あるものを検索してみます」
少し間を置いて。
「何箇所見つかるか、正直少し怖いですが」
立ち上がった。スーツの上着を羽織り、ネクタイを締め直している。来たときに緩めたのを、戻していた。何かのスイッチが切り替わったように見えた。
マスターに一礼した。「ありがとうございました。明日から、少しずつ直していきます」
それから私にも軽く会釈した。「伝言ゲームの喩え、わかりやすかったです。社内の説明で使わせてもらいます」
扉が閉まった。来たときと同じくらい静かに。
バーに沈黙が戻った。
余市のグラスに残った最後の一口を傾けた。潮気の余韻。一つの樽だけで完結した味。混ぜていないのに複雑で、でも余計なものは何もない。
「デメテルの法則、か」
覚えたての名前を口の中で転がした。直接の友人とだけ話せ。見知らぬ者とは話すな。Feature Envyと間違えたのは恥ずかしかったけれど——名前を出せたこと自体が、半年前の自分には考えられないことだった。
「マスター」
「はい」
「一つの樽で完結するって——いいですね。他の樽のことを気にしなくていいって」
マスターがグラスを下げた。
「一つの樽で完結するシングルカスクは、他の樽の中身を覗きません」
一拍の間。
「けれどそれは、孤立しているのではなく——自分の中に必要なものを持っている、ということです」
必要なものだけで、完結する。
視線がカウンターを滑った。取り置きボトル。三席分の距離。
八回通った。毎回確認するようになった。近づいていることを、もう自分に嘘をつかない。
何も考えずに手を伸ばしていた。カウンターの木目に指を滑らせるように——麻布に指先が触れるか触れないかの距離で。
「まだ、早いですよ」
穏やかだが、有無を言わせない声だった。怒られたのとは違う。ただ「まだ」だと言われた。
まだ、ということは——いつかは。
手を引いた。指先に、麻布の感触は残っていない。触れなかった。けれど何かの温度だけが、指先に残っている気がした。
マスターがカウンターの下から何かを取り出して、ペンを短く走らせるのが目の端に映った。前にも見たことがある。お客さまの好みの記録——ネクタイさんの好みだろうか。
「マスター、おやすみなさい」
「おやすみなさいませ。お気をつけて」
扉を押した。路地裏の夜風が指先に冷たい。
帰り道、マスターの言葉が耳の奥で響いた。知る必要のないことは、知らないほうがいい。直接の友人とだけ話せ。
——でも私は今夜、手を出しかけた。あのボトルに。
まだ早いと言われた。
けれど——知りたい、と思った。
それも、嘘ではない。
歩き出した。指先はまだ、あの一瞬の温度を覚えている。
🥃 マスターのテイスティングノート
本日の銘柄: 余市 シングルカスク
お客さまの症状: デメテルの法則違反(Law of Demeter / Message Chains)
ノージング(香り)── 問題の検知
$self->order->customer->address->city のように、矢印(->)が三つ、四つと連なるメソッドチェーンが見えたら、デメテルの法則違反を疑いましょう。「辿れば取れる」の便利さの裏に、本来知る必要のない相手の内部構造への依存が隠れています。
パレット(味わい)── 問題の本質
問題はドットや矢印の数ではありません。中間オブジェクトの構造を暗黙に前提としていることが問題です。Customer が address を primary_address に変えたとき、OrderReport まで壊れる——知る必要のないことを知ってしまったから。直接の友人を超えた「見知らぬ者」との会話が、変更の波及範囲を爆発させます。
フィニッシュ(余韻)── 解決の方針
Moo の handles で、各クラスが直接の隣人にだけ委譲する構造に変えます。OrderReport は Order だけを知り、Order は Customer だけを知る。Address の変更は Customer の handles で吸収され、Order 以降には波及しません。影響範囲が局所化される——知らないことは、壊れないのです。
ペアリング(相性の良いパターン)
- Tell, Don’t Ask(聞くな、伝えよ)
- Facade パターン(複雑なサブシステムへの統一窓口)
- Feature Envy との区別(データを羨むことと、構造に立ち入ることの違い)
「一つの樽で完結するシングルカスクは、他の樽の中身を覗きません。——けれどそれは孤立ではなく、自分の中に必要なものを持っているということです」
