はじめに
こんにちは、はなまるです!
前回の記事で「言葉を合わせ、意味が違うなら部屋を分けようぜ」というお話をしました。
ただ、「そうは言っても、うちのシステムすでにレガシーコードなんだけど?」という絶望的な状況がよくありますよね😢
今回も、オライリーの『ドメイン駆動設計をはじめよう』から学んだ内容で打破していきましょう!
1. レガシーコードには「腐敗防止層」で盾を構えろ
すでに稼働しているシステムでDDDをやろうとした時、最大の敵は「すでに存在するスパゲッティコード」です。
1番最初に思いつく対応は、「このコードはDDDじゃないから、全部綺麗に書き直すぞ!」というものです。
こういうのは、途中で力尽きることが多いです。
返事がないしかばねになりますよ!
ここで登場するのが、「腐敗防止層」です。
[ 新しく作る、綺麗なDDDの部屋 ]
│
│ (変換処理) ◀── これが「腐敗防止層」!
▼
[ 既存のレガシーコード ]
腐敗防止層ってなに?
要するに「ただの翻訳クラス」です。
新しく作る機能(綺麗な部屋)の中では、「ユビキタス言語」を使って、めちゃくちゃ綺麗なコードを書きます。
そして、古いシステムからデータを取得するときは、直接レガシーなクラスを呼ぶのではなく、この「腐敗防止層」を必ず経由させます。
レガシーコードの「謎の命名規則」「バグを孕んだデータ構造」「神クラス」を、この腐敗防止層の中で『新しくて綺麗なオブジェクト』に変換してから、新しい部屋に迎え入れるのです。
既存のゴミが、自分たちの綺麗な部屋に流れ込んでくるのを防ぐ盾をイメージしてください。
PHP/Laravelだと次のようなイメージです。
namespace App\Http\Controllers;
use App\Models\User;
use App\Infrastructure\AntiCorruptionLayer\UserTranslator;
final readonly class UserProfileController
{
public function __construct(
private UserTranslator $translator
) {}
public function show(int $id)
{
// 既存のレガシーデータを取得
$legacyUser = User::findOrFail($id);
// 腐敗防止層を通して、ドメインモデルに変換!
$user = $this->translator->translate($legacyUser);
return view('user.profile', [
'name' => $user->name,
'email' => $user->email->value,
'status' => $user->isDeleted ? '退会済み' : 'アクティブ',
]);
}
}
これがあれば、システム全体を一気にリファクタリングしなくても、自分たちの新機能だけは平和に、DDDの恩恵を受けながら開発できます。
2. 「戦術」の前に「戦略」を立てる
DDDの本を読むと、多くのエンジニアが「値オブジェクト」とか「エンティティ」といった、コードの書き方(戦術)に飛びつきたくなります。
「Stringじゃなくて、Emailクラスを作ってバリデーションさせるぞ!」
「イミュータブルにするぞ!」
DDDをしてる感があって楽しいですよね!
でも、いくら「戦術(コード書き方)」を磨いても、「戦略(部屋の分け方)」を間違えたら、システムは普通に終わります!!!
例えば、「販売部屋」と「配送部屋」がごちゃ混ぜのまま、めちゃくちゃ綺麗な「値オブジェクト」を書いたとします。
でも、部屋が分かれていないので、配送チームの仕様変更の巻き添えを食らって、販売のコードは大爆発します。
まずはコードを書く手を止めて、「戦略」に全力を出しましょう。
実装パターンの本気を出すのは、コンテキストを切り離してからで十分です。
3. 大砲でハエを撃たない
「すべての場所を、DDDでガチガチに作らなくていい。コアドメイン(複雑な業務ロジック)だけに全力を出せ」
エンジニアは真面目なので、「DDDをやる」となったら、システム中の全画面・全機能をDDDのルールで書こうとしがちです。
でも、ただDBのデータを引っ張ってきて画面に表示するだけの機能や、マスタデータを登録するだけの画面に、わざわざDDDの重厚な設計を持ち込むのは、大砲でハエを撃つようなものです。
コード量が増えて、開発スピードが落ちるトレードオフがあります。
※ コアドメイン: 競合他社との差別化になる、一番複雑で重要なビジネスの領域。
まとめ
今回の記事では、レガシーシステムへの対応として、3つの重要な考えを挙げました。
- 「腐敗防止層」を利用し悪化を防ぐ。
- 「戦術」の前に「戦略」を立てる。
- 「コアドメイン」に全力を出す。
もし「DDDって敷居が高いな…」と感じている方がいたら、完璧を目指さず、自分たちの身の回りの「一番面倒な場所」から修正してみてはいかがでしょうか?