AutoLoanProposal.java
package com.designpatterns.creational.builder.applied;
import java.util.Objects;
/**
* A vehicle-financing proposal, the kind assembled at a bank's point of sale: a required
* applicant and vehicle price, plus several independent optional add-ons (installment count,
* insurance, a trade-in as collateral, a promotional rate) that don't all apply to every deal.
*/
public final class AutoLoanProposal {
private static final int DEFAULT_INSTALLMENTS = 48;
private final String applicantId;
private final long vehiclePriceCents;
private final int installments;
private final boolean insuranceIncluded;
private final String collateralVehiclePlate;
private final boolean promotionalRate;
private AutoLoanProposal(Builder builder) {
this.applicantId = builder.applicantId;
this.vehiclePriceCents = builder.vehiclePriceCents;
this.installments = builder.installments;
this.insuranceIncluded = builder.insuranceIncluded;
this.collateralVehiclePlate = builder.collateralVehiclePlate;
this.promotionalRate = builder.promotionalRate;
}
public String applicantId() {
return applicantId;
}
public long vehiclePriceCents() {
return vehiclePriceCents;
}
public int installments() {
return installments;
}
public boolean insuranceIncluded() {
return insuranceIncluded;
}
public String collateralVehiclePlate() {
return collateralVehiclePlate;
}
public boolean hasCollateral() {
return collateralVehiclePlate != null;
}
public boolean promotionalRate() {
return promotionalRate;
}
public static Builder builder(String applicantId, long vehiclePriceCents) {
return new Builder(applicantId, vehiclePriceCents);
}
public static final class Builder {
private final String applicantId;
private final long vehiclePriceCents;
private int installments = DEFAULT_INSTALLMENTS;
private boolean insuranceIncluded = false;
private String collateralVehiclePlate;
private boolean promotionalRate = false;
private Builder(String applicantId, long vehiclePriceCents) {
if (vehiclePriceCents <= 0) {
throw new IllegalArgumentException("vehiclePriceCents must be positive");
}
this.applicantId = Objects.requireNonNull(applicantId, "applicantId must not be null");
this.vehiclePriceCents = vehiclePriceCents;
}
public Builder installments(int installments) {
if (installments <= 0) {
throw new IllegalArgumentException("installments must be positive");
}
this.installments = installments;
return this;
}
public Builder withInsurance() {
this.insuranceIncluded = true;
return this;
}
public Builder withCollateral(String vehiclePlate) {
this.collateralVehiclePlate = Objects.requireNonNull(vehiclePlate, "vehiclePlate must not be null");
return this;
}
public Builder promotionalRate() {
this.promotionalRate = true;
return this;
}
public AutoLoanProposal build() {
return new AutoLoanProposal(this);
}
}
}