在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);returnnew 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));}