【问题标题】:What is optimized way to validate mandatory fields based on other field value in Java?基于Java中的其他字段值验证必填字段的优化方法是什么?
【发布时间】:2020-07-12 12:20:50
【问题描述】:

我正在创建一个 Spring Boot Rest 应用程序,我在 POST 请求中将玩家信息作为 JSON 获取以持久保存到数据库中。我们总共有 16 个字段,但将来会添加更多字段。

{
    "jerseyNumber": "1",
    "firstName": "Sachin",
    "lastName": "Tendulkar",
    "age": "35",
    "country": "India",
    "playerType": "Batsmen",
    "score": "101",
    "ballsFaced": "110",
    "strikeRate": "90",
    "fours": "15",
    "sixes": "1",
    "oversBowled": "",    '
    "runsGiven": "",
    "maidenOvers": "",
    "wicketsTaken": "",
    "economy": ""
  }

如果 playerType = Batsmen,则以下 11 个字段为必填项,其他特定于投球手的字段可以为 null/空。

{
    "jerseyNumber": "1",
    "firstName": "Sachin",
    "lastName": "Tendulkar",
    "age": "35",
    "country": "India",
    "playerType": "Batsmen",
    "score": "101",
    "ballsFaced": "110",
    "strikeRate": "90",
    "fours": "15",
    "sixes": "1",
  }

如果 playerType = Bowler,则必须填写以下 11 个字段。

{
    "jerseyNumber": "10",
    "firstName": "Zaheer",
    "lastName": "Khan",
    "age": "38",
    "country": "India",
    "playerType": "Bowler",
    "oversBowled": "10",    '
    "runsGiven": "39",
    "maidenOvers": "1",
    "wicketsTaken": "3",
    "economy": "3.9"
  }

Pojo 类

public class CricketPlayer {
 private String jerseyNumber;
 private String firstName;
 private String lastName;
 private String age;
 private String country;
 private String playerType;
 private String score;
 private String ballsFaced;
 private String strikeRate;
 private String fours;
 private String sixes;
 private String oversBowled;
 private String runsGiven;
 private String maidenOvers;
 private String wicketsTaken;
 private String economy;


 // Getter Methods 
}

收到请求后,我需要根据 playerType 值进行验证,1)如果在 json 请求中给出了所有必填字段(非空或 null)。

还需要检查以下业务验证,

a) age => 18 and age <= 50
b) country is any value from (England, Australia, India, Srilanka, New Zealand, South Africa, Pakistan, Zimbabwe, West Indies, Bangladesh)
c) maidenOvers < oversBowled
d) wicketsTaken < 11
e) ballsfaced < =360
f) oversBowled <= 10

今后,必填字段的数量可以增加到 25-30 个字段。我可以根据玩家类型值使用 if else 语句编写验证。

if(cricketPlayer.getPlayerType.equals("Batsmen")
{
// writelogic to check if all mandatory fields are not null or empty

} else if(cricketPlayer.getPlayerType.equals("Bowler")
{


}

但如果我们有超过 20-25 个必须验证的字段,则多个 if else 块看起来不太好。在这种情况下要遵循的优化和最佳方法是什么,以使其更具可读性并且易于添加或删除任何验证。

【问题讨论】:

  • 看起来设计从一开始就是错误的。阅读关注点分离。
  • @AbhirojPanwar:由于投球手也可以击球,反之亦然,所以我将所有字段都放在同一个 json 中。
  • 在我看来,可以为其他字段分配默认值以进行验证。如果您使用 Spring Boot,那么 JSON 中的可选性将在编译时确定。您可以根据专业划分玩家并将其暴露在另一个休息端点/player/specialization
  • ^ 这取决于你,如果 - 其他任何一天都是错误的。相反,使用Hash-Map

标签: java spring spring-boot validation design-patterns


【解决方案1】:

使用Hash-Map。使用 Validator 接口 -> 然后可以有不同的实现 -> BatsmanValidator & BowlerValidator。您还可以抽象出共性并使用像PlayerValidator 这样的一个类来验证它们。

接口和类

Interface Validator {
  public boolean validate(Player pojo);
}

class BatsmanValidator implements Validator {
  public boolean validate(Player pojo) {
  // code to validate a batsman 
  }
}

用法

// setup validator
// Also, the player type should go in as enum.
Map<PlayerType, Validator> validators = new HashMap<>();
validators.put(Batsman, new BatsmanValidator());
validator.put(Bowler, new BowlerValidator());

// validate input
// This will itself validate the player based on type
// no if-else needed
validators.get(player.getType()).validate(player);

【讨论】:

  • :仍然在单独的验证器验证方法中,我将不得不编写多个 if-else 语句来检查是否给出了必填字段值。假设,我还必须添加业务验证,例如年龄 > 0 和年龄
  • 你必须在某个地方使用 if-else 来进行比较。这避免了在单个函数中进行比较的混乱。
猜你喜欢
  • 2016-01-20
  • 2015-07-24
  • 1970-01-01
  • 2017-09-08
  • 1970-01-01
  • 2021-04-10
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多