设计模式-建造者模式

  • 定义

将复杂的对象创建过程抽象出来,抽象过程的不同构建出来的产品对象也不一样,允许用户指定要创建的对象类型,但是不需要知道具体的构建过程。

  • 结构
    image

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tgk2rAUQ-1577697105841)(https://user-images.githubusercontent.com/35365788/71477175-87785c80-2823-11ea-8e47-e0191cda88ba.png)]

  • 优点

    • 产品和产品之间的创建过程解耦,客户端不需要了解创建的具体细节,相同创建过程创建不同的产品对象
    • 产品的创建过程可控,创建逻辑清晰
    • 具体的建造者之间的解耦,具体的建造者之间独立,对新增和修改开放,无需修改原有的类库
    • 指挥者针对抽象编程,拓展方便,符合’开闭原则‘
  • 缺点

    • 需要建造的过程有共同的相似点,差异大不适合
    • 建造过程不能过于复杂,否则会创建很多的具体的创建者
  • 建造者模式与抽象工厂模式的比较:

  • 与抽象工厂模式相比

建造者模式返回一个组装好的完整产品 ,而 抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。
在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。
如果将抽象工厂模式看成 汽车配件生产工厂 ,生产一个产品族的产品,那么建造者模式就是一个 汽车组装工厂 ,通过对部件的组装可以返回一辆完整的汽车。

举例一个简单的demo

产品

package com.example.design.pattern.book.builder;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Product {

    private String partA;
    private String partB;
    private String partC;
}
package com.example.design.pattern.book.builder;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Product {

    private String partA;
    private String partB;
    private String partC;
}

抽象建造者

public abstract class Builder {

    Product product = new Product();

    abstract void buildPertA();

    abstract void buildPertB();

    abstract void buildPertC();

    public Product getProduct() {
        return product;
    }
}

具体建造者A

public class BuilderA extends Builder {
    @Override
    void buildPertA() {
        product.setPartA("AAAA");
    }

    @Override
    void buildPertB() {
        product.setPartB("AAAA");
    }

    @Override
    void buildPertC() {
        product.setPartC("AAAA");
    }
}

具体建造者B


public class BuilderB extends Builder {
    @Override
    void buildPertA() {
        product.setPartA("BBBB");
    }

    @Override
    void buildPertB() {
        product.setPartB("BBBB");
    }

    @Override
    void buildPertC() {
        product.setPartC("BBBB");
    }
}

指导者


public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public Product build(){

        builder.buildPertA();
        builder.buildPertB();
        builder.buildPertC();
        return builder.getProduct();
    }

}


测试用例

@Test
    public void testBuilder(){
 
        BuilderA builderA = new BuilderA();
        Director director = new Director(builderA);

        Product product = director.build();

        System.out.println(product);
    }

举例一个简单的肯德基建造例子

参考文章
https://blog.csdn.net/qq_34337272/article/details/80540059

套餐产品(主食和饮料)

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Meal {

    private String food;
    private String drink;

}

套餐抽象建造者(抽象建造者)

public abstract class MealBuilder {

    Meal p = new Meal();

    abstract void buildFood();

    abstract void buildDrink();

    public Meal getProduct() {
        return p;
    }
}

套餐A(具体的建造者)

public class MealA extends MealBuilder {
    @Override
    void buildFood() {
        p.setFood("汉堡");
    }

    @Override
    void buildDrink() {

        p.setDrink("可乐");
    }
}

套餐B(具体建造者)


public class MealB extends MealBuilder {
    @Override
    void buildFood() {

        p.setFood("鸡腿");
    }

    @Override
    void buildDrink() {

        p.setDrink("雪碧");
    }
}

服务员(指导者)


@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Waiter {

    private MealBuilder mealBuilder;

    public Meal construct(){
        mealBuilder.buildDrink();
        mealBuilder.buildFood();
        return mealBuilder.getProduct();
    }
}

测试用例

    @Test
    public void testMeal() {

        //套餐A
        MealA mealA = new MealA();
        //服务员A
        Waiter director1 = new Waiter(mealA);
        //由套餐A组成的产品
        Meal product = director1.construct();
        System.out.println("套餐A的内容:" + product);


        //套餐B
        MealB mealB = new MealB();
        //服务员B
        Waiter director2 = new Waiter(mealB);
        //由套餐B组成的产品
        Meal product1 = director2.construct();
        System.out.println("套餐B的内容:" + product1);

    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值