JAVA23种设计模式之生成器模式

  1. 生成器模式
    生成器模式是一种对象的创建模式,可以将一个复杂产品的内部表象和产品的生产过程分隔开来,(构建与表示分离)。使得同样的构建过程可以创建不同的表示。
    简单的来说,就是讲一个复杂的对象拆分成一个一个小的对象,然后通过排列组合的方式生成不同的复杂对象。举个栗子:例如快餐店的套餐,会有个定价,比如说总价是20元套餐。可以有两素菜一个荤菜。素菜包括清炒白菜、土豆丝、麻婆豆腐等等,荤菜包括口水鸡,啤酒鸭,小炒肉等等。这样只要是两素菜一荤菜组合,就能形成一个个套餐。这其实就类似于生成器模式。这里的复杂产品是套餐,而生产过程则是一个一个的小菜。
  2. 生成器模式示意图
    生成器模式示意图
    3.生成器模式所含角色
  • 产品角色: 产品是要构建的复杂对象。
  • 抽象建造者角色: 为创建产品角色对象的各个部分指定抽象接口,一般至少包含有两个方法,一个是建造产品,一个是返回产品。
  • 具体建造者角色: 实现抽象建造者角色。并且根据不同的情形对于产品创建给出具体的方法。并且能够在创建完成后返回产品实例。
  • 导演角色: 构造一个能够使用抽象建造者的对象。该角色不涉及具体的产品信息。主要负责和客户端打交道。
  1. 示例代码:
    场景:某旅游网站推出了3日游和4日游的业务。需要设计一个度假计划生成的项目。
    产品角色:
public class Vacation {
    private Date date;
    private ArrayList<VacationDay> vacationDays=null;
    private int days = 0;
    private VacationDay vacationDay;
    public Vacation(String dt) {
        vacationDays = new ArrayList<VacationDay>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = sdf.parse(dt);
            vacationDay = new VacationDay(date);
            vacationDays.add(vacationDay);
            days++;
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public void setDate(String dt){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = sdf.parse(dt);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public Date getDate() {
        return date;
    }
    /**
     * 获取下一天
     * @param n
     * @return
     */
   private Date nextDate(int n){
       Calendar cal = Calendar.getInstance();
       cal.setTime(date);
       cal.add(Calendar.DATE, n);
       return cal.getTime();
   }
    /**
     * 假期中的下一天
     */
   public void addDay(){
        vacationDay = new VacationDay(nextDate(days));
        vacationDays.add(vacationDay);
        days++;
   }
    public boolean setVacationDay(int i){
        if ((i > 0) && (i < vacationDays.size())) {
            vacationDay = vacationDays.get(i);
            return true;
        }
        vacationDay = null;
        return false;
    }
    public void setHotel(String hotel){
        vacationDay.setHotel(hotel);
    }
    public void setEvent(String event){
        vacationDay.addEvents(event);
    }
    public void setTicket(String ticket){
        vacationDay.addtickets(ticket);
    }
    public void showInfo() {
        for (int i = 0, len = vacationDays.size(); i < len; i++) {
            System.out.println("** " + (i + 1) + " day**");
            System.out.println(vacationDays.get(i).toString());

        }
    }
}

假期中的每天用一个具体类标示:

public class VacationDay {
    private Date date;
    private String hotel;
    private ArrayList<String> events;
    private ArrayList<String> tickets;
    public VacationDay(Date dt) {
        date = dt;
        events = new ArrayList<String>();
        tickets = new ArrayList<String>();
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
    public String getHotel() {
        return hotel;
    }
    public void setHotel(String hotel) {
        this.hotel = hotel;
    }
    public void addEvents(String event){
        events.add(event);
    }
    public void addtickets(String ticket){
        tickets.add(ticket);
    }
    @Override
    public String toString() {
        return date + "VacationDay>>>>" +
                "date=" + date +
                ", hotel='" + hotel + '\'' +
                ", events=" + events +
                ", tickets=" + tickets ;
    }
}

抽象建造者角色:

public interface Builder {
    void buildvacation();
    void buildDay(int i);
    void addHotel(String hotel);
    void addTicket(String ticket);
    void addEvent(String event);
    Vacation getVacation();
}

具体建造者角色:

public class FourDaysBuilder implements Builder {
    private Vacation vacation;
    public FourDaysBuilder(String date) {
        vacation = new Vacation(date);
    }
    /**
     * 创建完整的假期的方法
     */
    @Override
    public void buildvacation() {
        addTicket("机票");
        addHotel("如家");
        addEvent("住宿");
        addEvent("晚餐");
        vacation.addDay();;
        addTicket("公园门票");
        addEvent("游城市公园");
        addTicket("水族馆门票");
        addEvent("游水族馆");
        addHotel("希尔顿酒店");
        vacation.addDay();
        addEvent("中央公园");
        addTicket("观光bus");
        addHotel("万达酒店");
        vacation.addDay();
        addTicket("机票");
        addEvent("回家");
    }
    @Override
    public void buildDay(int i) {
        vacation.setVacationDay(i);
    }
    @Override
    public void addHotel(String hotel) {
        vacation.setHotel(hotel);
    }
    @Override
    public void addTicket(String ticket) {
        vacation.setTicket(ticket);
    }
    @Override
    public void addEvent(String event) {
        vacation.setEvent(event);
    }
    @Override
    public Vacation getVacation() {
        return vacation;
    }
}

导演角色:

public class Director {
    private Builder builder;
    public Director(Builder builder) {
        this.builder = builder;
    }
    public void setBuilder(Builder builder) {
        this.builder = builder;
    }
    public void construct(){
        builder.buildvacation();
        builder.getVacation().showInfo();
    }
}

测试主函数:

public class Main {
    public static void main(String[] args) {
        Director director = new Director(new FourDaysBuilder("2019-01-30"));
        director.construct();

    }
}
  1. 生成器模式的总结:
    从上面的实例代码看出,生成器模式的有点是建造者是独立的,便于扩展。但是缺点也很明显如果内部系统较为复杂就会有很多的建造类。生成器模式的使用是系统中的子系统具有相互的联系。
发布了62 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/system_obj/article/details/88213310