建造者模式
◆建造者模式也属于创建型模式,它提供了一种创建对象的最佳方式。
◆定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
◆主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
◆用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细
节隐藏起来)
◆例子:
- 工厂(建造者模式) :负责制造汽车(组装过>程和细节在工厂内)
- 汽车购买者(用户) :你只需要说出你需要的>型号(对象的类型和内容),然后直接购买就可以使用了(不需要知道汽车是怎么组装的(车轮、 车门、>发动机、方向盘等等) )
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201225214333606.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzg0NzQ5,size_16,color_FFFFFF,t_70)
建造者模式的四个角色
- Product(产品角色): 一个具体的产品对象。
- Builder(抽象建造者): 创建一个Product对象的各个部件指定的 接口/抽象类。
- ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件。
- Director(指挥者): 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。指挥者指挥我们的具体的建造者来完成我们的产品
例一:
public class Director {
public Product build(Builder builder){
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
public abstract class Builder {
abstract void buildA();
abstract void buildB();
abstract void buildC();
abstract void buildD();
abstract Product getProduct();
}
public class Worker extends Builder{
private Product product;
public Worker(){
product = new Product();
}
@Override
void buildA() {
product.setBuildA("建地基");
System.out.println("建地基");
}
@Override
void buildB() {
product.setBuildB("钢筋工程");
System.out.println("钢筋工程");
}
@Override
void buildC() {
product.setBuildC("铺电线");
System.out.println("铺电线");
}
@Override
void buildD() {
product.setBuildD("粉刷");
System.out.println("粉刷");
}
@Override
Product getProduct() {
return product;
}
}
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() { return buildA; }
public void setBuildA(String buildA) { this.buildA = buildA; }
public String getBuildB() { return buildB; }
public void setBuildB(String buildB) { this.buildB = buildB; }
public String getBuildC() { return buildC; }
public void setBuildC(String buildC) { this.buildC = buildC; }
public String getBuildD() { return buildD; }
public void setBuildD(String buildD) { this.buildD = buildD; }
}
public class Test {
public static void main(String[] args) {
Director director = new Director();
Product build = director.build(new Worker());
System.out.println(build.toString());
}
}
例二
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210315225611927.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzg0NzQ5,size_16,color_FFFFFF,t_70)
代码如下:
public class
BuilderPatternDemo1 {
public static void main(String[] args) {
CommonHouse commonHouse = new CommonHouse();
HouseDirector houseDirector = new HouseDirector(commonHouse);
House house = houseDirector.constructHouse();
System.out.println("--------------------------");
HighBuilding highBuilding = new HighBuilding();
houseDirector.setHouseBuilder(highBuilding);
houseDirector.constructHouse();
}
}
class House {
private String baise;
private String wall;
private String roofed;
public String getBaise() {
return baise;
}
public void setBaise(String baise) {
this.baise = baise;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getRoofed() {
return roofed;
}
public void setRoofed(String roofed) {
this.roofed = roofed;
}
}
abstract class HouseBuilder {
protected House house = new House();
public abstract void buildBasic();
public abstract void buildWalls();
public abstract void roofed();
public House buildHouse() {
return house;
}
}
class CommonHouse extends HouseBuilder {
@Override
public void buildBasic() {
System.out.println(" 普通房子打地基5米 ");
}
@Override
public void buildWalls() {
System.out.println(" 普通房子砌墙10cm ");
}
@Override
public void roofed() {
System.out.println(" 普通房子屋顶 ");
}
}
class HighBuilding extends HouseBuilder {
@Override
public void buildBasic() {
System.out.println(" 高楼的打地基100米 ");
}
@Override
public void buildWalls() {
System.out.println(" 高楼的砌墙20cm ");
}
@Override
public void roofed() {
System.out.println(" 高楼的透明屋顶 ");
}
}
class HouseDirector {
HouseBuilder houseBuilder = null;
public HouseDirector(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
public void setHouseBuilder(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
public House constructHouse() {
houseBuilder.buildBasic();
houseBuilder.buildWalls();
houseBuilder.roofed();
return houseBuilder.buildHouse();
}
}
上面示例是Builder模式的常规用法,导演类Director在Builder模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director和抽象建造者进行结合。
通过静态内部类方式实现零件无序装配构造,这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式。就可以生产出不同复杂产品
比如:比如麦当劳的套餐,服务员(具体建造者)可以随意搭配任意几种产品(零件)组成一款套餐(产品),然后出售给客户。比第一种方式少 了指挥者,主要是因为第二种方式把指挥者交给用户来操作,使得产品的创建更加简单灵活。
例三: 没有指挥者参与
public abstract class Builder {
abstract Builder buildA(String msg);
abstract Builder buildB(String msg);
abstract Builder buildC(String msg);
abstract Builder buildD(String msg);
abstract Product getProduct();
}
public class Worker extends Builder{
private Product product;
public Worker(){ product = new Product(); }
@Override
Builder buildA(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildB(String msg) {
product.setBuildB(msg);
return this;
}
@Override
Builder buildC(String msg) {
product.setBuildC(msg);
return this;
}
@Override
Builder buildD(String msg) {
product.setBuildD(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
public class Product {
private String BuildA = "汉堡";
private String BuildB = "可乐";
private String BuildC = "薯条";
private String BuildD = "甜点";
public String getBuildA() { return BuildA; }
public void setBuildA(String buildA) { BuildA = buildA; }
public String getBuildB() { return BuildB; }
public void setBuildB(String buildB) { BuildB = buildB; }
public String getBuildC() { return BuildC; }
public void setBuildC(String buildC) { BuildC = buildC; }
public String getBuildD() { return BuildD; }
public void setBuildD(String buildD) { BuildD = buildD; }
@Override
public String toString() {
return "Product{" +
"BuildA='" + BuildA + '\'' +
", BuildB='" + BuildB + '\'' +
", BuildC='" + BuildC + '\'' +
", BuildD='" + BuildD + '\'' +
'}';
}
}
public class Test {
public static void main(String[] args) {
Worker worker = new Worker();
Product product = worker.buildA("鸡肉卷").buildB("橘子汽水").getProduct();
System.out.println(product.toString());
}
}
例四:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210315230038844.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzg0NzQ5,size_16,color_FFFFFF,t_70)
import java.util.ArrayList;
import java.util.List;
public class BuilderPatternDemo2 {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " +vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " +nonVegMeal.getCost());
}
}
interface Item {
public String name();
public Packing packing();
public float price();
}
interface Packing {
public String pack();
}
class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item){
items.add(item);
}
public float getCost(){
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems(){
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
}
class MealBuilder {
public Meal prepareVegMeal (){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal (){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
◆应用场景:
- 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
- 适合于一 个具有较多的零件(属性)的产品(对象)的创建过程。
◆建造者与抽象工厂模式的比较:
- 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。
- 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象, 返回一个完整的对象。
- 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回-一辆完整的汽车!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)