建造者模式
该设计模式解决的问题是在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
该模式有两种实现方向:
- 有一个制造者有自己的一套制造方案来制造该对象
- 自己指定制造计划
制造者制造
场景:造汽车
汽车类
@Data
@NoArgsConstructor
@ToString
@AllArgsConstructor
public class Car {
private CarBody carBody;
private Engine engine;
private Lamp lamp;
private Window window;
public boolean isWhole(){
if(carBody!=null&&engine!=null&&lamp!=null&&window!=null){
return true;
}
return false;
}
}
组件接口
public interface Component {
}
车身
public interface CarBody extends Component {
void printName();
}
引擎
public interface Engine extends Component {
void printName();
}
车窗
public interface Window extends Component {
void printName();
}
好的车身
public class GoodCarBody implements CarBody{
@Override
public void printName() {
System.out.println("好的车身");
}
}
不好的车身
public class BadCarBody implements CarBody{
@Override
public void printName() {
System.out.println("差的车身");
}
}
好的引擎
public class GoodEngine implements Engine{
@Override
public void printName() {
System.out.println("好的发动机");
}
}
不好的引擎
public class BadEngine implements Engine{
@Override
public void printName() {
System.out.println("差的发动机");
}
}
好的车窗
public class GoodWindow implements Window{
@Override
public void printName() {
System.out.println("好的车窗");
}
}
不好的车窗
public class BadWindow implements Window{
@Override
public void printName() {
System.out.println("差的车窗");
}
}
车的建造者
public interface CarBuilder {
void addCarBody(CarBody carBody);
void addWindow(Window window);
void addLamp(Lamp lamp);
void addEngine(Engine engine);
Car getCar();
}
具体的建造者
public class DaZhongCarBulder implements CarBuilder {
private Car car;
public DaZhongCarBulder(){
car = new Car();
}
@Override
public void addCarBody(CarBody carBody) {
if(carBody==null){
car.setCarBody(new GoodCarBody());
return;
}
car.setCarBody(carBody);
}
@Override
public void addWindow(Window window) {
if(window==null){
car.setWindow(new GoodWindow());
return;
}
car.setWindow(window);
}
@Override
public void addLamp(Lamp lamp) {
if(lamp==null){
car.setLamp(new GoodLamp());
return;
}
car.setLamp(lamp);
}
@Override
public void addEngine(Engine engine) {
if(engine==null){
car.setEngine(new GoodEngine());
return;
}
car.setEngine(engine);
}
@Override
public Car getCar() {
if(!car.isWhole()){
throw new IllegalArgumentException("零件不齐,车不能出厂");
}
return car;
}
}
指导者
public class Director {
public static Car getCar(CarBuilder carBuilder){
carBuilder.addWindow(null);
carBuilder.addCarBody(null);
carBuilder.addLamp(new BadLamp());
carBuilder.addEngine(null);
return carBuilder.getCar();
}
}
自定义建造
我们发现,有车由四部分组成,这四部分可以是同一个工厂造出来的,所以我们可以结合一个抽象工厂模式,将产品制造交给工厂。
组件工厂接口
public interface ComponentFactory {
CarBody getCarBody();
Engine getEngine();
Window getWindow();
Lamp getLamp();
}
不好的组件工厂
public class BadFactory implements ComponentFactory{
@Override
public CarBody getCarBody() {
return new BadCarBody();
}
@Override
public Engine getEngine() {
return new BadEngine();
}
@Override
public Window getWindow() {
return new BadWindow();
}
@Override
public Lamp getLamp() {
return new BadLamp();
}
}
好的组件工厂
public class GoodFactory implements ComponentFactory{
@Override
public CarBody getCarBody() {
return new GoodCarBody();
}
@Override
public Engine getEngine() {
return new GoodEngine();
}
@Override
public Window getWindow() {
return new GoodWindow();
}
@Override
public Lamp getLamp() {
return new GoodLamp();
}
}
改造CarBuilder
public interface CarBuilder {
CarBuilder addCarBody(CarBody carBody);
CarBuilder addWindow(Window window);
CarBuilder addLamp(Lamp lamp);
CarBuilder addEngine(Engine engine);
Car getCar();
}
具体制造商
public class DaZhongCarBulder implements CarBuilder {
private Car car;
public DaZhongCarBulder(){
car = new Car();
}
@Override
public CarBuilder addCarBody(CarBody carBody) {
car.setCarBody(carBody);
return this;
}
@Override
public CarBuilder addWindow(Window window) {
car.setWindow(window);
return this;
}
@Override
public CarBuilder addLamp(Lamp lamp) {
car.setLamp(lamp);
return this;
}
@Override
public CarBuilder addEngine(Engine engine) {
car.setEngine(engine);
return this;
}
@Override
public Car getCar() {
if(!car.isWhole()){
throw new IllegalArgumentException("零件不齐,车不能出厂");
}
return car;
}
}
客户端自定义制造
public class Customer {
public static void main(String[] args) {
DaZhongCarBulder daZhongCarBulder = new DaZhongCarBulder();
ComponentFactory goodFactory = new GoodFactory();
ComponentFactory badFactory = new BadFactory();
// 这就是链式编程
Car car = daZhongCarBulder
.addCarBody(goodFactory.getCarBody())
.addEngine(badFactory.getEngine())
.addLamp(goodFactory.getLamp())
.addWindow(goodFactory.getWindow())
.getCar();
System.out.println(car);
}
}
加深理解
再来个案例:kfc点餐
首先食物接口
public interface Food {
}
饮料接口
public interface Drink extends Food{
void drink();
}
薯条接口
public interface Chip extends Food{
void eatChip();
}
炸鸡接口
public interface Chicken extends Food{
void eatChicken();
}
奥尔良炸鸡
public class OrleansFriedChicken implements Chicken{
@Override
public void eatChicken() {
System.out.println("奥尔良炸鸡");
}
}
孜然炸鸡
public class CuminFriedChicken implements Chicken{
@Override
public void eatChicken() {
System.out.println("孜然炸鸡");
}
}
可乐
public class Cola implements Drink{
@Override
public void drink() {
System.out.println("可口可乐");
}
}
大薯条
public class BigChip implements Chip{
@Override
public void eatChip() {
System.out.println("大份薯条");
}
}
百事可乐
public class BaiShi implements Drink {
@Override
public void drink() {
System.out.println("百事可乐");
}
}
订单
@Data
@ToString
public class Order {
private List<Food> foods;
public Order(){
foods = new ArrayList<>();
}
public void addFood(Food food){
foods.add(food);
}
}
点单小程序
public class OrderApplication implements Builder{
private Order order;
public OrderApplication(){
order = new Order();
}
@Override
public Builder addFood(Food food) {
order.addFood(food);
return this;
}
@Override
public Order getOrder() {
if(order.getFoods().size()==0){
throw new IllegalArgumentException("您未点单!");
}
return order;
}
}
客户端
public static void main(String[] args) {
OrderApplication orderApplication = new OrderApplication();
Order order = orderApplication
.addFood(new BigChip())
.addFood(new OrleansFriedChicken())
.addFood(new Cola())
.getOrder();
System.out.println(order);
}