欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java代码重构思考

程序员文章站 2024-03-21 19:20:40
...

 

场景:

下面代码是当添加评论时,后端接收到数据后,处理数据并添加的过程

 public Review getReview(ReviewParamsModel reviewParamsModel) {
        Review review = new Review();
        if (reviewParamsModel != null) {
            review.setId(reviewParamsModel.getId());
            review.setAimId(reviewParamsModel.getAimId());
            review.setContent(reviewParamsModel.getContent());
            review.setRemark(reviewParamsModel.getRemark());
            review.setCreaterId(reviewParamsModel.getUserId());
            review.setIdentityType(reviewParamsModel.getIdentityType());

            review.setDeleted(Constant.DELETE_FALSE);

        }
        return review;
    }

上边的代码,从逻辑上讲,是没有问题的,只是这种写法让我很厌烦,例子中字段不多,但如果有20个字段,我们要如何做呢? 一个一个进行set数据吗?当然,如果你这么做了,肯定不会有什么问题,但是,这肯定不是一个最优的做法。

有没有办法呢?我们现行的可以使用BeanUtils.copyProperties对代码进行重构和优化:

public Review convertToReview(ReviewParamsModel reviewParamsModel) {
        Review review = new Review();
        if (reviewParamsModel != null) {
            BeanUtils.copyProperties(reviewParamsModel,review);
            review.setCreaterId(reviewParamsModel.getUserId());
            review.setDeleted(Constant.DELETE_FALSE);
        }
        return review;
    }

1、优化了方法名字叫转化成评论更符合;2、使用工具BeanUtils.copyProperties,我们只需要把model对象和要转化的对象两个的属性值设置为一样的名称,并且保证一样的类型就可以了。这种方式让代码更加清晰、易懂!

这里有个疑问BeanUtils.copyProperties和JSONObject.parseObject哪个好一些?

在实际工作中,完成了几个对象转化时,我们会发现,这样的操作有很多很多,那么应该定义好一个接口,让所有这样的操作都有规则的进行。

如何操作呢查阅资料发现大致有两类情况可供我们选择

1、阅读springframework源码,发现org.springframework.core.convert.converter.Converter这样的定义:

public interface Converter<S, T> {

	/**
	 * Convert the source object of type {@code S} to target type {@code T}.
	 * @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
	 * @return the converted object, which must be an instance of {@code T} (potentially {@code null})
	 * @throws IllegalArgumentException if the source cannot be converted to the desired target type
	 */
	@Nullable
	T convert(S source);

}

意思就是springframework中的Converter只是把原对象(source)转化为目标对象(target)

2、阅读了GUAVA的源码,发现了com.google.common.base.Convert这样的定义:

public abstract class Converter<A, B> implements Function<A, B> {
    protected abstract B doForward(A a);
    protected abstract A doBackward(B b);
    //其他略
}

从源码可以了解到,GUAVA中的Converter可以完成正向转化和逆向转化,

这里我们尝试使用第二种方式,修改我们model中的代码:

public class ReviewParamsModel {
    //省略

    public Review converterToReview() {
        ReviewParamsModelConverter reviewParamsModelConverter = new ReviewParamsModelConverter();
        return reviewParamsModelConverter.convert(this);
    }

    public ReviewParamsModel convertFor(Review review){
        ReviewParamsModelConverter reviewParamsModelConverter = new ReviewParamsModelConverter();
        ReviewParamsModel convert = reviewParamsModelConverter.reverse().convert(review);
        return convert;
    }
    private static class ReviewParamsModelConverter extends Converter<ReviewParamsModel, Review> {

        @Override
        protected Review doForward(ReviewParamsModel reviewParamsModel) {
            Assert.notNull(reviewParamsModel, "reviewParamsModel不能为空");
            Review review = new Review();
            BeanUtils.copyProperties(reviewParamsModel, review);
            review.setCreaterId(reviewParamsModel.getUserId());
            review.setDeleted(Constant.DELETE_FALSE);
            return review;
        }

        @Override
        protected ReviewParamsModel doBackward(Review review) {
            Assert.notNull(review, "review不能为空");
            ReviewParamsModel reviewParamsModel = new ReviewParamsModel();
            BeanUtils.copyProperties(review, reviewParamsModel);
            return reviewParamsModel;
        }
    }

调用层:

 public Review convertToReview(ReviewParamsModel reviewParamsModel) {
        //正向转化
        Review review = reviewParamsModel.converterToReview();
        //逆向转化
        //ReviewParamsModel reviewParamsModel1 = reviewParamsModel.convertFor(review);
        return review;
    }

对于有些业务是无法逆向转换的那么我们只需要告诉程序:逆向是无法调用的:

相关标签: 重构