Seam — контрольована точка розділення
Seam — це місце, де можна змінити або підмінити частину поведінки без одночасного переписування всього legacy-модуля. Ним може бути interface, adapter, gateway, function boundary, event або routing decision. Хороший seam зменшує blast radius і робить replacement спостережуваним.
Seam не створює безпеку автоматично. Якщо межа лише перейменовує прямий виклик, але не ізолює side effects, configuration або failure path, ризик залишається.
Як знайти seam
| Сигнал | Що дослідити | Ризик |
|---|---|---|
| Stable input/output | чи є чіткий формат на межі? | приховані поля або state coupling |
| Repeated dependency | чи повторюється client або utility? | зміна одного caller зачепить багато flows |
| Side-effect boundary | де відбувається write, event або external call? | часткова міграція і подвійний side effect |
| Routing decision | хто вирішує legacy vs new path? | розбіжність flags, dates або rollout |
| Test boundary | чи можна перевірити seam окремо? | неможливо відрізнити regression від integration failure |
Dependency direction і adapters
Під час декомпозиції зафіксуйте, хто володіє контрактом і в якому напрямку течуть залежності. Adapter може сховати legacy API від нового коду, але не повинен непомітно змінювати semantics, формат помилок або retry behavior.
Інтерфейс має бути достатньо вузьким, щоб описувати потрібну поведінку, а не всю внутрішню поверхню legacy-класу. Якщо seam повторює кожну деталь реалізації, він не створює незалежної точки заміни.
- позначте producer, consumer і owner контракту;
- запишіть data transformation та можливу втрату інформації;
- окремо опишіть errors, timeouts, retries і idempotency;
- перевірте, чи seam можна вимкнути або обійти під час rollback.
Seam map як decision record
- Виберіть один flow і знайдіть його entry point та side effects.
- Намалюйте фактичний dependency path без бажаних компонентів.
- Позначте candidate seams і evidence для кожного.
- Вкажіть, яка частина може бути замінена незалежно.
- Зазначте unknowns, owner та спосіб focused verification.
- Оберіть один seam для першого slice і зафіксуйте, чому інші відкладені.
Антипатерни seam-декомпозиції
- створити абстракцію лише заради кількості інтерфейсів;
- заховати business rule в adapter без окремого owner;
- змішати routing, persistence і форматування в одну нову boundary;
- ігнорувати legacy callers, які обходять новий seam;
- вважати seam безпечним до того, як перевірено його failure path.
Канонічне джерело уроку · JavaRush
Відкрити матеріал JavaRush