はじめに 吉本茜改め井上茜です。先月、離婚が成立して改姓しました。(旧姓に戻りました) 改めましてよろしくお願いいたします。 吉本に慣れてて吉本って呼びたい人はそのままでも全然問題ないです! 何も気にしません!心底どうでもいいです!!!w 離婚に至る詳細は以下の通りです↓ あれから実際に運用フェーズに入ったのですが、結論から言うと、 結婚生活というモノリスを解体したら、各サービスがめちゃくちゃ安定稼働 しています。 夫オブジェクトは別に壊れていなかった 結婚生活を続けるのは無理でした。でも、元夫が何もできない人だったのかというと全然そんなことはありません。 割としっかりしてるかなりまともな人間だと思います。 特にお金と書類周りは昔から私より全然強いです。 元々銀行員の夫婦なので、必要な手続きを確認する、条件を調べる、書類を揃える、期限を管理する、必要なお金を払う。このあたりは結婚していた頃から普通に自律稼働していました。 先日も、離婚手続きの都合で本来受けられるはずだった補助金が対象外になりました。 私は特に請求していません。 でも元夫は、自分で条件を確認して、自分が原因で対象外になったことを検知して、勝手に3万円振り込んできました。 こちらから特にリクエストを送っていません。イベントを検知して勝手に発火しました。 あれ??これってWebhookですよね?? これぞ本当のATM 離婚もしていないのに「夫はATMです」と言っている結構人がSNSでいますが、それは違います。 同居して、家事育児して、夫婦関係を維持して、そのうえで生活費をもらっているなら、それはATMではありません。 こっちは結婚生活というサービスを終了しています。 それでも養育費を払い、必要経費を払い、約束した損失は自主的に補填するというわけです。 しかも今回は、こちらから出金操作すらしていません。 イベントを検知し、条件を確認し、自動送金したということになります。 これが本物の Autonomous Transfer Machine ですw なぜ結婚生活は動かなかったのか 夫オブジェクトは壊れていません。お金と書類周りはむしろ高性能です。 じゃあ、なぜ結婚生活は無理だったのか?妻側の我儘なのでは?とか思いますよね、わかります。 今考えると、 密結合で責務過多だったから だと思います。 結婚生活では「夫」という一つの巨大なオブジェクトに、お金、書類、家事、育児、共同生活、意思決定、将来設計まで全部持たせていました。 責務が多すぎたんだと思います。 しかも家庭全体が夫オブジェクトに密結合しているので、一つの機能で問題が起きると影響範囲が広いわけです。 夫オブジェクト本人としては、 husband.isValid()// => true だったと思います。 本人からすれば、仕事をしている。お金も払っている。必要なこともやっている。 俺は正常稼働している。 実際、単体で見れば壊れていませんでした。 問題は、親クラス(私)が期待しているインターフェースと、夫オブジェクトの実装が一致していなかったことです。 例外を投げない夫オブジェクト 結婚生活で一番厄介だったのは、期待に応えない(=失敗すること)ではありませんでした。 ほんとの問題は、 例外を投げないことです。 たとえば、子どもが朝から熱を出しているとします。 私が「熱出てるわ。今日、保育園無理やわ」と言ったとします。 親クラスである私は、当然何らかのレスポンスが返ってくると思っています。 「了解、今日は俺が休む」「午前中なら対応できる」「今日は無理だから調整してほしい」。 何でもいいです。 でも夫オブジェクトは、 静かに出勤します。 const result = await husband.handle({ event: "child_has_fever", daycare: false, }) console.log(result) // undefined つまり何も返ってきません。 成功なのか、失敗なのか、対応中なのか、そもそも自分の責務として認識していないのか。呼び出し元には分かりません。 ただ、夫はいなくなりました。 これがまさに undefined です。 null ならいいのか問題 一方、保育園から突然お迎え要請が来た場合、電話を受け一時対応した私が密結合している夫にLINEします。「お迎え要請きた!いける?」 「無理」 const result = await husband.pickUpFromDaycare() console.log(result) // null これは null です。 期待していた値はありません。夫は迎えに行きません。でも「値がない」ということは明示されています。 なので私は「了解、じゃあ私が行く」で次の処理に進めます。 undefined も null も、最終的な結果だけ見れば夫は保育園に行きません。 、、、どっちも同じやないかい!!! 親クラスと子クラスで、インターフェースの認識が違う 多分、夫オブジェクト側はこうです。 「聞かれてないから返してない」 親クラスとしては「いや、 child_has_fever イベント通知したやん」と思っています。 でも夫オブジェクト側では、 canYouTakeCareOfChild() を明示的に呼ばれていないので、自分の処理は始まっていないのかもしれません。 wwwwww 親クラスはイベント通知で処理が始まると思っている。 夫オブジェクトは明示的にメソッドを呼ばれない限り動かない。 しかも例外は投げません。エラーも返しません。 静かに出勤します。 夫オブジェクト本人としては正常終了です。 親クラスから見ると、期待していた副作用だけが起きていません。 親クラスの期待値を変える手もあった もちろん、解決方法はありました。 親クラス側が、 「このオブジェクトは自律的には動かない」 という前提にそういう設計に変わればいい。 「熱出てるわ。今日保育園無理やで」ではなく、「今日あなたが休んで子どもを見られますか?」と明示的にメソッドを呼ぶ。 返ってこなければタイムアウトさせる。 undefined が返る前提でfallbackを持つ。必要な処理は全部こちらから明示的に呼び出す。 そういう設計に変える手もありました。 ほんとはそもそも親子関係でありたくないけど!!!! でもこれでやり過ごしてる夫婦が多いのは現実だと思います。 実際、それでうまく運用できる家庭もあると思います。 でも、 うちの親クラスはそういうスタンスではありませんでした。 私は「夫オブジェクトの仕様を理解して、全部適切な粒度で呼び出し、レスポンスを監視し、返ってこなければ自分でfallbackする」という運用を、この先何十年も続けたくありませんでした。 別に、夫オブジェクトが悪いからではありません。 そのインターフェースで家庭システムを運用したくなかった。 それだけのことです。 親クラス単体で動けるようになっていた 前回の記事で書いた通り、離婚を切り出す前に依存関係は全部潰しました。 住む場所を決めて、子どもの生活動線を確保して、収入と支出の見通しを立てて、養育費や財産分与も確認しました。 つまり、その時点でもう 親クラス単体で動く状態になっていました。 夫オブジェクトの仕様に親クラスを合わせることもできるし、夫オブジェクトを何とか修正し続けることもできる。 でも、どちらも必要ありませんでした。 うちでもやれるし、ここは疎結合でいくかって感じですね。 結婚生活というモノリスを解体した 結婚生活というモノリスを解体して、元夫から共同生活、家事の共同運用、私の感情的ケア(元々いらんけどねww)、私の人生の意思決定などの責務を剥がしました。 残ったのは主に、父親、養育費支払者、合意済み費用の負担者です。 するとどうでしょう、 めちゃくちゃ安定稼働しています。 なぜなら、残ったのは元々ちゃんと動いていた機能だからです。 お金、書類、契約、手続き。このあたりは結婚していた頃から普通に自律していました。 疎結合にしたから自律したわけではありません。 元々自律していた機能だけが、綺麗に残ったのです。 まじで当然すぎる フルスタックとして採用したのが間違いだった 元夫は壊れていませんでした。ただ、フルスタックではありませんでした。 お金と書類は強い。イベントも自分で検知する。必要条件も調べる。Webhookも発火する。 でも、すべての責務を持たせると、一部のメソッドから undefined が返ってくる。 問題は、そんなオブジェクトに「夫なんだから全部できるはず」という巨大なインターフェースを実装させようとしたことでした。 フルスタックとして採用したのが間違いだった。 単機能サービスとしては、かなり優秀でした。 そして私は、元夫サービスに依存していない このアーキテクチャの一番いいところはここです。 私は自分で収入を得て、自分で生活基盤を持っています。元夫サービスが停止しても、私のコア機能は止まりません。 クリティカルパスに入っていない。 なくても稼働する。あると、より豊かになる。 養育費が入れば余裕が増えるし、必要な費用を負担してくれれば、その分ほかに使えます。今回のように3万円が勝手に振り込まれれば、「Amazon株でも買おうかな」となる。 依存していないから、停止しても全体障害にならない。正常稼働したら追加リソースが入ってくる。 外部サービスとして完璧です。文句ない!! 人は変わらなくても、アーキテクチャは変えられる 離婚前と離婚後で、元夫という人間が劇的に変わったわけではありません。私も変わっていません。 親クラスの期待値を変えたわけでもありません。 夫オブジェクトを修正したわけでもありません。 変えたのは、 責務の境界と依存関係です。 親クラスが子クラスの仕様に合わせて運用を変える方法もあった。でも、うちの親クラスはそれを選ばなかった。 そして単体で動けるところまで依存関係は解消済みだったので、無理に同じモノリスで動かし続けなくてもいいですよね。 自分でもやれるし、疎結合でいくか って意思決定が良かった。って感じです 責務を分離して、依存を減らして、それぞれが正常に動ける境界を引き直しました。 その結果、元々 success を返せる機能だけが残り、たまにWebhookまで勝手に発火します。 便利すぎる。最高。責務の分離だいじ。 おわりに 前回の記事では、離婚を「人生を取り戻すためのプロジェクト」として書きました。 そして実際に運用フェーズに入って思います。 離婚は、壊れた夫オブジェクトを捨てることではありませんでした。 親クラスの期待値を無理に変えることでも、夫オブジェクトを何とか修正し続けることでもありませんでした。 結婚生活というモノリスを解体して、責務を見直して、依存関係を整理して、それぞれが正常に動ける境界を引き直した。 人は変わらない。でも、アーキテクチャは変えられる。 家庭では長年、 undefined を返されていました。でも今はもう、そのメソッドを呼ぶ必要がありません。離婚プロジェクト。 大規模リファクタリングまで含めて大成功です!!! ほんとに離婚前後って病んでる人多いみたいですが、私ノーダメージなので腫れ物ではないです。気になることあればなんでも答えるので聞いてくださいwww