ストラングリングすることにより、レガシーシステムを0からリライトしなくてもよくなる方法

Nicolas Carlo    
ソフトウェアクラフトマンシップに情熱を捧げ、アジャイルプロジェクト管理、フロント/バックエンドの知見もあわせ持つWeb開発者。
この記事は、著者の許可を得て配信しています。
https://understandlegacycode.com/blog/avoid-rewriting-a-legacy-system-from-scratch-by-strangling-it/

レガシープロジェクトにおいては、技術的な負債が多くなりすぎて、新しい機能を実装できなくなることがよくあります。

コードが繰り返しハッキングされ、もう後戻りできない状態になるということも…。

次に進む解決策が必要です!

アプリの一部をリワークしようとしたが、リファクタリングするたびにアプリの残りの部分がプルされてしまう😫

変更する前にユニット(単体)テストを作成しようとしたが、そのコードはそもそもテストできるように設計されていなかった! 😭

アプリをフリーズして、もうこれ以上いじるのはやめた方がいいのかも…😬

維持できないコードを、これ以上悪化させずに変更する必要がある場合はどうすればいいのだろうか?

「0からのリライト」が機能しないのでしょうか

コードは、変更する時のリスクが高くリファクタリングするには高額の費用がかかる場合があります。

このような状況においての得策はリライトすることです。

しかも、最初から。

方法は次の通りです:

1. 既存のアプリを書き換えながら、しばらくの間新機能を停止するという戦略について経営陣と話し合う。

2. 既存のアプリの機能にも対応するには、書き換えに6か月かかると推定される。

3. 数か月後、厄介なバグが発見され、古いコードでは何とかして修正する必要がある。したがって、古いコードと新しいコードにパッチを適用する。

4. 数か月後、新しい機能がクライアントに販売される。古いコードで実装する必要が出てきたが、新しいバージョンはまだ準備ができていない!古いコードで実装する必要が出てきたが、新しいバージョンでこれを実装するにはTODOを追加する必要がある。

5. 5か月後、このままではプロジェクトの進行が遅れることに気付く。古いアプリは予想以上の機能を持っていたのだ。今まで以上に頑張らないといけない。

6. 7か月後、新しいバージョンのテストを開始する。QAから、修正すべき点をたくさん指摘される。

7. 9か月後、「機能を開発しない」ことに対してこれ以上待てない様子。プロジェクトのリーダーもその状況に満足していないし、あなた自身も疲労困憊。 遅れないように書き直ししながら、古い苦痛なコードに変更を加え始める。

8. 最終的に、2つのシステムが実稼働状態になる。長期的な目標は古いコードを取り除くことだが、新しいコードはまだ準備ができていない。すべての機能を2回実装する必要があるのだ。

この方法、信用できるか不安ですか?それとも聞いたことがあるお馴染みのやり方ですか?

恥ずかしがらなくてもいいんです。これは本当によくあるミスなのだから

現在のプロジェクトにおいて、我々はそれを扱っています!

並行して動作する2つのシステムがあります。cart とbookingだ。 実際、bookingはcartに取って代わるものでした。

そのプロジェクトは3年前に始まりましたた。しかし、そのプロジェクトはずっと続いたのです! bookingはcart よりも優れているが、完全ではありません。 一部の購入フローではbookingが使用されていますが、まだカートが多くの場面で使用されています。

現在、新機能の実装には2倍の時間がかかっています。

ここからが面白くなるポイントです。cart は期待している新機能をサポートするように設計されておらず、bookingは古すぎるため、「cartを適切に書き換える」ことが提案されました😏

そうすれば、すぐに3つのシステムが数か月以内に並行して実行されることになるのです。

しかし、私たちはそういうことはしません。 というのも、レガシーシステムを回避するための効率的なテクニックを知っているからです。

そのテクニックというのはストラングルすることです。

レガシーコードベースをストラングルする方法

そのストラテジーはシンプルです:

新しいコードベースのために、古いコードベースを徐々に削除する

次がその方法だ:

・ 新しいコードを古いコードのプロキシとして機能させる。ユーザーは新しいシステムを使用するが、古いシステムにリダイレクトするだけなのだ。

・ エンドユーザーの観点から、変更することなくそれぞれのビヘイビアを新しいコードベースに再実装する。

・ ユーザーに新しいビヘイビアを消費させることにより、古いコードを徐々に削除する。 古い未使用のコードを削除する。

実際にはどういうふうに見えるのでしょうか

私たちのシステムで考えてみるとします。支払いの処理をするためのcart モジュールがあります。

書き換えが試行されました。支払いをcartよりもはるかにうまく処理する、新しいbookingを作成するのがその解決策でした。

しかし、このプロジェクトは100%提供されませんでした。書き換えに時間がかかりすぎたため、古いcartで新しい機能を開発する必要があったからです。

最終的に、2つのモジュールが実稼働することになりました。

もう一度、代わりにcartモジュールをストラングルしてみます。

代わりに、新しい予約モジュールをプロキシとして導入できます。

設定は非常に簡単です。すぐに、支払い処理ロジックを複製することなく、本番環境に配信することができるのです。

そして、徐々に支払いロジックを新しいbookingモジュールに移行し始めることができるようになりました。

ロジックを移行するときに、cartモジュールの未使用のコードは取り除きます。

