建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。使得多个简单的对象一步一步构建成一个复杂的对象。
建造者模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们。可以不必知道内部的具体构建细节,有点类似抽象工程模式。
比如一个汽车,有很多部件:车轮,车架,发动机还有各种小零件,这些部件被装配成一辆汽车,装配过程也非常复杂,builder模式就是为了将部件和组装过程分开。
组成一辆汽车需要这些部件,车轮可以是韩泰轮胎或者米其林轮胎,它们是橡胶的。发动机可以是德国造的或者是日本造的,它们是合金的。
我们创建一个表示车的type接口和实现type接口的实体类,以及一个表示零部件组装材料的packing接口和实现packing接口的实体类,轮胎是橡胶的,发动机是合金的。
我们创建一个car类,带有type的ArrayList和一个通过结合type来创建不同类型的Car对象的CarBuilder。用BuilderPatternDemo来演示。
创建一个表示车的type接口和组装车的packing接口:
type.java
public interface Type {
public String probenance();
public Packing packing();
public float price();
}
Packing.java
public interface Packing {
public String pack();
}
创建实现Packing接口的实体类:
Rubber.java
public class Rubber implements Packing {
@Override
public String pack() {
return "Rubber: 组装轮胎";
}
}
Metal.java
public class Metal implements Packing {
@Override
public String pack() {
return "Metal: 组装发动机";
}
}
创建实现Type接口的抽象类,该类提供了默认的功能。
Tyre.java
public abstract class Tyre implements Type {
@Override
public Packing packing() {
return new Rubber();
}
@Override
public abstract float price();
}
Motor.java
public abstract class Motor implements Type {
@Override
public Packing packing() {
return new Metal();
}
@Override
public abstract float price();
}
创建实现了Tyre和Motor的实体类
Michelin.java
public class Michelin extends Tyre {
@Override
public float price() {
return 2500.0f;
}
@Override
public String probenance() {
return "Michenlin Tyre";
}
}
Hankook.java
public class Hankook extends Tyre{
@Override
public float price() {
return 1500.0f;
}
@Override
public String probenance() {
return "Hankook Tyre";
}
}
Audi.java
public class Audi extends Motor{
@Override
public float price() {
return 15000.0f;
}
@Override
public String probenance() {
return "Audi Motor";
}
}
BMW.java
public class BMW extends Motor{
@Override
public float price() {
return 25000.0f;
}
@Override
public String probenance() {
return "BMW Motor";
}
}
创建一个Car类,带有上面定义的Type对象
car.java
import java.util.ArrayList;
import java.util.List;
public class Car {
private List<Type> types = new ArrayList<Type>();
public void addType(Type item) {
types.add(item);
}
public float getCost() {
float cost = 0.0f;
for (Type type : types) {
cost += type.price();
}
return cost;
}
public void showItems() {
for (Type type : types) {
System.out.print("Type : " + type.probenance());
System.out.print(", Packing : " + type.packing().pack());
System.out.println(", Price : " + type.price());
}
}
}
创建一个CarBuilder类,实际的builder类负责创建Car对象。
CarBuilder.java
public class CarBuilder {
public Car prepareLessCar (){
Car car = new Car();
car.addType(new Hankook());
car.addType(new Audi());
return car;
}
public Car prepareMoreCar (){
Car car = new Car();
car.addType(new Michelin());
car.addType(new BMW());
return car;
}
}
BuiderPatternDemo 使用 CarBuider来演示建造者模式(Builder Pattern)。
BuiderPatternDemo.java
public class BuiderPatternDemo {
public static void main(String[] args) {
CarBuilder carBuilder = new CarBuilder();
Car lessCar = carBuilder.prepareLessCar();
System.out.println("Less Car");
lessCar.showItems();
System.out.println("Total Cost: " +lessCar.getCost());
Car moreCar = carBuilder.prepareMoreCar();
System.out.println("\n\nMore Car");
moreCar.showItems();
System.out.println("Total Cost: " +moreCar.getCost());
}
}
结果演示:
Less Car
Type : Hankook Tyre, Packing : Rubber: 组装轮胎, Price : 1500.0
Type : Audi Motor, Packing : Metal: 组装发动机, Price : 15000.0
Total Cost: 16500.0
More Car
Type : Michenlin Tyre, Packing : Rubber: 组装轮胎, Price : 2500.0
Type : BMW Motor, Packing : Metal: 组装发动机, Price : 25000.0
Total Cost: 27500.0
优点:
建造者独立,易扩展。
便于控制细节风险。
缺点:
产品必须有共同点,范围有限制。
如内部变化复杂,会有很多的建造类。
使用场景:
需要生成的对象具有复杂的内部结构。
需要生成的对象内部属性本身相互依赖。