建造者模式(Builder Pattern),是通过对对象一个一个创建,最终构成一个复杂的对象。
我们在做开发的时候,有时候会面临很复杂的一个对象,怎么办?那就先不考虑那么复杂的情况,从简单的对象逐步构建。比如造房子的时候,我们不需要一下造出来摩天大楼,但是我们可以从地基开始,一层一层楼盖,最终建造成摩天大厦。
再比如,被熟知的KFC套餐,你可以买“可乐+牛肉堡”套餐A,也可以买“雪碧+鸡排堡”套餐B。用户不用知道套餐A或者套餐B怎么做,只需要知道这两个套餐里面有什么,并下单买就可以。
一般来说,这种模式主要包含四个角色,想想看,去KFC点餐的时候是不是也是四个角色?
- 产品(Product):就是汉堡,薯条,可乐什么的。
- 建造者(Builder):就是KFC官方,告诉KFC店什么可以当做套餐,比如KFC官方告诉KFC门店“鸡翅+可乐”可以成为新套餐。
- 具体实施者(ConcreteBuilder):厨师,具体实现“鸡翅,可乐,汉堡”等食物的人。
- 指挥者(Director):服务员,帮你装配好套餐。
接下来我们写代码来看一下:
public class Product { //店内有什么产品
private String food;
private String drink;
public String getDrink() {
return drink;
}
public void setDrink(String drink) {
this.drink = drink;
}
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
}
public interface Builder { //KFC告诉你有什么套餐,但具体实现靠KFC门店
Product product = new Product();
public void buildFood();
public void buildDrink();
public default Product getProduct(){ //JDK1.8
return product;
}
}
public class ConcreteBuilderA implements Builder{//套餐A包含的食物
@Override
public void buildFood() {
product.setFood("牛肉堡");
}
@Override
public void buildDrink() {
product.setDrink("可乐");
}
}
public class ConcreteBuilderB implements Builder{//套餐B包含的食物
@Override
public void buildFood() {
product.setFood("鸡排堡");
}
@Override
public void buildDrink() {
product.setDrink("雪碧");
}
}
public class Director { //服务员为客户打包
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public Product getProduct(){
builder.buildFood();
builder.buildDrink();
return builder.getProduct(); //打包套餐(由上述方法得到的食物进行打包)
}
}
public class Consumer {
public static void main(String[] args) {
//消费者想要套餐A:牛肉堡+可乐
ConcreteBuilderA concreteBuilderA = new ConcreteBuilderA();
//服务员了解需求
Director director = new Director(concreteBuilderA);
//服务员将套餐打包
Product product = director.getProduct();
//给用户展示套餐
System.out.println("用户点的饮料是:"+product.getDrink()+"; 用户点的食物是:"+product.getFood());
}
}
我们通过主方法可以看到,当用户知道套餐A或者套餐B是什么的时候,不必再为套餐怎么装配或者怎么做饭烦恼,只需告诉服务员自己想要套餐几,因此具体内部细节被忽略。这就是他的优点。
总结:
- 优点:
-
用户不必知道具体实现过程,提高了软件的可复用性,降低了耦合度。也因此开发者可以创建许多新的对象而不必考虑与其他对象的关联。
-
增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合 “开闭原则”
-
缺点
- 当用户所需产品差异性较大时不建议使用。(去KFC点宫保鸡丁)
- 类的声明较为复杂。上述很基本的实现方式,用到了4个类一个接口。若类内部关联很复杂,则会创建过多的类,使得程序逻辑混乱,降低了可读性。
与抽象工厂模式的区别:
- 抽象工厂模式更关注整体框架,建造者模式更关心为用户的服务
上述是“官话”,也就是废话,我倒是没想出来这俩区别在哪,感觉二者挺像的。但是功夫不到家,理解也比较浅显,所以不太能理解二者去区别。希望有大神可以留个言,指导一下~