Anticipándonos al inminente inicio del curso "Arquitectura y Patrones de Diseño", compartimos con ustedes la traducción del material.
También invitamos a todos a una lección de demostración abierta "Plantillas GRASP" . En esta lección, analizaremos la separación funcional de funcionalidades y veremos 9 plantillas GRASP. ¡Únete a nosotros!
, Builder ( ). , .
Builder
Builder - .
Builder .
Builder , .
.
(GoF), , - .
.
Builder — , . - (director), .
, Builder :
Product () - , , , .
Builder () - /, , -. , () (buildPart), (ConcreteBuilder).
ConcreteBuilder ( ) - -, -. ConcreteBuilder-, -.
Director () - , -. -.
Builder , :
( ) ?
, ?
, Builder.
Builder
1: Car (), :
package org.trishinfotech.builder;
public class Car {
private String chassis;
private String body;
private String paint;
private String interior;
public Car() {
super();
}
public Car(String chassis, String body, String paint, String interior) {
this();
this.chassis = chassis;
this.body = body;
this.paint = paint;
this.interior = interior;
}
public String getChassis() {
return chassis;
}
public void setChassis(String chassis) {
this.chassis = chassis;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getPaint() {
return paint;
}
public void setPaint(String paint) {
this.paint = paint;
}
public String getInterior() {
return interior;
}
public void setInterior(String interior) {
this.interior = interior;
}
public boolean doQualityCheck() {
return (chassis != null && !chassis.trim().isEmpty()) && (body != null && !body.trim().isEmpty())
&& (paint != null && !paint.trim().isEmpty()) && (interior != null && !interior.trim().isEmpty());
}
@Override
public String toString() {
// StringBuilder class also uses Builder Design Pattern with implementation of java.lang.Appendable interface
StringBuilder builder = new StringBuilder();
builder.append("Car [chassis=").append(chassis).append(", body=").append(body).append(", paint=").append(paint)
return builder.toString();
}
}
, doQualityCheck
. , Builder Product-. , .
2: / CarBuilder
, .
package org.trishinfotech.builder;
public interface CarBuilder {
// 1
public CarBuilder fixChassis();
// 2
public CarBuilder fixBody();
// 3
public CarBuilder paint();
// 4
public CarBuilder fixInterior();
//
public Car build();
}
, CarBuilder
, . . build
, , Car
. () , ( ).
3: ConcreteBuilder
. , ConcreteBuilder
, -, Car
.
, ClassicCarBuilder
, .
package org.trishinfotech.builder;
public class ClassicCarBuilder implements CarBuilder {
private String chassis;
private String body;
private String paint;
private String interior;
public ClassicCarBuilder() {
super();
}
@Override
public CarBuilder fixChassis() {
System.out.println("Assembling chassis of the classical model");
this.chassis = "Classic Chassis";
return this;
}
@Override
public CarBuilder fixBody() {
System.out.println("Assembling body of the classical model");
this.body = "Classic Body";
return this;
}
@Override
public CarBuilder paint() {
System.out.println("Painting body of the classical model");
this.paint = "Classic White Paint";
return this;
}
@Override
public CarBuilder fixInterior() {
System.out.println("Setting up interior of the classical model");
this.interior = "Classic interior";
return this;
}
@Override
public Car build() {
Car car = new Car(chassis, body, paint, interior);
if (car.doQualityCheck()) {
return car;
} else {
System.out.println("Car assembly is incomplete. Can't deliver!");
}
return null;
}
}
ModernCarBuilder
.
package org.trishinfotech.builder;
public class ModernCarBuilder implements CarBuilder {
private String chassis;
private String body;
private String paint;
private String interior;
public ModernCarBuilder() {
super();
}
@Override
public CarBuilder fixChassis() {
System.out.println("Assembling chassis of the modern model");
this.chassis = "Modern Chassis";
return this;
}
@Override
public CarBuilder fixBody() {
System.out.println("Assembling body of the modern model");
this.body = "Modern Body";
return this;
}
@Override
public CarBuilder paint() {
System.out.println("Painting body of the modern model");
this.paint = "Modern Black Paint";
return this;
}
@Override
public CarBuilder fixInterior() {
System.out.println("Setting up interior of the modern model");
this.interior = "Modern interior";
return this;
}
@Override
public Car build() {
Car car = new Car(chassis, body, paint, interior);
if (car.doQualityCheck()) {
return car;
} else {
System.out.println("Car assembly is incomplete. Can't deliver!");
}
return null;
}
}
SportsCarBuilder
.
package org.trishinfotech.builder;
public class SportsCarBuilder implements CarBuilder {
private String chassis;
private String body;
private String paint;
private String interior;
public SportsCarBuilder() {
super();
}
@Override
public CarBuilder fixChassis() {
System.out.println("Assembling chassis of the sports model");
this.chassis = "Sporty Chassis";
return this;
}
@Override
public CarBuilder fixBody() {
System.out.println("Assembling body of the sports model");
this.body = "Sporty Body";
return this;
}
@Override
public CarBuilder paint() {
System.out.println("Painting body of the sports model");
this.paint = "Sporty Torch Red Paint";
return this;
}
@Override
public CarBuilder fixInterior() {
System.out.println("Setting up interior of the sports model");
this.interior = "Sporty interior";
return this;
}
@Override
public Car build() {
Car car = new Car(chassis, body, paint, interior);
if (car.doQualityCheck()) {
return car;
} else {
System.out.println("Car assembly is incomplete. Can't deliver!");
}
return null;
}
}
4: - AutomotiveEngineer
, ( Car
) .
package org.trishinfotech.builder;
public class AutomotiveEngineer {
private CarBuilder builder;
public AutomotiveEngineer(CarBuilder builder) {
super();
this.builder = builder;
if (this.builder == null) {
throw new IllegalArgumentException("Automotive Engineer can't work without Car Builder!");
}
}
public Car manufactureCar() {
return builder.fixChassis().fixBody().paint().fixInterior().build();
}
}
, manufactureCar
.
Main
.
package org.trishinfotech.builder;
public class Main {
public static void main(String[] args) {
CarBuilder builder = new SportsCarBuilder();
AutomotiveEngineer engineer = new AutomotiveEngineer(builder);
Car car = engineer.manufactureCar();
if (car != null) {
System.out.println("Below car delievered: ");
System.out.println("======================================================================");
System.out.println(car);
System.out.println("======================================================================");
}
}
}
:
Assembling chassis of the sports model Assembling body of the sports model Painting body of the sports model Setting up interior of the sports model Below car delievered: ====================================================================== Car [chassis=Sporty Chassis, body=Sporty Body, paint=Sporty Torch Red Paint, interior=Sporty interior] ======================================================================
, , Builder
. (Abstract Factory), . , . , «», - «».
: Real-Builder-Design-Pattern-Source-Code
Builder
. , Builder
. , , , Java 8.
Builder
, .
Employee
, .
public class Employee {
private int empNo;
private String name;
private String depttName;
private int salary;
private int mgrEmpNo;
private String projectName;
}
, EmpNo
EmpName
, - . , .
.
,
Employee
.
, , , - . , null
.
Employee emp1 = new Employee (100, "Brijesh", null, 0, 0, "Builder Pattern");
, .
public Employee(int empNo, String name) {
super();
if (empNo <= 0) {
throw new IllegalArgumentException("Please provide valid employee number.");
}
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("Please provide employee name.");
}
this.empNo = empNo;
this.name = name;
}
public Employee(int empNo, String name, String depttName) {
this(empNo, name);
this.depttName = depttName;
}
public Employee(int empNo, String name, String depttName, int salary) {
this(empNo, name, depttName);
this.salary = salary;
}
public Employee(int empNo, String name, String depttName, int salary, int mgrEmpNo) {
this(empNo, name, depttName, salary);
this.mgrEmpNo = mgrEmpNo;
}
public Employee(int empNo, String name, String depttName, int salary, int mgrEmpNo, String projectName) {
this(empNo, name, depttName, salary, mgrEmpNo);
this.projectName = projectName;
}
, Builder
:
package org.trishinfotech.builder.example;
public class Employee {
private int empNo;
private String name;
private String depttName;
private int salary;
private int mgrEmpNo;
private String projectName;
public Employee(EmployeeBuilder employeeBuilder) {
if (employeeBuilder == null) {
throw new IllegalArgumentException("Please provide employee builder to build employee object.");
}
if (employeeBuilder.empNo <= 0) {
throw new IllegalArgumentException("Please provide valid employee number.");
}
if (employeeBuilder.name == null || employeeBuilder.name.trim().isEmpty()) {
throw new IllegalArgumentException("Please provide employee name.");
}
this.empNo = employeeBuilder.empNo;
this.name = employeeBuilder.name;
this.depttName = employeeBuilder.depttName;
this.salary = employeeBuilder.salary;
this.mgrEmpNo = employeeBuilder.mgrEmpNo;
this.projectName = employeeBuilder.projectName;
}
public int getEmpNo() {
return empNo;
}
public String getName() {
return name;
}
public String getDepttName() {
return depttName;
}
public int getSalary() {
return salary;
}
public int getMgrEmpNo() {
return mgrEmpNo;
}
public String getProjectName() {
return projectName;
}
@Override
public String toString() {
// StringBuilder Builder
// java.lang.Appendable
StringBuilder builder = new StringBuilder();
builder.append("Employee [empNo=").append(empNo).append(", name=").append(name).append(", depttName=")
.append(depttName).append(", salary=").append(salary).append(", mgrEmpNo=").append(mgrEmpNo)
.append(", projectName=").append(projectName).append("]");
return builder.toString();
}
public static class EmployeeBuilder {
private int empNo;
protected String name;
protected String depttName;
protected int salary;
protected int mgrEmpNo;
protected String projectName;
public EmployeeBuilder() {
super();
}
public EmployeeBuilder empNo(int empNo) {
this.empNo = empNo;
return this;
}
public EmployeeBuilder name(String name) {
this.name = name;
return this;
}
public EmployeeBuilder depttName(String depttName) {
this.depttName = depttName;
return this;
}
public EmployeeBuilder salary(int salary) {
this.salary = salary;
return this;
}
public EmployeeBuilder mgrEmpNo(int mgrEmpNo) {
this.mgrEmpNo = mgrEmpNo;
return this;
}
public EmployeeBuilder projectName(String projectName) {
this.projectName = projectName;
return this;
}
public Employee build() {
Employee emp = null;
if (validateEmployee()) {
emp = new Employee(this);
} else {
System.out.println("Sorry! Employee objects can't be build without required details");
}
return emp;
}
private boolean validateEmployee() {
return (empNo > 0 && name != null && !name.trim().isEmpty());
}
}
}
EmployeeBuilder
. Java. .
EmployeeMain
Employee
:
package org.trishinfotech.builder.example;
public class EmployeeMain {
public static void main(String[] args) {
Employee emp1 = new Employee.EmployeeBuilder().empNo(100).name("Brijesh").projectName("Builder Pattern")
.build();
System.out.println(emp1);
}
}
, . . (Director), ( ) . , Employee
, .
Builder
, Order () - Order Service Type (Take Away - /Eat Here - ), (Food Items) (Customer Name - ) . . , .
OrderService
:
package org.trishinfotech.builder;
public enum OrderService {
TAKE_AWAY("Take Away", 2.0d), EAT_HERE("Eat Here", 5.5d);
private String name;
private double tax;
OrderService(String name, double tax) {
this.name = name;
this.tax = tax;
}
public String getName() {
return name;
}
public double getTax() {
return tax;
}
}
FoodItem
:
package org.trishinfotech.builder.meal;
import org.trishinfotech.builder.packing.Packing;
public interface FoodItem {
public String name();
public int calories();
public Packing packing();
public double price();
}
Meal
(). Meal
( ).
package org.trishinfotech.builder.meal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.trishinfotech.builder.packing.MultiPack;
import org.trishinfotech.builder.packing.Packing;
public class Meal implements FoodItem {
private List<FoodItem> foodItems = new ArrayList<FoodItem>();
private String mealName;
private double discount;
public Meal(String mealName, List<FoodItem> foodItems, double discount) {
super();
if (Objects.isNull(foodItems) || foodItems.stream().filter(Objects::nonNull).collect(Collectors.toList()).isEmpty()) {
throw new IllegalArgumentException(
"Meal can't be order without any food item");
}
this.mealName = mealName;
this.foodItems = new ArrayList<FoodItem>(foodItems);
this.discount = discount;
}
public List<FoodItem> getFoodItems() {
return foodItems;
}
@Override
public String name() {
return mealName;
}
@Override
public int calories() {
int totalCalories = foodItems.stream().mapToInt(foodItem -> foodItem.calories()).sum();
return totalCalories;
}
@Override
public Packing packing() {
double packingPrice = foodItems.stream().map(foodItem -> foodItem.packing())
.mapToDouble(packing -> packing.packingPrice()).sum();
return new MultiPack(packingPrice);
}
@Override
public double price() {
double totalPrice = foodItems.stream().mapToDouble(foodItem -> foodItem.price()).sum();
return totalPrice;
}
public double discount() {
return discount;
}
}
:
Burger
:
package org.trishinfotech.builder.food.burger;
import org.trishinfotech.builder.meal.FoodItem;
import org.trishinfotech.builder.packing.Packing;
import org.trishinfotech.builder.packing.Wrap;
public abstract class Burger implements FoodItem {
@Override
public Packing packing() {
return new Wrap();
}
}
ChickenBurger
:
package org.trishinfotech.builder.food.burger;
public class ChickenBurger extends Burger {
@Override
public String name() {
return "Chicken Burger";
}
@Override
public int calories() {
return 300;
}
@Override
public double price() {
return 4.5d;
}
}
VegBurger
( ):
package org.trishinfotech.builder.food.burger;
public class VegBurger extends Burger {
@Override
public String name() {
return "Veg Burger";
}
@Override
public int calories() {
return 180;
}
@Override
public double price() {
return 2.7d;
}
}
Nuggets
:
package org.trishinfotech.builder.food.nuggets;
import org.trishinfotech.builder.meal.FoodItem;
import org.trishinfotech.builder.packing.Container;
import org.trishinfotech.builder.packing.Packing;
public abstract class Nuggets implements FoodItem {
@Override
public Packing packing() {
return new Container();
}
}
CheeseNuggets
:
package org.trishinfotech.builder.food.nuggets;
public class CheeseNuggets extends Nuggets {
@Override
public String name() {
return "Cheese Nuggets";
}
@Override
public int calories() {
return 330;
}
@Override
public double price() {
return 3.8d;
}
}
ChickenNuggets
:
package org.trishinfotech.builder.food.nuggets;
public class ChickenNuggets extends Nuggets {
@Override
public String name() {
return "Chicken Nuggets";
}
@Override
public int calories() {
return 450;
}
@Override
public double price() {
return 5.0d;
}
}
:
. , BeverageSize
:
package org.trishinfotech.builder.beverages;
public enum BeverageSize {
XS("Extra Small", 110), S("Small", 150), M("Medium", 210), L("Large", 290);
private String name;
private int calories;
BeverageSize(String name, int calories) {
this.name = name;
this.calories = calories;
}
public String getName() {
return name;
}
public int getCalories() {
return calories;
}
}
Drink
:
package org.trishinfotech.builder.beverages;
import org.trishinfotech.builder.meal.FoodItem;
public abstract class Drink implements FoodItem {
protected BeverageSize size;
public Drink(BeverageSize size) {
super();
this.size = size;
if (this.size == null) {
this.size = BeverageSize.M;
}
}
public BeverageSize getSize() {
return size;
}
public String drinkDetails() {
return " (" + size + ")";
}
}
ColdDrink
:
package org.trishinfotech.builder.beverages.cold;
import org.trishinfotech.builder.beverages.BeverageSize;
import org.trishinfotech.builder.beverages.Drink;
import org.trishinfotech.builder.packing.Bottle;
import org.trishinfotech.builder.packing.Packing;
public abstract class ColdDrink extends Drink {
public ColdDrink(BeverageSize size) {
super(size);
}
@Override public Packing packing() {
return new Bottle();
}
}
CocaCola
:
package org.trishinfotech.builder.beverages.cold;
import org.trishinfotech.builder.beverages.BeverageSize;
public class CocaCola extends ColdDrink {
public CocaCola(BeverageSize size) {
super(size);
}
@Override
public String name() {
return "Coca-Cola" + drinkDetails();
}
@Override
public int calories() {
if (size != null) {
switch (size) {
case XS:
return 110;
case S:
return 150;
case M:
return 210;
case L:
return 290;
default:
break;
}
}
return 0;
}
@Override
public double price() {
if (size != null) {
switch (size) {
case XS:
return 0.80d;
case S:
return 1.0d;
case M:
return 1.5d;
case L:
return 2.0d;
default:
break;
}
}
return 0.0d;
}
}
Pepsi
:
package org.trishinfotech.builder.beverages.cold;
import org.trishinfotech.builder.beverages.BeverageSize;
public class Pepsi extends ColdDrink {
public Pepsi(BeverageSize size) {
super(size);
}
@Override public String name() {
return "Pepsi" + drinkDetails();
}
@Override public int calories() {
if (size != null) {
switch (size) {
case S:
return 160;
case M:
return 220;
case L:
return 300;
default:
break;
}
}
return 0;
}
@Override public double price() {
if (size != null) {
switch (size) {
case S:
return 1.2d;
case M:
return 2.2d;
case L:
return 2.7d;
default:
break;
}
}
return 0.0d;
}
}
HotDrink
:
package org.trishinfotech.builder.beverages.hot;
import org.trishinfotech.builder.beverages.BeverageSize;
import org.trishinfotech.builder.beverages.Drink;
import org.trishinfotech.builder.packing.Packing;
import org.trishinfotech.builder.packing.SipperMug;
public abstract class HotDrink extends Drink {
public HotDrink(BeverageSize size) {
super(size);
}
@Override public Packing packing() {
return new SipperMug();
}
}
Cuppuccinno
:
package org.trishinfotech.builder.beverages.hot;
import org.trishinfotech.builder.beverages.BeverageSize;
public class Cappuccino extends HotDrink {
public Cappuccino(BeverageSize size) {
super(size);
}
@Override public String name() {
return "Cappuccino" + drinkDetails();
}
@Override public int calories() {
if (size != null) {
switch (size) {
case S:
return 120;
case M:
return 160;
case L:
return 210;
default:
break;
}
}
return 0;
}
@Override public double price() {
if (size != null) {
switch (size) {
case S:
return 1.0d;
case M:
return 1.4d;
case L:
return 1.8d;
default:
break;
}
}
return 0.0d;
}
}
HotChocolate
:
package org.trishinfotech.builder.beverages.hot;
import org.trishinfotech.builder.beverages.BeverageSize;
public class HotChocolate extends HotDrink {
public HotChocolate(BeverageSize size) {
super(size);
}
@Override public String name() {
return "Hot Chocolate" + drinkDetails();
}
@Override public int calories() {
if (size != null) {
switch (size) {
case S:
return 370;
case M:
return 450;
case L:
return 560;
default:
break;
}
}
return 0;
}
@Override public double price() {
if (size != null) {
switch (size) {
case S:
return 1.6d;
case M:
return 2.3d;
case L:
return 3.0d;
default:
break;
}
}
return 0.0d;
}
}
:
Packing
:
package org.trishinfotech.builder.packing;
public interface Packing {
public String pack();
public double packingPrice();
}
Bottle
:
package org.trishinfotech.builder.packing;
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
@Override
public double packingPrice() {
return 0.75d;
}
}
Container
:
package org.trishinfotech.builder.packing;
public class Container implements Packing {
@Override
public String pack() {
return "Container";
}
@Override
public double packingPrice() {
return 1.25d;
}
}
MultiPack
. MutiPack
, .
package org.trishinfotech.builder.packing;
public class MultiPack implements Packing {
private double packingPrice;
public MultiPack(double packingPrice) {
super();
this.packingPrice = packingPrice;
}
@Override
public String pack() {
return "Multi-Pack";
}
@Override
public double packingPrice() {
return packingPrice;
}
}
SipperMug
:
package org.trishinfotech.builder.packing;
public class SipperMug implements Packing {
@Override
public String pack() {
return "Sipper Mug";
}
@Override
public double packingPrice() {
return 1.6d;
}
}
Wrap
:
package org.trishinfotech.builder.packing;
public class Wrap implements Packing {
@Override
public String pack() {
return "Wrap";
}
@Override
public double packingPrice() {
return 0.40d;
}
}
BillPrinter
, .
package org.trishinfotech.builder.util;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.DoubleAdder;
import org.trishinfotech.builder.Order;
import org.trishinfotech.builder.OrderService;
import org.trishinfotech.builder.meal.Meal;
import org.trishinfotech.builder.packing.Packing;
public class BillPrinter {
static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
public static void printItemisedBill(Order order) {
OrderService service = order.getService();
System.out.printf("%60s\n", "Food Court");
System.out.println("=================================================================================================================");
System.out.printf("Service: %10s (%2.2f Tax) Customer Name: %-20s\n", service.getName(), service.getTax(), order.getCustomerName());
System.out.println("-----------------------------------------------------------------------------------------------------------------");
System.out.printf("%25s | %10s | %10s | %10s | %15s | %10s | %10s\n", "Food Item", "Calories", "Packing", "Price", "Packing Price", "Discount %", "Total Price");
System.out.println("-----------------------------------------------------------------------------------------------------------------");
DoubleAdder itemTotalPrice = new DoubleAdder();
order.getFoodItems().stream().forEach(item -> {
String name = item.name();
int calories = item.calories();
Packing packing = item.packing();
double price = item.price();
double packingPrice = packing.packingPrice();
double discount = item instanceof Meal? ((Meal)item).discount() : 0.0d;
double totalItemPrice = calculateTotalItemPrice(price, packingPrice, discount);
System.out.printf("%25s | %10d | %10s | %10.2f | %15.2f | %10.2f | %10.2f\n", name, calories, packing.pack(), price, packing.packingPrice(), discount, totalItemPrice);
itemTotalPrice.add(totalItemPrice);
});
System.out.println("=================================================================================================================");
double billTotal = itemTotalPrice.doubleValue();
billTotal = applyTaxes(billTotal, service);
System.out.printf("Date: %-30s %66s %.2f\n", dtf.format(LocalDateTime.now()), "Total Bill (incl. taxes):", billTotal);
System.out.println("Enjoy your meal!\n\n\n\n");
}
private static double applyTaxes(double billTotal, OrderService service) {
return billTotal + (billTotal * service.getTax())/100;
}
private static double calculateTotalItemPrice(double price, double packingPrice, double discount) {
if (discount > 0.0d) {
price = price - (price * discount)/100;
}
return price + packingPrice;
}
}
. Order
:
package org.trishinfotech.builder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.trishinfotech.builder.meal.FoodItem;
public class Order {
private List<FoodItem> foodItems = new ArrayList<FoodItem>();
private String customerName;
private OrderService service;
public Order(OrderService service, List<FoodItem> foodItems, String customerName) {
super();
if (Objects.isNull(service)) {
throw new IllegalArgumentException(
"Meal can't be order without selecting service 'Take Away' or 'Eat Here'");
}
if (Objects.isNull(foodItems) || foodItems.stream().filter(Objects::nonNull).collect(Collectors.toList()).isEmpty()) {
throw new IllegalArgumentException(
"Meal can't be order without any food item");
}
this.service = service;
this.foodItems = new ArrayList<FoodItem>(foodItems);
this.customerName = customerName;
if (this.customerName == null) {
this.customerName = "NO NAME";
}
}
public List<FoodItem> getFoodItems() {
return foodItems;
}
public String getCustomerName() {
return customerName;
}
public OrderService getService() {
return service;
}
}
OrderBuilder
, Order
.
package org.trishinfotech.builder;
import java.util.ArrayList;
import java.util.List;
import org.trishinfotech.builder.beverages.BeverageSize;
import org.trishinfotech.builder.beverages.cold.CocaCola;
import org.trishinfotech.builder.beverages.cold.Pepsi;
import org.trishinfotech.builder.food.burger.ChickenBurger;
import org.trishinfotech.builder.food.burger.VegBurger;
import org.trishinfotech.builder.food.nuggets.CheeseNuggets;
import org.trishinfotech.builder.food.nuggets.ChickenNuggets;
import org.trishinfotech.builder.meal.FoodItem;
import org.trishinfotech.builder.meal.Meal;
public class OrderBuilder {
protected static final double HAPPY_MENU_DISCOUNT = 5.0d;
private String customerName;
private OrderService service = OrderService.TAKE_AWAY;
private List<FoodItem> items = new ArrayList<FoodItem>();
public OrderBuilder() {
super();
}
// . Order.
// Builder (, OrderBuilder), .
public OrderBuilder name(String customerName) {
this.customerName = customerName;
return this;
}
public OrderBuilder service(OrderService service) {
if (service != null) {
this.service = service;
}
return this;
}
public OrderBuilder item(FoodItem item) {
items.add(item);
return this;
}
//
public OrderBuilder vegNuggetsHappyMeal() {
List<FoodItem> foodItems = new ArrayList<FoodItem>();
foodItems.add(new CheeseNuggets());
foodItems.add(new Pepsi(BeverageSize.S));
Meal meal = new Meal("Veg Nuggets Happy Meal", foodItems, HAPPY_MENU_DISCOUNT);
return item(meal);
}
public OrderBuilder chickenNuggetsHappyMeal() {
List<FoodItem> foodItems = new ArrayList<FoodItem>();
foodItems.add(new ChickenNuggets());
foodItems.add(new CocaCola(BeverageSize.S));
Meal meal = new Meal("Chicken Nuggets Happy Meal", foodItems, HAPPY_MENU_DISCOUNT);
return item(meal);
}
public OrderBuilder vegBurgerHappyMeal() {
List<FoodItem> foodItems = new ArrayList<FoodItem>();
foodItems.add(new VegBurger());
foodItems.add(new Pepsi(BeverageSize.S));
Meal meal = new Meal("Veg Burger Happy Meal", foodItems, HAPPY_MENU_DISCOUNT);
return item(meal);
}
public OrderBuilder chickenBurgerHappyMeal() {
List<FoodItem> foodItems = new ArrayList<FoodItem>();
foodItems.add(new ChickenBurger());
foodItems.add(new CocaCola(BeverageSize.S));
Meal meal = new Meal("Chicken Burger Happy Meal", foodItems, HAPPY_MENU_DISCOUNT);
return item(meal);
}
public Order build() {
Order order = new Order(service, items, customerName);
if (!validateOrder()) {
System.out.println("Sorry! Order can't be placed without service type (Take Away/Eat Here) and any food item.");
return null;
}
return order;
}
private boolean validateOrder() {
return (service != null) && !items.isEmpty();
}
}
! Main
:
package org.trishinfotech.builder;
import org.trishinfotech.builder.beverages.BeverageSize;
import org.trishinfotech.builder.beverages.cold.CocaCola;
import org.trishinfotech.builder.beverages.cold.Pepsi;
import org.trishinfotech.builder.beverages.hot.HotChocolate;
import org.trishinfotech.builder.food.burger.ChickenBurger;
import org.trishinfotech.builder.food.nuggets.CheeseNuggets;
import org.trishinfotech.builder.food.nuggets.ChickenNuggets;
import org.trishinfotech.builder.util.BillPrinter;
public class Main {
public static void main(String[] args) {
OrderBuilder builder1 = new OrderBuilder();
// you can see the use of chained calls of setters here. No statement terminator
// till we set all the values of the object
Order meal1 = builder1.name("Brijesh").service(OrderService.TAKE_AWAY).item(new ChickenBurger())
.item(new Pepsi(BeverageSize.M)).vegNuggetsHappyMeal().build();
BillPrinter.printItemisedBill(meal1);
OrderBuilder builder2 = new OrderBuilder();
Order meal2 = builder2.name("Micheal").service(OrderService.EAT_HERE).item(new ChickenNuggets())
.item(new CheeseNuggets()).item(new CocaCola(BeverageSize.L)).chickenBurgerHappyMeal()
.item(new HotChocolate(BeverageSize.M)).vegBurgerHappyMeal().build();
BillPrinter.printItemisedBill(meal2);
}
}
:
Food Court
=================================================================================================================
Service: Take Away (2.00 Tax) Customer Name: Brijesh
-----------------------------------------------------------------------------------------------------------------
Food Item | Calories | Packing | Price | Packing Price | Discount % | Total Price
-----------------------------------------------------------------------------------------------------------------
Chicken Burger | 300 | Wrap | 4.50 | 0.40 | 0.00 | 4.90
Pepsi (M) | 220 | Bottle | 2.20 | 0.75 | 0.00 | 2.95
Veg Nuggets Happy Meal | 490 | Multi-Pack | 5.00 | 2.00 | 5.00 | 6.75
=================================================================================================================
Date: 2020/10/09 20:02:38 Total Bill (incl. taxes): 14.89
Enjoy your meal!
Food Court
=================================================================================================================
Service: Eat Here (5.50 Tax) Customer Name: Micheal
-----------------------------------------------------------------------------------------------------------------
Food Item | Calories | Packing | Price | Packing Price | Discount % | Total Price
-----------------------------------------------------------------------------------------------------------------
Chicken Nuggets | 450 | Container | 5.00 | 1.25 | 0.00 | 6.25
Cheese Nuggets | 330 | Container | 3.80 | 1.25 | 0.00 | 5.05
Coca-Cola (L) | 290 | Bottle | 2.00 | 0.75 | 0.00 | 2.75
Chicken Burger Happy Meal | 450 | Multi-Pack | 5.50 | 1.15 | 5.00 | 6.38
Hot Chocolate (M) | 450 | Sipper Mug | 2.30 | 1.60 | 0.00 | 3.90
Veg Burger Happy Meal | 340 | Multi-Pack | 3.90 | 1.15 | 5.00 | 4.86
=================================================================================================================
Date: 2020/10/09 20:02:38 Total Bill (incl. taxes): 30.78
Enjoy your meal!
! , Builder.
: Real-Builder-Design-Pattern-Source-Code
: Builder-Design-Pattern-Sample-Code
« ».