生成器模式

生成器模式

生成器模式(Builder Pattern)又叫创建者模式、建造者模式等等,使用生成器封装一个产品的构造过程,并允许按步骤构造。

假设我们有一下场景:

现在有一个主题公园,请你为他们制定一套度假计划:客人可以选择旅馆以及各种门票、餐厅订位,甚至也可以选择登记参加特殊的活动,首先你需要建立了像下面这样的结构:

在这里插入图片描述

从上面可以看出每个假期都有很几天,其实主要专注一天的设计就足够了,其他的都是重复的工作。

你需要一个有弹性的设计

每个客人的度假计划都不太一样,例如天数、活动类型。比如,当地居民可以不需要旅馆,但是想要用餐并参加特殊活动。而其他的客人可能是从外地飞过来的,所以需要旅馆、用餐和门票。

所以你需要一个有弹性的数据结构,代表客人的规划,以及所有的变化;你也需要遵循一系列潜在的复杂顺序,创建这样的规划。你要如何才能够提供一种方式 来创建这个复杂的结构,而不会和创建它的步骤混在一起呢?

使用生成器模式

我们将旅客规划的过程,封装到一个对象中(让我们称此对象为生成器),然后客户调用生产器为它创建旅游规划,UML如图所示:

在这里插入图片描述

客户端按照生成器生成所有的对象,然后可以通过调用planner.getPlannerDes()获取相应的计划描述,简易代码如下所示:

//建造者抽象类
public interface  AbstractBuilder{
    void buildDay(int day);

    void addHotel(boolean hotel);

    void addReservation(boolean reservation);

    void addSpecialEvent(List<String> specialEvent);

    void addTickets(int tickets);

    Vacation getVacation();
}

//假期建造者实现类
public class VacationBuilder implements AbstractBuilder{

    Vacation vacation;

    public VacationBuilder() {
        this.vacation = new Vacation();
    }


    @Override
    public void buildDay(int day) {
        vacation.setBuildDay(day);
    }

    @Override
    public void addHotel(boolean hotel) {
        vacation.setHotel(hotel);
    }

    @Override
    public void addReservation(boolean reservation) {
        vacation.setReservation(reservation);
    }

    @Override
    public void addSpecialEvent(List<String> specialEvent) {
        vacation.setSpecialEvents(specialEvent);
    }

    @Override
    public void addTickets(int tickets) {
        vacation.setTickets(tickets);
    }

    @Override
    public Vacation getVacation() {
        return vacation;
    }
}

//一天的安排Vacation类
public class Vacation {

    private Integer buildDay;

    private boolean hotel;

    private Integer tickets;

    private Boolean reservation;

    private List<String> specialEvents;

 	//getter setter省略
}

//整个计划类
public class Planner {

    List<Vacation> vacationList;
    public Planner() {
        this.vacationList = new ArrayList<>();
    }

    public String getPlannerDes(){
        StringBuilder sb = new StringBuilder();
        sb.append("尊敬的顾客,你的行程安排如下:\n");
        for (int i=0;i<vacationList.size();i++){
            Vacation vacation = vacationList.get(i);
            sb.append("第")
                    .append(vacation.getBuildDay())
                    .append("天行程:")
                    .append("是否入住酒店:")
                    .append(vacation.isHotel())
                    .append(" 是否需要就餐:")
                    .append(vacation.getReservation())
                    .append(" 特殊活动:");
            if (vacation.getSpecialEvents()!=null){
                sb.append(vacation.getSpecialEvents().toString());
            }else{
                sb.append("无");
            }
             sb.append(" 购买门票数:").append(vacation.getTickets()).append("\n");
        }
        return sb.toString();
    }

}

//client类及其测试
public class Cilent {

    public Planner constructVavation(int vacationDay,HashMap<String,Boolean> trueOrNot,List<List<String>> specialEvents,List<Integer>tickets){
        Planner planner = new Planner();

        for(int i=0;i<vacationDay;i++){
            int index = i+1;
            VacationBuilder vacationBuilder = new VacationBuilder();
            vacationBuilder.buildDay(index);
            vacationBuilder.addHotel(trueOrNot.get("hotel"+index));
            vacationBuilder.addReservation(trueOrNot.get("reservation"+index));
            vacationBuilder.addSpecialEvent(specialEvents.get(i));
            vacationBuilder.addTickets(tickets.get(i));
            planner.vacationList.add(vacationBuilder.getVacation());
        }

        return planner;
    }

    public static void main(String[] args) {
        int  vacationDay = 3;
        HashMap<String,Boolean> trueOrNot = new HashMap<>();
        trueOrNot.put("hotel1",true);
        trueOrNot.put("hotel2",true);
        trueOrNot.put("hotel3",false);

        trueOrNot.put("reservation1",false);
        trueOrNot.put("reservation2",false);
        trueOrNot.put("reservation3",true);
        List<Integer> tickets = new ArrayList<>();

        tickets.add(10);
        tickets.add(20);
        tickets.add(30);


        List<List<String>> specialEvents = new ArrayList<>();
        specialEvents.add(null);
        specialEvents.add(null);

        List<String> events = new ArrayList<>();
        events.add("浴足");
        events.add("看电影");
        specialEvents.add(events);

        Planner planner = new Cilent().constructVavation(vacationDay, trueOrNot, specialEvents, tickets);
        System.out.println(planner.getPlannerDes());
    }
}

//执行结果
//尊敬的顾客,你的行程安排如下:
//第1天行程:是否入住酒店:true 是否需要就餐:false 特殊活动:无 购买门票数:10
//第2天行程:是否入住酒店:true 是否需要就餐:false 特殊活动:无 购买门票数:20
//第3天行程:是否入住酒店:false 是否需要就餐:true 特殊活动:[浴足, 看电影] 购买门票数:30

这样客户端就可以通过直接调用constructVavation来创建对象而不需要关系过程。

优缺点及用途

优点
  • 将一个复杂的对象的创建封装起来。
  • 允许对象通过多个步骤来创建,并且可以改变过程(这与工厂模式只有一个步骤是不同的)。
  • 向客户隐藏产品的内部表现。
  • 产品的实现可以被替换,因为客户只看到一个抽象的接口。
缺点

与工厂模式相比,采用生成器创建对象的客户需要了解更多的知识。

用途

经常被用在创建组合结构。

注:生产器本人也没有琢磨地很明白,欢迎大家的指导。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值