什么是建造者模式
建造者模式可以简单理解为搭积木建房子,是我们一步一步、一层一层来搭建对象的过程,属于创建型模式,一般对象会提供一个Builder来进行构造。在构建的过程中我们不需要知道构建的过程,我们只需要告诉构建者我想要什么就可以了。
详细介绍
举个例子,假如我们去肯德基点餐有大概以下几步:
- 点一个汉堡
- 点一杯可乐
- 服务员下单
其中 我们前三个的顺序其实是可以随意切换的,可以先要可乐再要汉堡,下单是最后的build操作,来生成我们最终的订单。当然我们如果学了装饰器模式后可以选择要冰可乐和双牛堡,这个后边装饰器模式讲。
我们看下类的结构图。
实战代码
package com.chengfengfeng.design.builder;
/**
* 订单项
* @author: chengzhangheng
* @create: 2020-09-12 15:09
**/
public interface Item {
String getName();
int getPrice();
int getNum();
default int getFee() {
return getNum() * getPrice();
}
}
package com.chengfengfeng.design.builder;
import lombok.Data;
/**
* 可乐
* @author: chengzhangheng
* @create: 2020-09-12 15:05
**/
@Data
public class Cola implements Item{
private String name = "可 乐";
private int price = 5;
private int num;
Cola(int num) {
this.num = num;
}
}
package com.chengfengfeng.design.builder;
import lombok.Data;
/**
* @author: chengzhangheng
* @create: 2020-09-12 15:04
**/
@Data
public class Burger implements Item {
private String name = "汉堡包";
private int price = 5;
private int num;
Burger(int num) {
this.num = num;
}
}
package com.chengfengfeng.design.builder;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 订单
*
* @author: chengzhangheng
* @create: 2020-09-12 15:08
**/
@Data
public class Order {
/**
* 订单号
*/
private String orderNum;
/**
* 订单项
*/
private List<Item> items;
/**
* 打印我们的订单
*/
public void print() {
System.out.println(" *订单*");
System.out.println("订单号: " + this.orderNum);
System.out.println("----------------------------");
System.out.println("名称 | 单价 | 数量 | 总计 ");
items.forEach(item -> System.out.println(
String.format("%s %s %s %s ",
item.getName(), item.getPrice(), item.getNum(), item.getFee())));
}
public static class Builder {
private List<Item> items;
public Builder add(Item item) {
if (this.items == null) {
this.items = new ArrayList<>();
}
this.items.add(item);
return this;
}
public Order build() {
Order order = new Order();
//订单号先随便给
order.setOrderNum("1");
order.setItems(this.items);
return order;
}
}
}
package com.chengfengfeng.design.builder;
/**
* @author: chengzhangheng
* @create: 2020-09-12 15:15
**/
public class Test {
public static void main(String[] args) {
//我们要两个可乐
//两个汉堡
Order.Builder builder = new Order.Builder();
Order order = builder.add(new Burger(2))
.add(new Cola(2))
.build();
order.print();
}
}
看下我们的执行结果。
除了订餐,我们另外一个经常用到的建造者模式是mybatis plus用来构建sql语句,我们只需要设置参数,最终构建者会遵循sql规则帮我们构造成一个完整的sql语句,我们在设置的时候无需担心顺序问题,这就是内部细节隐藏。
testMapper.selectCount(new QueryWrapper<Test>()
.eq("id", id)
.le("age", 18)
.eq("sex", 1);