《设计模式》5.建造者模式(创建型)

一个复杂对象包含许多可选属性,创建可划分为特定的几个宏观步骤(方法),这些步骤可以根据实际情况任意组合,使用这不必关心对象具体创建工作。

主要角色:

产品角色(Product):复杂对象,包含许多可选属性,创建可划分为特定的几个宏观步骤。
建造者(Builder):包含创建产品各步骤的方法实现,最后还包含一个返回复杂对象的方法,通常定义为:T build();
指挥者(Director):指挥建造者组合创建步骤,实现复杂对象的创建,可省略。

抽象建造者 AutoWorker

import lombok.Data;

@Data
public abstract class AutoWorker {
    protected Car car;
    public AutoWorker() {
        car = new Car();
    }

    public abstract void createChassis();
    public abstract void createEngine();
    public abstract void createCarBody();
    public abstract void createElectricalEquipments();

    public Car build() {
        return car;
    }
}

具体的建造者 BydAutoWorker

import java.util.ArrayList;
import java.util.List;

public class BydAutoWorker extends AutoWorker {
    public BydAutoWorker() {
        super();
    }

    @Override
    public void createChassis() {
        car.setChassis("BYD Chassis");
    }

    @Override
    public void createEngine() {
        car.setEngine("BYD engine");
    }

    @Override
    public void createCarBody() {
        car.setCarBody("BYD Song Car Body");
    }

    @Override
    public void createElectricalEquipments() {
        List<String> electricalEquipments = new ArrayList<>();
        electricalEquipments.add("Dashboard");
        electricalEquipments.add("Reversing Radar");
        electricalEquipments.add("Air Conditioning");
        car.setElectricalEquipments(electricalEquipments);
    }
}

产品 Car

import lombok.Data;
import java.util.List;

@Data
public class Car {
    private String chassis;
    private String engine;
    private String carBody;
    private List<String> electricalEquipments;
}

抽象指挥者 AutomotiveEngineer

public interface AutomotiveEngineer {
    Car getCar();
}

指挥者 BydAutomotiveEngineer

public class BydAutomotiveEngineer implements AutomotiveEngineer {
    private AutoWorker builder;
    public BydAutomotiveEngineer(AutoWorker builder) {
        this.builder = builder;
    }

    @Override
    public Car getCar() {
        builder.createChassis();
        builder.createEngine();
        builder.createCarBody();
        builder.createElectricalEquipments();
        return builder.build();
    }
}

测试类

public class CarBuilderTester {
    public static void main(String args[]) {
        AutoWorker builder = new BydAutoWorker();
        AutomotiveEngineer engineer = new BydAutomotiveEngineer(builder);
        Car car = engineer.getCar();
        System.out.println(car.toString());
    }
}

订单创建

省略了指挥者,通常建造者以内部类的方式实现

import lombok.Data;
import net.sf.cglib.beans.BeanCopier;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Data
public class Order {
    private String orderNo;
    private List<String> products;
    private String customer;
    private String shippingAddress;
    private String contactNumber;
    private BigDecimal amount;
    private String status;

    @Data
    public static class Builder {
        private static final DateFormat df = new SimpleDateFormat("yyMMddHHmmssSSS");
        private static final BeanCopier beanCopier = BeanCopier.create(Order.Builder.class, Order.class, false);

        private String orderNo;
        private List<String> products;
        private String customer;
        private String contactNumber;
        private String shippingAddress;
        private BigDecimal amount;

        public Builder() {
            this.products = new ArrayList<>(16);
        }

        public Builder orderNo(String orderNo) {
            this.orderNo = orderNo;
            return this;
        }

        public Builder addToShopingCart(String product) {
            this.products.add(product);
            return this;
        }

        public Builder customer(String customer) {
            this.customer = customer;
            return this;
        }

        public Builder contactNumber(String contactNumber) {
            this.contactNumber = contactNumber;
            return this;
        }

        public Builder shippingAddress(String shippingAddress) {
            this.shippingAddress = shippingAddress;
            return this;
        }

        public Order build() {
            Order order = new Order();

            // also we can use beanCopier if there is too many properties
            //beanCopier.copy(this, order, null);

            // set order no
            if (orderNo == null || orderNo.isEmpty()) {
                orderNo = df.format(new Date());
            }
            order.setOrderNo(orderNo);

            // set products
            if (products == null || products.isEmpty()) {
                throw new RuntimeException("You must choose a product at least!");
            }
            order.setProducts(products);

            // set customer
            if (customer == null || customer.isEmpty()) {
                String uuid = UUID.randomUUID().toString().replace("-", "");
                customer = String.format("CUST#%s", uuid.substring(0, 4));
            }
            order.setCustomer(customer);

            // set contact number
            if (contactNumber == null || contactNumber.isEmpty()) {
                throw new RuntimeException("Contact number is required!");
            }
            order.setContactNumber(contactNumber);

            // set shipping address
            if (shippingAddress == null || shippingAddress.isEmpty()) {
                throw new RuntimeException("Shipping address is required!");
            }
            order.setShippingAddress(shippingAddress);

            // calculate total amount if $2.00 per product
            order.setAmount(new BigDecimal(2 * products.size()));

            // set status as new order
            order.setStatus("NEW");

            return order;
        }
    }
}

测试类

public class OrderBuilderTester {
    public static void main(String args[]) {
        Order order = new Order.Builder()
                .addToShopingCart("Apple")
                .addToShopingCart("Banana")
                .contactNumber("136-****-7821")
                .shippingAddress("北京市东城区xx小区xx栋xx单元xxxx号")
                .build();

        System.out.println(order.toString());
    }
}

参考:
@see: http://c.biancheng.net/view/1354.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值