これには時間がかかる場合があるが、古いメンテナンス不可能なカートを新しいbookingに置き換えるという目標に向かってゆっくりと前進します。

リライトではなく、ストラングルすること

これの最も良いところは、書き換え中に新しい機能を配信するという問題を解決できるところにあります。

このテクニックでは、コードを複製することはありません。新しい機能を2回実装する必要がないのです!

また、できるだけ早く新しいシステムを実稼働環境に配置することができます。フィードバックがより早く得られるため、作業が減り、故障のリスクが少なくなるのです。

最終的には、リライトを徐々にロールアウトできるようになります。6か月間コードを凍結する必要はもうありません。

新しくはない

今、紹介したテクニックは、マーティン・ファウラー氏によって「ストラングラーフィグ」パターンと呼ばれている。

つまりは、

『巨大なストラングラーイチジク』はやがて幻想的で美しい形となり、元の支持木である木を絞め殺すのだ

(注:ストラングラーイチジクは、イチジクの木の上のほうの枝に種を蒔き、 木をつたわりながらだんだんと下に下りていき、最後には自分の根を土に下ろしてしまいます。 そうやって何年もかけて、幻想的で美しい形へと成長していき、その木に絞められたイチジクの木は、 ストラングラーに絞め殺されてしまうのです。)

「ストラングル」(絞め殺す、抑え込むという意味)には暴力的な意味合いがあるかもしれませんが、比喩的には、古いシステムをゆっくりと取り除くという意味を込めてこういう言葉を使っているのです。完全なカットオーバーよりもリスクが低くなります。

これは「Working Effectively with Legacy Code(邦題:レガシーコード改善ガイド)」でマイケル・フェザーズ氏によって提唱されているものでもあります。

ラップクラステクニックは、既存のコードを変更せずに、システムに新しいビヘイビアを追加する方法であります。ビヘイビアを追加するには、既存のコードを新しいクラスにラップするのです。

新しい責任と古い責任との間にある程度の距離を置くようにします。

古いコードを扱うのが特に難しいときには、こうすることでより優れた設計にするための最初のステップとなるのです。

ドメイン駆動設計(DDD)にしている場合は、レガシーシステムを段階的に廃止するために、おすすめできるアプローチです。

レガシーシステムをブラックボックス(機能はわかっているが中の構造が不明の装置)だと思っているでしょう。 DDD原則の適用を開始するバブルコンテキストを作成します。このバブルコンテキストは、腐敗防止レイヤーを介して、古いレガシーシステム相互に作用するのです。

成長するバブルコンテキストに徐々に新しい機能が実装さる一方で、レガシーシステムはビジネスとの関連性をあまり持たなくなるでしょう。

レガシーシステムを永久に使わなくてもいい日がいつか来るのかもしれないですね🙌


コメントを読む

新着ピック  






















新着ニュース

コードを書かない系エンジニア(プリセールスエンジニア)の仕事と価値 | Developers.IO

RIZAP、本社社員を基本在宅勤務に IT活用で業務効率が向上、オフィス面積の削減も視野

[アップデート] 委任したメンバーアカウントで Config ルール/適合パックを Organizations 組織全体にデプロイできるようになりました | Developers.IO

新型コロナ禍で神戸市がマイクロソフトと包括連携、Power Virtual Agentsでチャットボット、Twilioで音声自動案内などを構築 | TechCrunch Japan

デジカメのWebカメラ化ソフト続々 ソニーも「対応を検討中」

懐かしのiPod Shuffle風 SpigenのAirPods Proカバー「クラシック・シャッフル」を試す

EC2の不揮発性ブロックストレージ「インスタンスストア」を使ってみよう! | Developers.IO

PDFベースの共同編集・電子署名サービスのAnvilがグーグル系VCから5億円超を調達 | TechCrunch Japan

Pythonのreduceと内包表記/ジェネレータ式を比較してみた | Developers.IO

「リングライト」おすすめ3選 Web会議や自撮りの表情をぐっと明るく【2020年最新版】

Zoom、エンドツーエンドの暗号化を有料プランのみにするのは「FBIに協力したいから」とCEO

5月のDeepRacerのF1 ProAm Event のタイムトライアルで3位になったので、EC2でのDeepRacerのローカルトレーニング 2020 環境構築手順を共有します | Developers.IO

5月のDeepRacerのF1 ProAm Event...

DevelopersIO / 4時間前


ベイエリアの黒人テックリーダーが人種差別的不公正に向けた行動を呼び掛け | TechCrunch Japan

英国チャレンジャーバンクのMonzoが最大120名を解雇へ、「経済状況」は未だに困難 | TechCrunch Japan

[アップデート]  S3 アクションの最終実行履歴が IAM からカンタンに確認できるようになりました | Developers.IO

“敏感な”ロボットフィンガー、コロンビア大が開発

電子の姿、AIで予測 数時間かかっていた計算を数秒で 東大と産総研

ツイキャス運営のモイ、音声SNS「パルミン」公開 2Dアバター同士で通話

楽天モバイルに聞く「Rakuten Mini」開発秘話 なぜ自社ブランド端末が必要だったのか

[Amazon SageMaker] イメージ分類のモデルをNeoで最適化して、RasPi4+OpenCV+Webカメラで使用してみました | Developers.IO

もっと見る
記事をPICKする
会員登録
Register
記事をPICKする

会員登録すると、もっと便利に利用できます。