天天看點

spring自動注入接口的多個實作類(結合政策設計模式)

在使用spring開發的時候,有時候會出現一個接口多個實作類的情況,但是有沒有有時候有這樣一種情況,就是你的邏輯代碼裡面還不知道你需要使用哪個實作類,就是比如說:你去按摩,按摩店裡面有幾種會員打折,比如有,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<String,DiscountStrategy> discountStrategyMap = new HashMap<>();
    // 構造函數,如果你是集合接口對象,那麼久會把spring容器中所有關于該接口的子類,全部抓出來放入到集合中
    @Authwired 
    public DisCountStrageService(List<DiscountStrategy> 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模式不支援,會報錯,因為以前的方式注入是通過配置檔案去注入的,需要去修改一個applicationContext的配置檔案