在java8中,我们可以使用接口作为方法参数。
例如:
chargeCard可以有两种类型的card(1- cardDetailDto 2-cardReferenceDto), 因此在这里,可以用接口作为参数。
public interface PaymentProvider {
PaymentsResponse chargeCard(Charge charge);
}
在Charge接口中,定义了一个返回PaymentsRequest的一个方法。
public interface Charge {
PaymentsRequest generatePaymentsRequest();
}
封装两个Dto ChargeCardReferenceDto和ChargeCardDetailDto,继承BaseChargeDto
@MappedSuperclass
@Data
public class BaseChargeDto {
private String employerReference;
private BigDecimal cost;
}
@EqualsAndHashCode(callSuper = true)
@Builder
@Value
public class ChargeCardReferenceDto extends BaseChargeDto {
String cardReference;
}
@Builder
@Value
@EqualsAndHashCode(callSuper = true)
public class ChargeCardDetailDto extends BaseChargeDto {
String encryptedCardNumber;
String encryptedExpiryMonth;
String encryptedExpiryYear;
String encryptedSecurityCode;
String holderName;
}
PaymentsRequestFactory是一个工具类,生成不同的PaymentsRequest。
@Component
public class PaymentsRequestFactory {
public PaymentsRequest buildPaymentsRequestWithCardDetail(
final ChargeCardDetailDto chargeCardDetailDto,
final CobraUser user) {
final PaymentsRequest paymentsRequest =
buildBasicPaymentsRequest(
user,
chargeCardDetailDto.getEmployerReference(),
chargeCardDetailDto.getCost()
);
final DefaultPaymentMethodDetails paymentMethodDetails =
new DefaultPaymentMethodDetails()
.encryptedCardNumber(chargeCardDetailDto.getEncryptedCardNumber())
.encryptedExpiryMonth(chargeCardDetailDto.getEncryptedExpiryMonth())
.encryptedExpiryYear(chargeCardDetailDto.getEncryptedExpiryYear())
.encryptedSecurityCode(chargeCardDetailDto.getEncryptedSecurityCode())
.holderName(chargeCardDetailDto.getHolderName())
.type(PaymentMethodType.TYPE_SCHEME)
.storeDetails(true);
paymentsRequest.paymentMethod(paymentMethodDetails);
return paymentsRequest;
}
public PaymentsRequest buildPaymentsRequestWithCardReference(
final ChargeCardReferenceDto chargeCardReferenceDto,
final CobraUser user) {
final PaymentsRequest paymentsRequest =
buildBasicPaymentsRequest(
user,
chargeCardReferenceDto.getEmployerReference(),
chargeCardReferenceDto.getCost()
);
final DefaultPaymentMethodDetails paymentMethodDetails =
new DefaultPaymentMethodDetails()
.storedPaymentMethodId(chargeCardReferenceDto.getCardReference())
.type(PaymentMethodType.TYPE_SCHEME);
paymentsRequest.paymentMethod(paymentMethodDetails);
paymentsRequest.shopperInteraction(ShopperInteractionEnum.CONTAUTH);
return paymentsRequest;
}
PaymentsRequest buildBasicPaymentsRequest(
final CobraUser user,
final String employerReference,
final BigDecimal cost) {
final Amount amount = PaymentAmount.from(cost);
return
new PaymentsRequest()
.amount(amount)
.shopperReference(employerReference)
.merchantAccount(merchantAccount);
}
}
在service层,在调用paymentProvider.chargeCard(...)时,用lambda表达式作为方法参数。
public PaymentsResponse chargeCardByCardDetail(
final ChargeCardDetailDto chargeCardDetailDto,
final CobraUser currentUser) {
return paymentProvider
.chargeCard(() -> paymentsRequestFactory
.buildPaymentsRequestWithCardDetail(chargeCardDetailDto, currentUser));
}
public PaymentsResponse chargeCardByCardReference(
final ChargeCardReferenceDto chargeCardReferenceDto,
final CobraUser currentUser) {
return paymentProvider
.chargeCard(() -> paymentsRequestFactory
.buildPaymentsRequestWithCardReference(chargeCardReferenceDto, currentUser));
}