java浅拷贝案例

@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);

这两段代码都没有暴露实现,都是在讲如何在同一个方法中,做一组相同层次的语义操作,而不是暴露具体的实现。这样做可以被多次调用,减少不必要的代码量

猜你喜欢

转载自blog.csdn.net/qq_42227281/article/details/103494451