レガシーコードを扱いやすくするためのデザインパターン

レガシーコードを扱うのは、地雷原を歩いているような感覚になることがあります。
「今にも何かが壊れそうだけど、どこでどうなるかわからない...」

そんなときこそ、デザインパターンが強力な武器になります。

この記事では、Pythonで実装されたサンプルコードを使いながら、レガシーコードの整理や拡張に役立つ代表的なデザインパターンを紹介します。


🧩 1. アダプターパターン(Adapter Pattern)

課題: 古いコードのインターフェースが、新しいシステムに合わない
解決策: ラッパーを使ってインターフェースを変換する

例:

# legacy_system.py
class LegacyPaymentProcessor:
    def make_payment(self, amount):
        print(f"[Legacy] ¥{amount} の支払いを処理中")
# adapter.py
class PaymentInterface:
    def pay(self, amount):
        raise NotImplementedError

class LegacyAdapter(PaymentInterface):
    def __init__(self, legacy_processor):
        self.legacy_processor = legacy_processor

    def pay(self, amount):
        return self.legacy_processor.make_payment(amount)

使い方

adapter = LegacyAdapter(LegacyPaymentProcessor())
adapter.pay(1000)

✅ これで PaymentInterface を通じて新旧システムの橋渡しができます。


🏗️ 2. ファサードパターン(Facade Pattern)

課題: 古いサブシステムが複雑すぎて使いにくい
解決策: 単一の簡易インターフェースを用意して操作を一元化する

例:

class LegacyAuth:
    def check_user(self, username, password):
        return username == "admin" and password == "1234"

class LegacyLogger:
    def log(self, msg):
        print(f"[LOG]: {msg}")
class AuthFacade:
    def __init__(self):
        self.auth = LegacyAuth()
        self.logger = LegacyLogger()

    def login(self, username, password):
        if self.auth.check_user(username, password):
            self.logger.log(f"{username} がログインしました。")
            return True
        self.logger.log("ログイン失敗。")
        return False

✅ 複雑な処理を隠し、使いやすいインターフェースにまとめました。


🧪 3. デコレーターパターン(Decorator Pattern)

課題: 既存のコードを変更せずに機能を追加したい
解決策: クラスをラップして動作を拡張する

例:

class LegacyReporter:
    def report(self):
        print("基本レポートを生成中...")

class TimestampedReporter:
    def __init__(self, wrapped):
        self.wrapped = wrapped

    def report(self):
        from datetime import datetime
        print(f"レポート生成時刻: {datetime.now()}")
        self.wrapped.report()

✅ 元のクラスを一切触れずに、時間スタンプを追加できます。


🧰 4. ストラテジーパターン(Strategy Pattern)

課題: アルゴリズムや処理方法を柔軟に切り替えたい
解決策: 処理を外部化し、戦略として注入できるようにする

例:

class LegacySorter:
    def sort(self, data):
        return sorted(data)

class ReverseSortStrategy:
    def sort(self, data):
        return sorted(data, reverse=True)

class SorterContext:
    def __init__(self, strategy):
        self.strategy = strategy

    def sort(self, data):
        return self.strategy.sort(data)

✅ ソート方法を柔軟に差し替えることが可能です。


🚦 5. プロキシパターン(Proxy Pattern)

課題: 既存の機能にログや制御を追加したいが、直接変更できない
解決策: アクセスを仲介するクラスを作成する

例:

class LegacyDatabase:
    def query(self, sql):
        print(f"SQL 実行中: {sql}")
        return f"結果: {sql}"

class LoggingProxy:
    def __init__(self, db):
        self.db = db

    def query(self, sql):
        print(f"[LOG] クエリ実行前: {sql}")
        return self.db.query(sql)

✅ ログ機能などを追加するのに最適な方法です。


✨ まとめ

デザインパターンを活用することで、レガシーコードともうまく付き合っていけます。

ポイント:

  • 包む(Wrap)・分離する(Isolate)・差し替える(Inject)
  • 少しずつ安全にリファクタリングする
  • ユニットテストを必ず書く

もしあなたが今、実際のレガシーコードで困っているなら、そのコードを共有してくれれば一緒に改善していきましょう 💬✨

Related Posts

Articles

Our Products


Related Posts

Articles

Our Products


Get in Touch with us

Speak to Us or Whatsapp(+66) 83001 0222

Chat with Us on LINEiiitum1984

Our HeadquartersChanthaburi, Thailand