java设计模式之建造者模式(Builder Pattern)
将一个复杂对象的构建与它的表示分离,使得同样的构建可以创建不同的表示。摘自《大话设计模式》。
简单实现
我们这里定义一个产品类(Product)和部分接口(每个部件Part)。这里我们模仿一个早餐得各种套餐,而每种套餐都包括一个主食和饮品,而一个完整的产品是由各个部分组成,其中定义了一个add()方法,让这个完整的产品自由的添加相应得部分。
一个套餐就是一种产品。
/**
* @Description 每个部分
* @Author lijia
* @Date 2020/11/17 10:22
*/
public interface Food {
/**
* 名称
*/
String name();
/**
* 功能
*/
String description();
}
/**
* @Description 产品类
* @Author lijia
* @Date 2020/11/17 10:20
*/
public class Product {
/**
* 一个产品 可以是各个部分组成
*/
private List<Food> foodList = new ArrayList();
public void add(Food food) {
this.foodList.add(food);
}
public void show() {
partList.stream().forEach(item -> {
System.out.println(item.name() + "---[" + item.description()+"]");
});
}
}
而每个食物都有同样得属性,
/**
* @Description 面条类
* @Author lijia
* @Date 2020/11/17 10:25
*/
public class Noodles implements Food {
@Override
public String name() {
return "面条";
}
@Override
public String description() {
return "面食";
}
}
/**
* @Description
* @Author lijia
* @Date 2020/11/17 10:33
*/
public class Egg implements Food {
@Override
public String name() {
return "鸡蛋";
}
@Override
public String description() {
return "蛋类";
}
}
/**
* @Description
* @Author lijia
* @Date 2020/11/17 10:27
*/
public class Milk implements Food {
@Override
public String name() {
return "牛奶";
}
@Override
public String description() {
return "饮品";
}
}
声明一个抽象的建造者,定义了一个产品是有两部分组成。
/**
* @Description
* @Author lijia
* @Date 2020/11/17 10:46
*/
public interface Builder {
void addFood();
void addWater();
Product getProduct();
}
具体建造者,建造了两个具体的部件。
/**
* @Description 具体建造者一 (套餐一)
* @Author lijia
* @Date 2020/11/17 10:44
*/
public class CategoryOneBuilder implements Builder {
private Product product = new Product();
@Override
public void addFood() {
product.add(new Noodles());
}
@Override
public void addWater() {
product.add(new Milk());
}
@Override
public Product getProduct() {
return product;
}
}
/**
* @Description 具体建造者二 (套餐二)
* @Author lijia
* @Date 2020/11/17 10:44
*/
public class CategoryTowBuilder implements Builder {
private Product product = new Product();
@Override
public void addFood() {
product.add(new Egg());
}
@Override
public void addWater() {
product.add(new Milk());
}
@Override
public Product getProduct() {
return product;
}
}
客户端代码一
/**
* @Description
* @Author lijia
* @Date 2020/11/17 10:41
*/
public class Main {
public static void main(String[] args) {
Builder builder=new CategoryOneBuilder();
builder.addFood();
builder.addWater();
Product product = builder.getProduct();
product.show();
}
}
从客户端代码可以看出,建造者建造一个完成的产品还是在客户端进行,可能导致建造出的产品缺失。因此引入一个指挥者,指挥建造者的建造过程,改进
/**
* @Description
* @Author lijia
* @Date 2020/11/18 14:52
*/
public class Director {
public void createProduct(Builder builder){
builder.addFood();
builder.addWater();
}
}
改进客户端
/**
* @Description
* @Author lijia
* @Date 2020/11/17 10:41
*/
public class Main {
public static void main(String[] args) {
Director director=new Director();
Builder builder1=new CategoryOneBuilder();
Builder builder2=new CategoryTowBuilder();
director.createProduct(builder1);
Product product1 = builder1.getProduct();
product1.show();
director.createProduct(builder2);
Product product2 = builder2.getProduct();
product2.show();
}
}