建造者模式
2022-12-01 本文已影响0人
慎独静思
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
它使用多个简单的对象一步一步构建成一个复杂的对象,复杂对象通常由各个部分的子对象用一定的算法构成,当各个部分可能经常变化,但组合它们的算法确相对稳定时可以考虑使用建造者模式。
上图中我们创建了一个复杂对象,复杂对象是由两个简单对象构成的,组成复杂对象的简单对象可能经常变化,但组合它们的算法,也就是Builder对象是相对稳定的,此时可以考虑使用建造者模式。
咱们还是用抽象工厂模式 中提到的早餐的例子来说明
interface Item {
float getPrice();
}
interface Drinks extends Item {
void drink();
}
class Soybean implements Drinks {
@Override
public void drink() {
System.out.println("drink Soybean");
}
@Override
public float getPrice() {
return 1.5f;
}
}
class Milk implements Drinks {
@Override
public void drink() {
System.out.println("drink milk");
}
@Override
public float getPrice() {
return 2f;
}
}
interface Pasta extends Item {
void eat();
}
class YouTiao implements Pasta {
@Override
public void eat() {
System.out.println("eat you tiao");
}
@Override
public float getPrice() {
return 1f;
}
}
class Bread implements Pasta {
@Override
public void eat() {
System.out.println("eat bread");
}
@Override
public float getPrice() {
return 2.5f;
}
}
以上内容是我们创建的simple item
interface Meal {
void orderItem(Item item);
float getCost();
}
class Breakfast implements Meal {
private List<Item> items = new ArrayList<>();
@Override
public void orderItem(Item item) {
items.add(item);
}
@Override
public float getCost() {
float result = 0f;
for (Item item: items) {
result += item.getPrice();
}
return result;
}
}
这是我们创建的早餐类,它是个复杂对象
interface MealBuilder {
void startOrder();
Meal getMeal();
}
class BreakfastBuilder implements MealBuilder {
private Meal meal;
@Override
public void startOrder() {
meal = new Breakfast();
}
public void orderSoybean(int count) {
Objects.requireNonNull(meal);
for (int i = 0; i < count; i++) {
meal.orderItem(new Soybean());
}
}
public void orderMilk(int count) {
Objects.requireNonNull(meal);
for (int i = 0; i < count; i++) {
meal.orderItem(new Milk());
}
}
public void orderYouTiao(int count) {
Objects.requireNonNull(meal);
for (int i = 0; i < count; i++) {
meal.orderItem(new YouTiao());
}
}
public void orderBread(int count) {
Objects.requireNonNull(meal);
for (int i = 0; i < count; i++) {
meal.orderItem(new Bread());
}
}
@Override
public Meal getMeal() {
return meal;
}
}
这是我们创建的builder,它用来创建复杂对象。
BreakfastBuilder mealBuilder = new BreakfastBuilder();
mealBuilder.startOrder();
mealBuilder.orderSoybean(2);
mealBuilder.orderYouTiao(3);
mealBuilder.orderBread(2);
Meal meal = mealBuilder.getMeal();
System.out.println("Price is " + meal.getCost());
这是客户端使用builder创建meal的过程,builder隐藏了创建复杂对象的细节,给客户提供了方便调用的接口。
标准的使用过程中还存在一个Director角色,用来构建建造者,此处未使用。
平时我们比较常用的是链式调用的建造者模式。
class Breakfast implements Meal {
private List<Item> items = new ArrayList<>();
public Breakfast(Builder builder) {
items.addAll(builder.items);
}
@Override
public void orderItem(Item item) {
items.add(item);
}
@Override
public float getCost() {
float result = 0f;
for (Item item : items) {
result += item.getPrice();
}
return result;
}
public static class Builder {
private List<Item> items = new ArrayList<>();
public Builder orderSoybean(int count) {
for (int i = 0; i < count; i++) {
items.add(new Soybean());
}
return this;
}
public Builder orderMilk(int count) {
for (int i = 0; i < count; i++) {
items.add(new Milk());
}
return this;
}
public Builder orderYouTiao(int count) {
for (int i = 0; i < count; i++) {
items.add(new YouTiao());
}
return this;
}
public Builder orderBread(int count) {
for (int i = 0; i < count; i++) {
items.add(new Bread());
}
return this;
}
public Breakfast build() {
return new Breakfast(this);
}
}
}
我们以链式调用的方式重写了上边的例子。
Meal breakfast = new Breakfast.Builder()
.orderSoybean(2)
.orderBread(3)
.orderYouTiao(2)
.build();
System.out.println("Price is: " + breakfast.getCost());
直观上来说,感觉链式调用的方式更容易理解和使用,可能是因为平时接触的最多的还是链式调用的构建者模式。
看了一遍又写了一遍,感觉还是一知半解,悲
可能脑海中有这个印象了吧,遇到问题可以朝这个方向考虑。
完结。
参考
《设计模式-可复用面向对象软件的基础》