建造者模式实践

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/heroqiang/article/details/84668926

建造者模式是一种常见的设计模式,属于创建型模式,我们常见的工厂、单例、原型、包括《重构与模式》一书中提到的creation method都属于创建型模式。建造者适合用于构建复杂对象,它可以将创建和表示分离,使我们的代码可读性更好,更易于维护。

在我们的实际开发中,经常会构建一些实体对象,比如,在笔者参与的交易系统中,会记录用户的每一笔支付,我们在创建支付实体对象时,通常会写出这样的代码:

PaymentRecord paymentRecord = new PaymentRecord();
// 设置一些基础属性
paymentRecord.setId(sequence.nextValue());
paymentRecord.setUserId(...);
...
// 计算价格
Long discountFee = ...; // 促销金额
Long totalFee = calculateTotalFee(..., discountFee); // 计算总金额
paymentRecord.setTotalFee(totalFee);
paymentRecord.setDiscountFee(discountFee);
...
// 一些扩展属性的设置
...
// 不同的业务的一些个性化参数设置
...

我们会发现,这样一个对象的构建过程非常的复杂,每次需要对这里做一些改动时,都需要埋头于这一堆繁琐的代码中苦苦的寻找,可读性非常差,维护起来相当麻烦,而这样的代码在我们的实际开发过程中是非常常见的,我们可以利用建造者模式来进行一次重构。首先,抽象建造者:

/**
 * PaymentRecord 建造者
 */
public interface PaymentRecordBuilder {

    /**
     * 构建payment record
     */
    PaymentRecord build();

}

接下来根据不同的构建需求实现不同的建造者:

/**
 * 根据支付请求构建 PaymentRecord
 */
public class RequestPaymentRecordBuilder implements PaymentRecordBuilder {

    private PaymentRequest paymentRequest;

    public RequestPaymentRecordBuilder(PaymentRequest paymentRequest) {
        this.paymentRequest = paymentRequest;
    }
    
    @Override
    public PaymentRecord build() {
        PaymentRecord paymentRecord = new PaymentRecord();
        buildBase(paymentRecord);
        buildFee(paymentRecord);
        buildExtension(paymentRecord);
        buildBiz(paymentRecord);
        return paymentRecord;
    }
    
    /**
      * 构建基础属性
     */
    private void buildBase(PaymentRecord paymentRecord) {
        paymentRecord.setId(sequence.nextValue());
        paymentRecord.setUserId(paymentRequest.getUserId());
        ...
    }

    /**
      * 费用
     */
    private void buildFee(PaymentRecord paymentRecord) {
        // 获取促销金额
        Long discountFee = ...;
        // 计算总金额
        Long totalFee = calculateTotalFee(..., discountFee);
        paymentRecord.setTotalFee(totalFee);
        paymentRecord.setDiscountFee(discountFee);
        ...
    }
    
    /**
      * 构建扩展属性
     */
    private void buildExtension(PaymentRecord paymentRecord) {
        ...
    }

    /**
      * 构建不同业务相关
     */
    private void buildBiz(PaymentRecord paymentRecord) {
        ...
    }
}

这样整个实体对象的构建过程就非常清晰,将整个构建过程拆分开来,相互独立,层次很分明,每一个子构建过程如果还是比较复杂,同样可以抽象另外的建造者进行构建。这样看似简单的重构,却能大大的提高程序的可读性和可维护性,然后我们就可以使用这样的方式来构建实体对象:

PaymentRecord paymentRecord = new RequestPaymentRecordBuilder(paymentRequest).build();

猜你喜欢

转载自blog.csdn.net/heroqiang/article/details/84668926