Spring自動注入インタフェースの複数の実装クラス(ポリシー設計モードと組み合わせた)


springを使って開発する時、時には1つのインタフェースの複数の実現類の情況が現れて、しかし時にはこのような情況があるかどうか、あなたの論理コードの中でまだどの実現類を使う必要があるか分からないで、例えば:あなたはマッサージに行って、マッサージ店の中でいくつかの会員の割引があって、例えばvip、svipと普通のユーザーがあって、マッサージ店では、これらの会員に対して異なる割引を定義し、ユーザーごとに異なる会員によって異なる消費状況を計算する必要がありますか?
このような場合でも、一般の人にとっては、第一眼は間違いなくif elseを直接加えて判断すればいいのです
このようにして、機能を実現するには、間違いなく大丈夫です.もし後でこのマッサージ店に会員が追加されたら、論理コードを修正してif elseを追加しなければなりませんか.そうすれば、システムアーキテクチャ設計の開閉原則に違反し、if elseを書くこともあなたのコードを優雅に見えません.
コードではDiscountStrategyインタフェースクラスを定義できます
public interface DiscountStrategy {

    public String getType();
    public double disCount(double fee);

}

そして彼のいくつかの実装クラスを書いています
一般ユーザー実装クラス
@Service
public class NormalDisCountService implements  DiscountStrategy {


    public String getType(){
        return "normal";
    }

    public double disCount(double fee){
        return fee * 1;
    }

}

会員実現クラス
public class VipDisCountService  implements  DiscountStrategy{


    public String getType(){
        return "vip";
    }

    public double disCount(double fee){
        return fee * 0.8;
    }

}

svipスーパー会員実現クラス
@Service
public class SVipDisCountService  implements  DiscountStrategy {


    public String getType(){
        return "svip";
    }

    public double disCount(double fee){
        return fee * 0.5;
    }

}

そしてユーザーが入ってきて消費すると、現在の身分によって割引されます.
mapコレクションを定義し、すべてのインプリメンテーションクラスをこのコレクションに挿入し、現在の会員タイプに応じて異なる操作を行います.
@Service
public class DisCountStrageService {


    Map discountStrategyMap = new HashMap<>();
    //     ,          ,     spring             ,           
    public DisCountStrageService(List discountStrategys){
        for (DiscountStrategy discountStrategy: discountStrategys) {
            discountStrategyMap.put(discountStrategy.getType(),discountStrategy);
        }
    }

    public double disCount(String type,Double fee){
        DiscountStrategy discountStrategy =discountStrategyMap.get(type);
        return discountStrategy.disCount(fee);
    }
}

テストクラス
@RunWith(SpringRunner.class)
@SpringBootTest
public class MzySpringModeApplicationTests {

    @Autowired
    OrderService orderService;

    @Autowired
    DisCountStrageService disCountStrageService;


    @Test
    public void contextLoads() {
        //orderService.saveOrder();
        double vipresult = disCountStrageService.disCount("vip",100d);
        double svipresult = disCountStrageService.disCount("svip",100d);
        double normalresult = disCountStrageService.disCount("normal",100d);
        System.out.println(vipresult);
        System.out.println(svipresult);
        System.out.println(normalresult);
    }


}

これがjava設計モードのポリシーモードであり,構造関数でlist集合に注入されるにすぎない.
後でマッサージ店が会員システムを増やし続けても、例えばブラックカードユーザーは、以前のコードを修正する必要がなく、インタフェースの実装クラスを書くだけで、システムアーキテクチャの開閉原則に違反することはありません(修正閉鎖、拡張開放)
注意:上記の方法はspringbootプロジェクトにしか適用できません.以前のspringmvcモードではサポートされていません.エラーが発生します.以前の方法では、注入はプロファイルによって注入されたので、アプリケーションContextのプロファイルを変更する必要があります.