この記事では、戦略モデルの最適化をif-elseビジネスディスパッチロジックに紹介します
アプリケーションシナリオ
最近、サービスを作成しました。クーポンのタイプresourceTypeとコード化されたresourceIdに従ってgrantTypeをクエリします。
実現する方法:
- クーポンタイプresourceType->に従って、クエリするデータテーブルを決定します。
- エンコーディングresourceId-> querygrantTypeによると
さまざまなデータベーステーブルに対応する、多くの種類のクーポンがあります。
- 赤い封筒
- ショッピングバウチャー
- QQメンバー
- テイクアウトメンバー
実際のクーポンはこれらよりはるかに多いです、この要求は私たちがそれを書くことです事業の割り当ての論理
最初のアイデアは、一般的にif-else、swtichの場合です。
switch(resourceType){
case "红包":
查询红包的派发方式
break;
case "购物券":
查询购物券的派发方式
break;
case "QQ会员" :
...
break;
case "外卖会员" :
...
break;
......
default : logger.info("查找不到该优惠券类型resourceType以及对应的派发方式");
break;
}
if-elseを次のように書くことには欠点があります。
- つまり、多くの判断があり、単一のifステートメントブロックのコードが多すぎる場合、if-elseコードブロック全体が長すぎて、読みやすさが低下します。
- また、if-elseコード全体に多くの行があるため、変更が不便であり、保守性が低くなります。
次に、if-elseを試みます事業の割り当て ロジックの最適化
戦略モード
定義については考えていません。いわば、戦略モデルの構造は次のとおりです。
- すべてのアルゴリズムをサポートするパブリック抽象クラス/インターフェース:つまり、ifが判断された後、インターフェースのメソッドが実行されます
- 特定の戦略の実装クラス:赤いエンベロープ配布メソッドを照会するためのロジックは1つのクラスで記述され、ショッピングクーポンは別のクラスで記述されます。
- クライアント呼び出しの入り口:パブリックインターフェイスへの参照を保持することにより、ポリモーフィズムを使用して、オブジェクトを作成するときに特定の戦略アルゴリズムを実行します。
コード上:
1つのパブリックインターフェイス
public abstract class Strategy{
//定义支持所有算法的公共接口
public abstract String query();
}
クライアントが特定の戦略を実行するとき、Strategy strategy = new ConcreteStrategy01()
第二に、特定の戦略実装クラス
パブリックインターフェイスを継承し、内部の抽象メソッドにコンテンツを追加します。
赤い封筒の配布方法を照会します。
//查询红包redPaper 发放方式
class ConcreteStrategy01 extends Strategy{
public String query(){
return "每周末9点发放";
}
}
ショッピングクーポンの発行方法を照会します。
//查询购物券shopping的发放方式
class ConcreteStrategy02 extends Strategy{
public String query(){
return "每周三20点发放";
}
}
三、クライアントコールの入り口
パブリックインターフェイス参照を保持するため、またはnew ConcreteStrategy01() 或者 new ConcreteStrategy02()
特定のポリシー実装を実現するためにポリモーフィズムを渡すことができないため[クエリの赤いエンベロープ、クエリクーポン]
class Context{
//持有公共接口的引用,后续通过多态来获取[红包、购物券]的实现类
Strategy strategy;
public Context(Strategy strategy){
this.strategy=strategy;
}
public String ContextInterface(){
return strategy.query();
}
}
クライアントは特定の戦略を実装します。
戦略モデルは特定のビジネスが割り当てられている場合でも、if-elseメソッドが使用されます、保守性の点で単純なif-elseよりも優れているだけです。特定のビジネスロジックを変更する場合は、対応するクラスを変更するだけで済みます。
例:赤いエンベロープ配布メソッドのクエリgrantType:
製品要件を確認します。クーポンタイプresourceTypeとコード化されたresourceIdに従って、配布メソッドgrantTypeをクエリします。
具体的な操作は、クーポンタイプresourceTypeでチェックするテーブルを決定し、コード化されたresourceIdに従って対応する配布メソッドgrantTypeを見つけることです。
class Test{
//客户端执行具体策略的测试方法
public static void main(String[] args){
String resourceType="红包";
String grantType;
switch(resourceType){
case "红包":
Context context01=new Context(new ConcreteStrategy01());
grantType=context01.ContextInterface();
break;
case "购物券":
Context context02=new Context(new ConcreteStrategy02());
grantType=context02.ContextInterface();
break;
default:
throw new IllegalStateException("Unexpected value: " + resourceType);
}
}
}
戦略の具体的な実装を簡素化しました
実行の結果:
戦略モデルの長所と短所
利点
- 保守性は良好です。赤いエンベロープ配布ロジックを変更する場合は、対応するクラスConcreteStrategy01を変更するだけで済みます。
不利益
- ビジネスディスパッチロジック全体を見落とすことはできません
- 戦略カテゴリーの増加