ホームページ > ウェブフロントエンド > jsチュートリアル > 戦略パターンを使用してオーバーコンディショニングを回避する

戦略パターンを使用してオーバーコンディショニングを回避する

Linda Hamilton
リリース: 2025-01-12 06:04:42
オリジナル
732 人が閲覧しました

数週間前、私は Globo Player のソリューションに取り組みました。そこでは、実行中にソフトウェアの特定の動作をアクティブ化および非アクティブ化する必要がありました。このタイプのニーズは、一般的に if-else や switch などの連鎖条件を使用して解決されますが、このアプローチは常に理想的であるとは限りません。

この記事では、この課題を完全に満たし、さまざまなプログラミング シナリオに適用できるソリューションを紹介します。

どの戦略を使用すればよいでしょうか?

あなたが未知の目的地に到着したところだと想像してください。空港を出るとき、ホテルに行くにはいくつかの選択肢があります。最も安価な方法は自転車をレンタルすることですが、これには時間がかかります。バスを利用すると少し高くなりますが、より早く安全に到着します。最後に、レンタカーを借りるのが最も早いオプションですが、最も高価でもあります。

Usando Strategy Pattern para evitar condicionamento exagerado

この状況で最も重要な点は、選択した戦略に関係なく、最終的な目的は同じである、つまりホテルに到着するということを理解することです。

このアナロジーはソフトウェア開発にも適用できます。異なるプロセスが同じ目的を達成しようとするシナリオに対処する場合、戦略設計パターンを使用すると役立ちます。

戦略なしでプログラムを作成すると...

当座普通、またはプレミアムなど、顧客の口座タイプに基づいて手数料を計算できる銀行システムを開発する必要があると想像してください。これらの計算は実行時に実行する必要があり、コード フローを適切な計算に正しく導く実装が必要です。

原則として、一般的なアプローチは、連鎖した条件文の単純な構造を使用して、問題を迅速かつ機能的に解決することです。

class Banco {
  calcularTaxa(tipoConta, valor) {
    if (tipoConta === "corrente") {
      return valor * 0.02; // 2% de taxa
    } else if (tipoConta === "poupanca") {
      return valor * 0.01; // 1% de taxa
    } else if (tipoConta === "premium") {
      return valor * 0.005; // 0,5% de taxa
    } else {
      throw new Error("Tipo de conta não suportado.");
    }
  }
}

const banco = new Banco();
const taxa = banco.calcularTaxa("corrente", 1000); // Exemplo: R00
console.log(`A taxa para sua conta é: R$${taxa}`);
ログイン後にコピー
ログイン後にコピー

このソリューションは単純なシナリオではうまく機能しますが、銀行が将来さらに 5 つの口座タイプを追加する必要がある場合はどうなりますか?

calcularTaxa(tipoConta, valor) {
  if (tipoConta === "corrente") {
    return valor * 0.02; // 2% de taxa
  } else if (tipoConta === "poupanca") {
    return valor * 0.01; // 1% de taxa
  } else if (tipoConta === "premium") {
    return valor * 0.005; // 0,5% de taxa
  } else if (tipoConta === "estudante") {
    return valor * 0.001; // 0,1% de taxa
  } else if (tipoConta === "empresarial") {
    return valor * 0.03; // 3% de taxa
  } else if (tipoConta === "internacional") {
    return valor * 0.04 + 10; // 4% + taxa fixa de R
  } else if (tipoConta === "digital") {
    return valor * 0.008; // 0,8% de taxa
  } else if (tipoConta === "exclusiva") {
    return valor * 0.002; // 0,2% de taxa
  } else {
    throw new Error("Tipo de conta inválido!");
  }
}
ログイン後にコピー
ログイン後にコピー

ここで、コードに重大な制限が現れ始めます。このアプローチの問題を調べてみましょう:

1.スケーラビリティが低い

新しいアカウント タイプを追加する必要があるたびに、calculateRate メソッドを変更する必要があります。これにより、条件文の数が継続的に増加し、コードがより複雑になり、管理が難しくなります。

2.高い依存性

レート計算ロジックは、calculateRate メソッドに完全に結合されています。ある種類のアカウントに変更を加えると、他の種類のアカウントに誤って影響を与える可能性があり、バグが発生するリスクが高まります。

3.コードの繰り返し

金額 * 手数料などの同様のスニペットは、アカウントの種類ごとに複製されます。これはコードの再利用を減らし、DRY (同じことを繰り返さない) 原則に違反します。

次のステップでは、戦略パターンがこれらの問題をどのように解決し、よりクリーンでスケーラブルなモジュール化されたコードを促進できるかを見ていきます。

