【ITニュース解説】How I Ended Up Using Adapter, Flyweight, and Strategy in One Project
2025年09月16日に「Medium」が公開したITニュース「How I Ended Up Using Adapter, Flyweight, and Strategy in One Project」について初心者にもわかりやすく解説しています。
ITニュース概要
あるプロジェクトでAdapter、Flyweight、Strategyというデザインパターンを組み合わせ、複雑な課題を解決した経験を紹介する。実務でデザインパターンがどのように活用されるかを学べる記事だ。
ITニュース解説
システム開発において、効率的で柔軟なコードを書くための工夫として「デザインパターン」という考え方がある。これは、過去のソフトウェア開発で繰り返し現れる問題に対する、再利用可能な解決策のひな形だ。ある開発チームが、多くの課題を抱える配達プラットフォームのプロジェクトで、このデザインパターンをどのように活用したのか、その具体的な事例を見ていこう。
このプロジェクトでは、複数の異なる配達サービス(例えばFedExやUPSのような運送会社)と連携する必要があった。それぞれの配達サービスは、システムとやり取りするための「窓口」(API)が異なっており、統一性がない。もし各サービスごとに異なるコードを直接書いてしまうと、新しい配達サービスが追加されるたびに多くの修正が必要になり、システムが複雑で扱いにくくなってしまうという問題があった。
ここで活躍したのが「Adapter(アダプター)パターン」だ。アダプターパターンは、互換性のないインターフェース(窓口)を持つクラス同士を連携させるためのパターンである。このプロジェクトでは、各配達サービス(FedExやUPS)の異なるAPIを、システム内部で定義した統一されたインターフェースに変換するアダプターを作成した。例えば、システムが「荷物を送って」と共通の命令を出すと、その命令を受け取ったアダプターが、連携しているサービス(FedExなど)固有の「荷物発送」のやり方に翻訳して実行する。これにより、システム側は各サービスの具体的な違いを意識することなく、あたかも同じサービスを使っているかのように統一的な方法で操作できるようになった。新しいサービスを追加する場合も、新しいアダプターを作るだけで既存のシステムに大きな変更を加える必要がなくなるため、システムの拡張性と保守性が大幅に向上した。
次に、この配達プラットフォームでは、標準配達、速達、同日配達など、様々な配達方法が存在し、それぞれ料金の計算方法が異なっていた。将来的に新しい配達方法や料金体系が追加される可能性も高かったため、配達方法が変わるたびに料金計算のコードを修正するのは非効率で、バグの温床にもなりかねない。
この課題を解決するために「Strategy(戦略)パターン」が導入された。戦略パターンは、アルゴリズム(処理の手順)の集まりを定義し、それぞれのアルゴリズムをカプセル化(独立した部品としてまとめる)し、それらを交換可能にするパターンだ。このプロジェクトでは、料金計算のロジックを、それぞれの配達方法に応じた独立した「戦略」オブジェクトとして定義した。例えば、「標準配達料金計算戦略」「速達料金計算戦略」といった具合だ。システムは、特定の配達依頼が来たときに、その依頼の配達方法に応じた適切な戦略オブジェクトを選択し、その戦略オブジェクトに料金計算を実行させる。これにより、新しい配達方法が追加された場合でも、既存のコードを変更せずに新しい料金計算戦略を定義して追加するだけで対応できるようになった。システムの中核部分に手を加える必要がないため、コードの変更によるリスクを最小限に抑えつつ、柔軟に機能を追加できるようになったのだ。
さらに、このプラットフォームでは、毎日大量の配達依頼(オーダー)を処理する必要があった。もしそれぞれの配達依頼オブジェクトが、出発地、目的地、配達タイプといったすべての情報を持つと、メモリ使用量が膨大になり、システムのパフォーマンスに影響を与えてしまう可能性がある。多くの配達依頼は、共通の出発地や目的地、配達タイプを持つことが考えられるため、これらの情報を個々のオブジェクトがそれぞれ持つのは無駄が多い。
この問題に対処するために「Flyweight(フライウェイト)パターン」が適用された。フライウェイトパターンは、共有可能なオブジェクトを効率的に管理することで、オブジェクトの生成数を減らし、メモリ使用量を削減するパターンだ。このパターンでは、オブジェクトの状態を「共通状態(Intrinsic State)」と「固有状態(Extrinsic State)」に分割する。 「共通状態」とは、複数のオブジェクトで共有できる、不変のデータのことだ。例えば、配達依頼の出発地、目的地、配達タイプといった情報は、多くの配達依頼で共通して使われることが多い。これらの情報は「フライウェイト」オブジェクトとして一つだけ作成され、メモリ上にプールされる。そして、複数の配達依頼オブジェクトが、この共有されたフライウェイトオブジェクトを参照する形になる。 一方、「固有状態」とは、個々のオブジェクトに固有の、変化するデータのことだ。例えば、個々の配達依頼に割り振られる注文IDや、現在の配達状況などは、各依頼に固有の情報として、それぞれの配達依頼オブジェクトが自身で保持する。 このように、共通の状態を複数のオブジェクトで共有することで、メモリ上に同じ情報が重複して存在するのを避け、大量のオブジェクトを扱う際のメモリ使用量を大幅に削減し、システムの処理速度と応答性を向上させることができた。
これらのアダプター、戦略、フライウェイトというデザインパターンを組み合わせることで、配達プラットフォームは、異なるサービスとの柔軟な連携、多様な料金計算ロジックへの対応、そして大量のデータ処理における効率的なメモリ管理を実現した。システムエンジニアを目指す上で、このようなデザインパターンを理解し、適切に活用する能力は、将来的に堅牢で保守しやすいソフトウェアを設計するために不可欠なスキルとなるだろう。これらのパターンは、一見複雑に見えるかもしれないが、それぞれの役割と解決する課題を理解することで、より良いソフトウェア設計への道が開かれる。