組合模式,將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。簡單理解就是,整體和部分的接口定義是一致的,在使用的時候,只有調用整體的接口就行,部分接口有新增的自定義,組合到整體就可以了。
spring cloud security組合設計模式的實現
在spring cloud security中訪問令牌的產生實現,就是一個典型的組合設計模式。訪問令牌的接口TokenGranter定義如下:
public interface TokenGranter {
OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest);
}
ResourceOwnerPasswordTokenGranter,支持密碼類型獲取令牌。
ImplicitTokenGranter,支持隱式類型獲取令牌。
AuthorizationCodeTokenGranter,支持授權碼類型獲取令牌。
ClientCredentialsTokenGranter,支持客戶端類型獲取令牌。
RefreshTokenGranter,支持刷新令牌。
CompositeTokenGranter,組合類。
類結構圖如下:
除了CompositeTokenGranter以外,每個類都實現了TokenGranter接口,並且滿足各類獲取令牌的功能。CompositeTokenGranter類,組合了所有的實現,在業務調用中直接調用CompositeTokenGranter即可。CompositeTokenGranter的實現類,如下:
public class CompositeTokenGranter implements TokenGranter {
private final List<TokenGranter> tokenGranters;
public CompositeTokenGranter(List<TokenGranter> tokenGranters) {
this.tokenGranters = new ArrayList<TokenGranter>(tokenGranters);
}
public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {
for (TokenGranter granter : tokenGranters) {
OAuth2AccessToken grant = granter.grant(grantType, tokenRequest);
if (grant!=null) {
return grant;
}
}
return null;
}
public void addTokenGranter(TokenGranter tokenGranter) {
if (tokenGranter == null) {
throw new IllegalArgumentException("Token granter is null");
}
tokenGranters.add(tokenGranter);
}
}
價格或者優惠券擴展字段的設計實現
在價格或優惠券的設計中,自定義的字段在數據庫中使用ext擴展字段保存,不同業務對象自定義json數據。生成json對象的接口設計如下:
public interface PriceExtGenerator {
/**
* 生成
*/
Map<String, Object> generate(PriceSaveDto priceSaveDto);
}
LongDistancePriceExtGenerator,遠途費ext生成器
GuaranteedPriceExtGenerator,保底費ext屬性生成器
DailyRentPriceExtGenerator,日租費ext屬性生成器
CompositePriceExtGenerator,組合類
類結構圖如下:
CompositePriceExtGenerator 實現類如下:
public class CompositePriceExtGenerator implements PriceExtGenerator {
private Map<String, PriceExtGenerator> priceExtGeneratorMap;
private CompositePriceExtGenerator() {
priceExtGeneratorMap = ImmutableMap.of(
PriceCodeEnum.DAILY_RENT_PRICE.name(), new DailyRentPriceExtGenerator(),
PriceCodeEnum.GUARANTEED_PRICE.name(), new GuaranteedPriceExtGenerator(),
PriceCodeEnum.LONG_DISTANCE_PRICE.name(), new LongDistancePriceExtGenerator());
}
/**
* 生成
*/
@Override
public Map<String, Object> generate(PriceSaveDto priceSaveDto) {
String priceCode;
PriceExtGenerator priceExtGenerator;
if (Objects.isNull(priceSaveDto)
|| Objects.isNull(priceCode = priceSaveDto.getCode())
|| Objects.isNull(priceExtGenerator = PriceExtGeneratorManagerItem.INSTANCE.priceExtGeneratorMap.get(priceCode))) {
return null;
}
return priceExtGenerator.generate(priceSaveDto);
}
}