一、整體設計思路
為了實現在短信服務提供商變更時,不修改現有代碼就能無縫切換到新服務實現,可采用策略模式結合依賴注入以及配置中心化管理的方式來設計軟件系統。
二、 具體實現步驟
1. 定義統一接口(以短信服務為例,接口命名為 SmsService
)
創建一個抽象的接口,用于定義該類服務的統一行為規范,所有具體服務提供商的實現類都需要遵循這個接口所定義的方法。例如:
public interface SmsService {Response sendSms(Request request);
}
這里定義了 sendSms
方法,意味著不同短信服務提供商的具體實現類都要實現該方法來完成發送短信的操作,從外部調用角度來看,調用這個接口的 sendSms
方法就能獲取相應的短信發送服務結果,無需關心具體是由哪個服務商來提供服務。
2. 實現具體服務提供商
針對不同的短信服務提供商,分別實現上述定義的 SmsService
接口,并在各自的實現類中封裝對應服務商特有的業務邏輯。比如:
// 阿里云短信服務實現
@Service("aliyunSmsService")
public class AliyunSmsServiceImpl implements SmsService {public AliyunSmsServiceImpl(@Value("${sms.aliyun.accessKey}") String accessKey,@Value("${sms.aliyun.secretKey}") String secretKey) { /* 初始化相關參數 */ }@Overridepublic Response sendSms(Request request) {// 此處編寫調用阿里云短信 API 的具體邏輯}
}// 騰訊云短信服務實現
@Service("tencentSmsService")
public class TencentSmsServiceImpl implements SmsService {public TencentSmsServiceImpl(@Value("${sms.tencent.appId}") String appId,@Value("${sms.tencent.secretKey}") String secretKey) { /* 初始化相關參數 */ }@Overridepublic Response sendSms(Request request) {// 編寫調用騰訊云短信 API 的具體邏輯}
}
3. 配置文件管理(以 application.yml
為例)
在配置文件中指定當前使用的短信服務提供商,同時配置各個提供商所需的相關參數,方便后續根據配置來獲取和使用對應的服務。示例配置如下:
sms:provider: aliyun # 可選值如: aliyun, tencent 等,代表不同的短信服務提供商aliyun:accessKey: your-aliyun-keysecretKey: your-aliyun-secrettencent:appId: your-tencent-app-idsecretKey: your-tencent-secret
4. 動態選擇服務實現(配置類)
創建一個 Spring 配置類,用于根據配置文件中指定的短信服務提供商名稱,從 Spring 容器中獲取對應的具體服務實現類實例,并將其作為一個 Bean
提供給其他需要使用短信服務的地方。代碼如下:
@Configuration
public class SmsServiceConfig {@Beanpublic SmsService smsService(@Value("${sms.provider}") String provider,Map<String, SmsService> smsServiceMap) {return smsServiceMap.get(provider + "SmsService");}
}
這里的 smsService
方法被標注為 @Bean
,意味著該方法返回值會作為 Bean
被添加到 Spring 容器中供其他組件依賴注入使用。在方法參數中:
@Value("${sms.provider}") String provider
用于從配置文件中獲取當前指定的短信服務提供商名稱(如"aliyun"
或"tencent"
等)。Map<String, SmsService> smsServiceMap
是 Spring 容器自動管理的一個Map
結構,它的鍵(String
)是各個實現了SmsService
接口的Bean
名稱(像"aliyunSmsService"
、"tencentSmsService"
等,由@Service
注解指定名稱時確定),值(SmsService
)就是對應的實現了SmsService
接口的具體短信服務Bean
實例。Spring 容器在初始化SmsServiceConfig
類并處理smsService
這個@Bean
方法時,會自動查找類型為Map<String, SmsService>
的Bean
(也就是收集了所有實現Sms