@RequestMapping("/v1/api/user")
@RestController
public class UserApi {
@Autowired
private UserService userService;
@PostMapping
public User addUser(UserInputDTO userInputDTO){
User user = new User();
user.setUsername(userInputDTO.getUsername());
user.setAge(userInputDTO.getAge());
return userService.addUser(user);
}
}
上边的代码,从逻辑上讲,是没有问题的,只是这种写法让我很厌烦,例子中只有两个字段,如果有20个字段,我们要如何做呢?一个一个进行set数据吗?当然,如果你这么做了,肯定不会有什么问题,但是,这肯定不是一个最优的做法。
关于一个对象的值赋给另一个对象,这种的方法网上有很多, 不一一赘述,此篇讲述浅拷贝,我们可以使用org.springframework.beans.BeanUtils#copyProperties
对代码进行重构和优化:
TestOBJ_B 对象
public class TestOBJ_B {
private int id;
private String name;
private List<String> like;
private String phone;
}
TestOBJ_A 对象
public class TestOBJ_A {
private String name;
private String like;
private String phone;
private String salt;
}
省略 getting、setting方法
测试,将B对象的值赋给A对象,代码如下
public static void main(String[] args) {
List<String> likes = Arrays.asList("打篮球", "听歌", "玩游戏");
//赋值
TestOBJ_B testOBJ_b = new TestOBJ_B(1,"对象A",likes,"没有电话");
System.out.println(testOBJ_b);
//A对象为空对象,不对其单独赋值
TestOBJ_A testOBJ_a = new TestOBJ_A();
//将B对象的值赋给A对象
BeanUtils.copyProperties(testOBJ_b,testOBJ_a);
System.err.println(testOBJ_a);
}
testOBJ_b = TestOBJ_B{id=1, name='对象A', like='[打篮球, 听歌, 玩游戏]', phone='没有电话'}
testOBJ_a = TestOBJ_A{name='对象A', like='null', phone='没有电话', salt='null'}
BeanUtils.copyProperties是一个浅拷贝方法,复制属性时,我们只需要把DTO对象和要转化的对象两个的属性值设置为一样的名称,并且保证一样的类型就可以了。如果你在做DTO转化的时候一直使用set进行属性赋值,那么请尝试这种方式简化代码,让代码更加清晰!
虽然这段代码很好的简化和优化了代码,但是他的语义是有问题的,我们需要提现一个转化过程才好,所以代码改成如下:
@PostMapping
public User addUser(UserInputDTO userInputDTO){
User user = convertFor(userInputDTO);
return userService.addUser(user);
}
private User convertFor(UserInputDTO userInputDTO){
User user = new User();
BeanUtils.copyProperties(userInputDTO,user);
return user;
}
这是一个更好的语义写法,虽然他麻烦了些,但是可读性大大增加了,在写代码时,我们应该尽量把语义层次差不多的放到一个方法中,比如:
User user = convertFor(userInputDTO);
return userService.addUser(user);
这两段代码都没有暴露实现,都是在讲如何在同一个方法中,做一组相同层次的语义操作,而不是暴露具体的实现。这样做可以被多次调用,减少不必要的代码量