戦略は一度に一つ!

上記の問題を回避するために、ソフトウェアでは各アカウント タイプを独立したエンティティとして扱います。これは、アカウントの種類ごとに特定の料金計算があり、将来のその他の関連する動作が発生する可能性があるためです。

すべての操作を解決する CalculateRate メソッドを含む Bank クラスを作成する代わりに、口座の種類ごとにクラスを作成しましょう。

class Banco {
  calcularTaxa(tipoConta, valor) {
    if (tipoConta === "corrente") {
      return valor * 0.02; // 2% de taxa
    } else if (tipoConta === "poupanca") {
      return valor * 0.01; // 1% de taxa
    } else if (tipoConta === "premium") {
      return valor * 0.005; // 0,5% de taxa
    } else {
      throw new Error("Tipo de conta não suportado.");
    }
  }
}

const banco = new Banco();
const taxa = banco.calcularTaxa("corrente", 1000); // Exemplo: R00
console.log(`A taxa para sua conta é: R$${taxa}`);
ログイン後にコピー
ログイン後にコピー

これにより、各計算操作がアカウント タイプの特定の範囲内に維持されることが保証されます。これで、各タイプのアカウントに焦点を当てた分離された動作が得られました。

Usando Strategy Pattern para evitar condicionamento exagerado


戦略に基づくソリューション アーキテクチャ

しかし、目的のアカウント選択はどこにあるのでしょうか?

calcularTaxa(tipoConta, valor) {
  if (tipoConta === "corrente") {
    return valor * 0.02; // 2% de taxa
  } else if (tipoConta === "poupanca") {
    return valor * 0.01; // 1% de taxa
  } else if (tipoConta === "premium") {
    return valor * 0.005; // 0,5% de taxa
  } else if (tipoConta === "estudante") {
    return valor * 0.001; // 0,1% de taxa
  } else if (tipoConta === "empresarial") {
    return valor * 0.03; // 3% de taxa
  } else if (tipoConta === "internacional") {
    return valor * 0.04 + 10; // 4% + taxa fixa de R
  } else if (tipoConta === "digital") {
    return valor * 0.008; // 0,8% de taxa
  } else if (tipoConta === "exclusiva") {
    return valor * 0.002; // 0,2% de taxa
  } else {
    throw new Error("Tipo de conta inválido!");
  }
}
ログイン後にコピー
ログイン後にコピー

連鎖した意思決定構造 (if-else) を作成する代わりに、Bank クラスのコンストラクターでアカウント、ストラテジーを渡すことを選択したことに注意してください。これにより、setConta メソッドは実行時に銀行をインスタンス化するときに目的の口座タイプを選択できるようになります。レートの計算は this.conta.calcularTaxa(valor) を通じて実行されます。

class ContaCorrente {
  calcularTaxa(valor) {
    return valor * 0.02; // 2% de taxa
  }
}

class ContaPoupanca {
  calcularTaxa(valor) {
    return valor * 0.01; // 1% de taxa
  }
}

class ContaPremium {
  calcularTaxa(valor) {
    return valor * 0.005; // 0,5% de taxa
  }
}
ログイン後にコピー

このモデルを使用すると、戦略パターンを簡単な方法で適用でき、より柔軟でスケーラブルで結合度の低い実装が保証されます。

すべてにおいて戦略を使用できますか?

ストラテジー パターンは、実行コードをさまざまな条件やタイプに直接結合することなく、実行時の操作の動作を変更する必要がある場合の強力なソリューションです。このパターンは、操作の動作がコンテキストに応じて変化する可能性があり、代替手段が互いに独立しているシナリオに最適です。

戦略パターンを使用する場合

  • バリアント動作: 特定の条件 (銀行の例では異なる口座タイプなど) に応じてシステムの動作を動的に変更する必要がある場合。
  • 複雑な条件文を避ける: 決定ロジックが複数の if-else や switch などの多くのフロー制御構造に基づいている場合、コードの保守が困難になります。
  • メンテナンスと拡張の容易さ: 既存のコードを変更せずに新しい動作を追加したい場合は、新しい戦略クラスを作成するだけです。
  • 動作の分離: 特定の動作をさまざまなクラスで分離し、コードをよりモジュール化して柔軟にしたい場合。

Strategy を使用することで、システムのより良いメンテナンスと拡張を促進するだけでなく、コードがよりクリーンでモジュール化され、柔軟になることを保証します。

以上が戦略パターンを使用してオーバーコンディショニングを回避するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート