Java多步骤验证方法-重构
我有一个方法,可以执行多个验证,这些验证依赖于前面的验证。这是一项纯粹的休息服务,没有表单/前端。e、 gJava多步骤验证方法-重构,java,Java,我有一个方法,可以执行多个验证,这些验证依赖于前面的验证。这是一项纯粹的休息服务,没有表单/前端。e、 g public Json processPayment(User user, Amount amount, CardData cardData) { Json result = new Json(); Json userResult = validateUser(user); if (userResult.isNotValid()) result.p
public Json processPayment(User user, Amount amount, CardData cardData) {
Json result = new Json();
Json userResult = validateUser(user);
if (userResult.isNotValid())
result.put("errorCode", userResult.get("errorCode");
result.put("message", userResult.get("message");
return result;
}
Merchant merchant = getMerchant(user);
Json merchantResult = validateMerchant(user);
if (merchantResult.isNotValid())
result.put("errorCode", merchantResult.get("errorCode");
result.put("message", merchantResult.get("message");
return result;
}
Json limitsResult = validateLimits(user, merchant, amount);
if (limitsResult.isNotValid())
result.put("errorCode", limitsResult.get("errorCode");
result.put("message", limitsResult.get("message");
return result;
}
// Like above there are few more steps.
.
.
.
// All validations are fine process transaction.
Json transactionResult = processTransaction(user, merchant, amount, cardData);
if (transactionResult.isNotValid())
result.put("errorCode", transactionResult.get("errorCode");
result.put("message", transactionResult.get("message");
} else {
result.put("message", "Transaction Successful");
result.put("referenceNumber, transactionResult.get("rrn");
}
return result;
}
在每个步骤中,如果结果无效,则应立即返回错误消息,否则继续下一步
由于有多个步骤,这种方法变得太大,几乎不可能进行单元测试
我想把这个方法分解成更小的方法。我已经将每个步骤的所有业务逻辑转移到单独的方法中,但流程仍然保留在这个大方法中
Sonarint CC为47,这是一个大问题
请建议处理此问题的正确方法
谢谢。您可以编写
doValidation()
函数,如下所示
private doValidation(Json validationResult, Json result) {
if (validationResult.isNotValid())
result.put("errorCode", validationResult.get("errorCode");
result.put("message", validationResult.get("message");
return false;//validation failed
}
return true;//validation passed
}
并从processPayment()
方法调用此方法
public Json processPayment(User user, Amount amount, CardData cardData) {
Json result = new Json();
if( !doAllValidations(user,amount,cardData, result) )
return result;
// All validations are fine process transaction.
Json transactionResult = processTransaction(user, merchant, amount, cardData);
if (transactionResult.isNotValid())
result.put("errorCode", transactionResult.get("errorCode");
result.put("message", transactionResult.get("message");
} else {
result.put("message", "Transaction Successful");
result.put("referenceNumber, transactionResult.get("rrn");
}
return result;
}
最后,如果需要,可以将所有验证移到其他方法
public bool doAllValidations(User user, Amount amount, CardData cardData, result) {
Json userResult = validateUser(user);
if (!doValidation(userResult, result))
return result;
Merchant merchant = getMerchant(user);
Json merchantResult = validateMerchant(user);
if (!doValidation(merchantResult, result))
return result;
Json limitsResult = validateLimits(user, merchant, amount);
if (!doValidation(limitsResult, result))
return result;
....
}
这里有一个小例子,可以为您提供解决方案 主要思想是每个验证步骤共享一个公共上下文。此上下文保存验证过程的所有信息 接下来是一个验证程序队列。每个代表一个验证步骤。验证器更改上下文(如添加商家对象),调用您的验证方法,并在必要时更改上下文的结果 验证过程本身只是在队列上迭代,寻找失败的验证程序 只要运行这个代码。也许这有助于:
import java.util.*;
接口支付验证接口{
公共布尔验证(PaymentValidationContext);
}
类PaymentValidationContext{
字符串结果=”;
字符串用户;
int cardData;
弦乐商人;
public PaymentValidationContext(字符串用户,int cardData){
this.user=用户;
this.cardData=cardData;
}
}
类支付验证器{
公共静态布尔validateUser(PaymentValidationContext上下文){
if(context.user==null){
context.result+=“用户错误\n”;
返回false;
}
返回true;
}
公共静态布尔validateMerchant(PaymentValidationContext上下文){
context.merchant=context.user+“#”+context.cardData;
if(context.merchant.length()!validator.validate(context));
返回context.result;
}
//用于测试-------
公共静态void main(字符串[]args){
处理器p=新处理器();
System.out.print(p.processPayment(“Foobar”,1337));//确定
System.out.print(p.processPayment(null,1337));//失败
System.out.print(p.processPayment(“,1));//失败
}
}
是您要找的。这是我已经在做的。所有业务逻辑都在此方法之外。这个方法中只有流程,但所有单独的方法都会返回结果,我必须检查结果是否有效,并在此基础上继续下一步。将4行验证结果移动到其他方法。让我把processPayment方法也放进去。在这种情况下,doAllValidations
方法变得更大,而不是processPayment
。这听起来是完美的解决方案。我将尝试基于此重构代码,并在此处更新。谢谢@obenland你是指javax.naming.Context
还是我应该添加我自己的简单实现?哦。我没能把这个拿走。我认为拥有一个公共上下文类是很好的,但是对于这个示例,您不需要一个。我确定了我的答案
import java.util.*;
interface PaymentValidatorInterface {
public boolean validate(PaymentValidationContext context);
}
class PaymentValidationContext {
String result = "";
String user;
int cardData;
String merchant;
public PaymentValidationContext(String user, int cardData) {
this.user = user;
this.cardData = cardData;
}
}
class PaymentValidator {
public static boolean validateUser(PaymentValidationContext context) {
if (context.user == null) {
context.result += "User is wrong\n";
return false;
}
return true;
}
public static boolean validateMerchant(PaymentValidationContext context) {
context.merchant = context.user + "#" + context.cardData;
if (context.merchant.length() <= 3) {
context.result += "Marchant is wrong\n";
return false;
}
return true;
}
public static boolean finishValidation(PaymentValidationContext context) {
context.result += "Everything is fine.\n";
return true;
}
}
public class Processor {
private final static Queue<PaymentValidatorInterface> validators = new LinkedList<>();
static {
validators.add(PaymentValidator::validateUser);
validators.add(PaymentValidator::validateMerchant);
validators.add(PaymentValidator::finishValidation);
}
public String processPayment(String user, int cardData) {
PaymentValidationContext context = new PaymentValidationContext(user, cardData);
validators.stream().anyMatch(validator -> !validator.validate(context));
return context.result;
}
// For testing -------
public static void main(String[] args) {
Processor p = new Processor();
System.out.print(p.processPayment("Foobar", 1337)); // ok
System.out.print(p.processPayment(null, 1337)); // fails
System.out.print(p.processPayment("", 1)); // fails
}
}