前言
Java 8 函数式编程可以简化传统设计模式使用方式,下面看两个重构例子,用Functional Interface 实现策略工厂。
案例一
- 原始实现:
switch (agreementBuildItem.getSignNaturalType()) {
case LEGAL_PERSON:
party = newParty(company.getLegalPerson());
break;
case LEGAL_PERSON_SPOUSE:
party = newParty(company.getLegalPerson().getSpouse());
break;
case ACTUAL_CONTROLLER:
party = newParty(company.getActualController());
break;
case ACTUAL_CONTROLLER_SPOUSE:
party = newParty(company.getActualController().getSpouse());
break;
case LEGAL_PERSON_ALIPAY_ACCOUNT:
party = newParty(company.getLegalPerson().getAlipayAccountData());
break;
case ACTUAL_CONTROLLER_ALIPAY_ACCOUNT:
party = newParty(company.getActualController().getAlipayAccountData());
break;
case COMPANY_TRADE_ALIPAY_ACCOUNT:
party = newParty(company.getAlipayAccountMap().get("TRADE_ALIPAY_ACCOUNT"));
break;
default:
throw new UnsupportedOperationException();
}
- 重构后实现:
/**
* @author zhengyu.nie
* 2020/11/24.
*/
public final class PartyFactory {
private PartyFactory() {}
private static final Function> LEGAL_PERSON_PARTY_FUNC = company
-> newParty(company.getLegalPerson());
private static final Function> LEGAL_PERSON_SPOUSE_PARTY_FUNC = company
-> newParty(company.getLegalPerson().getSpouse());
private static final Function> ACTUAL_CONTROLLER_PARTY_FUNC = company
-> newParty(company.getActualController());
private static final Function> ACTUAL_CONTROLLER_SPOUSE_PARTY_FUNC = company
-> newParty(company.getActualController().getSpouse());
private static final Function> LEGAL_PERSON_ALIPAY_PARTY_FUNC = company
-> newParty(company.getLegalPerson().getAlipayAccountData());
private static final Function> ACTUAL_CONTROLLER_ALIPAY_PARTY_FUNC = company
-> newParty(company.getActualController().getAlipayAccountData());
private static final Function> COMPANY_TRADE_ALIPAY_ACCOUNT_PARTY_FUNC = company
-> newParty(company.getAlipayAccountMap().get("TRADE_ALIPAY_ACCOUNT"));
private static final Map>> PARTY_FUNC_MAP = Maps.newHashMap();
static {
PARTY_FUNC_MAP.put(SignNaturalType.LEGAL_PERSON, LEGAL_PERSON_PARTY_FUNC);
PARTY_FUNC_MAP.put(SignNaturalType.LEGAL_PERSON_SPOUSE, LEGAL_PERSON_SPOUSE_PARTY_FUNC);
PARTY_FUNC_MAP.put(SignNaturalType.ACTUAL_CONTROLLER, ACTUAL_CONTROLLER_PARTY_FUNC);
PARTY_FUNC_MAP.put(SignNaturalType.ACTUAL_CONTROLLER_SPOUSE, ACTUAL_CONTROLLER_SPOUSE_PARTY_FUNC);
PARTY_FUNC_MAP.put(SignNaturalType.LEGAL_PERSON_ALIPAY_ACCOUNT, LEGAL_PERSON_ALIPAY_PARTY_FUNC);
PARTY_FUNC_MAP.put(SignNaturalType.ACTUAL_CONTROLLER_ALIPAY_ACCOUNT, ACTUAL_CONTROLLER_ALIPAY_PARTY_FUNC);
PARTY_FUNC_MAP.put(SignNaturalType.COMPANY_TRADE_ALIPAY_ACCOUNT, COMPANY_TRADE_ALIPAY_ACCOUNT_PARTY_FUNC);
}
public static Optional getParty(Company company, SignNaturalType signNaturalType) {
Function> companyOptionalFunction = PARTY_FUNC_MAP.get(signNaturalType);
if (companyOptionalFunction == null) {
throw new UnsupportedOperationException();
}
Optional party = companyOptionalFunction.apply(company);
return party;
}
}
案例二
- 原始实现
public CreditSchema convertToCreditSchema(CreditSchemaDTO creditSchemaDto) {
CreditSchemaBuilder creditSchemaBuilder = CreditSchema.builder();
creditSchemaBuilder.creditNo(creditSchemaDto.getCreditNo());
creditSchemaBuilder.fgNo(creditSchemaDto.getFgNo());
creditSchemaBuilder.institutionCreditNo(creditSchemaDto.getInstitutionCreditNo());
creditSchemaBuilder.institutionCreditQuotaNo(creditSchemaDto.getInstitutionCreditQuotaNo());
creditSchemaBuilder.riskCreditNo(creditSchemaDto.getRiskCreditNo());
creditSchemaDto.getFactors().forEach(factor -> {
if (factor instanceof RepaymentDayFactor) {
RepaymentDayFactor repaymentDayFactor = (RepaymentDayFactor)factor;
creditSchemaBuilder.repaymentDay(repaymentDayFactor.getRepaymentDay());
}
if (factor instanceof RepaymentMethodFactor) {
RepaymentMethodFactor repaymentMethodFactor = (RepaymentMethodFactor)factor;
creditSchemaBuilder.repaymentMethod(repaymentMethodFactor.getValue().name());
}
if (factor instanceof InterestRateFactor) {
InterestRateFactor interestRateFactor = (InterestRateFactor)factor;
creditSchemaBuilder.interestRate(interestRateFactor.getValue());
}
………………
}
);
return creditSchemaBuilder.build();
}
- 重构后实现
public CreditSchema convertToCreditSchema(CreditSchemaDTO creditSchemaDto) {
CreditSchemaBuilder creditSchemaBuilder = CreditSchema.builder();
creditSchemaBuilder.creditNo(creditSchemaDto.getCreditNo());
creditSchemaBuilder.fgNo(creditSchemaDto.getFgNo());
creditSchemaBuilder.institutionCreditNo(creditSchemaDto.getInstitutionCreditNo());
creditSchemaBuilder.institutionCreditQuotaNo(creditSchemaDto.getInstitutionCreditQuotaNo());
creditSchemaDto.getFactors().forEach(factor -> creditResultFactorAccessor.access(creditSchemaBuilder, factor));
return creditSchemaBuilder.build();
}
/**
* @author zhengyu.nie
* 2020/11/9.
*/
@Component
class CreditResultFactorAccessor {
private static final BiConsumer CREDIT_SCHEMA_FACTOR
= (creditSchemaBuilder, repaymentMethodFactor) ->
creditSchemaBuilder.repaymentMethod(String.valueOf(repaymentMethodFactor.getValue()));
private static final BiConsumer INTEREST_RATE_FACTOR
= (creditSchemaBuilder, interestRateFactor) -> {
creditSchemaBuilder.interestUnit(String.valueOf(interestRateFactor.getUnit()));
creditSchemaBuilder.interestRate(interestRateFactor.getValue());
};
private static final BiConsumer CREDIT_SCHEMA_LOAN_TERM_FACTOR
= (creditSchemaBuilder, loanTermFactor) -> {
creditSchemaBuilder.loanTermUnit(String.valueOf(loanTermFactor.getUnit()));
creditSchemaBuilder.loanTerm(loanTermFactor.getValue());
};
private static final BiConsumer CREDIT_SCHEMA_EXPIRATION_FACTOR
= (creditSchemaBuilder, expirationFactor) -> {
creditSchemaBuilder.creditStartTime(expirationFactor.getStartTime());
creditSchemaBuilder.creditEndTime(expirationFactor.getEndTime());
};
private static final BiConsumer LOAN_SCHEMA_REPAYMENT_DAY_FACTOR
= (creditSchemaBuilder, repaymentDayFactor) -> creditSchemaBuilder.repaymentDay(
repaymentDayFactor.getRepaymentDay());
private static final Map consumerMap = new HashMap<>();
static {
consumerMap.put(FactorTypeEnum.REPAYMENT_METHOD, CREDIT_SCHEMA_FACTOR);
consumerMap.put(FactorTypeEnum.INTEREST_RATE, INTEREST_RATE_FACTOR);
consumerMap.put(FactorTypeEnum.LOAN_TERM, CREDIT_SCHEMA_LOAN_TERM_FACTOR);
consumerMap.put(FactorTypeEnum.REPAYMENT_DAY, LOAN_SCHEMA_REPAYMENT_DAY_FACTOR);
consumerMap.put(FactorTypeEnum.EXPIRATION_DATE, CREDIT_SCHEMA_EXPIRATION_FACTOR);
}
public void access(CreditSchemaBuilder creditSchemaBuilder, Factor factor) {
if (consumerMap.containsKey(factor.getFactorType())) {
consumerMap.get(factor.getFactorType()).accept(creditSchemaBuilder, factor);
}
}
}