一个复杂对象包含许多可选属性,创建可划分为特定的几个宏观步骤(方法),这些步骤可以根据实际情况任意组合,使用这不必关心对象具体创建工作。
主要角色:
产品角色(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