设计模式--Builder生成器模式

Posted chongcheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式--Builder生成器模式相关的知识,希望对你有一定的参考价值。

如果文章中哪里有问题,希望各位大哥大姐指出,小弟十分感激。

正文

什么是生成器模式?

  生成器模式就是把生产对象的过程进一步抽取、细化、独立。以往我们生产对象,可能就是在一个小作坊里面从头做到尾。现在用了生成器模式,就等于把这些生产步骤细化分割了,进行了分散操作,一道工序完了就下一道工序,换一道工序就换个地方。举个例子,就像建房子,房子需要地基、主体、大门、房间、花园、地下室…….。按照以前的写法,就等于你雇了一个施工队,然后将整个房子的建造都交给他们,而且你还要把全部要求给他们说明白,不然他们要么全给你造了,要么全没造。用了生成器模式后,我们初始先生成最基础、最不可缺少的内容:地基和房子主体。并且将大门、房间、花园、地下室…….这些附加的东西都分别外包给不同的施工队(方法),你想加什么东西,就雇佣什么施工队(调方法),并告诉他们你要弄成什么样子。最后你在来个验收(生成最后的对象),那就行了。

为什么要用生成器模式?

  像前面说的,用生成器将对象的生成过程细分成不同部分,然后我们就可以更准确的去控制这个对象的生成。生成器模式很适合那个生成过程很复杂,且对象内部结构复杂,多变的类。例如前面提及的房子类,他的内部结构有很多,每个内部结构(属性)又有不同形式(值),就很适合这种模式去生成。再例如汽车,内部有车身、引擎、轮胎、座椅等等,每种又有不同的厂家、型号,更是复杂多变。

怎样使用生成器模式?

  首先我们需要一些最基本的东西:
    1:我们要生产的最终产品对象,如House。
    2:我们要有组成最终产品的各个部件,如Building、Door、Basement、Room、Garden。
    3:有一个建筑造公司,这个建造公司要有不同的施工队,如Builder
    4:(非必须)一个销售人员,直接给你推销最终产品,怎么造房子由销售人员去联系建筑公司。如Salesperson

 

技术图片

 

 技术图片

 

 代码很长,建议先跳过main方法看其他的,最后才看main方法。

/**
 *     生成器模式
 * */
public class BuilderHouse {
    public static void main(String[] args) {
        /** 我有1百万 */
        double myMoney = 1000000;
        /** 为了结婚去买套婚房 */
        House myHouse = null;
        /** 召唤一个售楼员 */
        Salesperson salesperson = new Salesperson();
        
        if(myMoney > 5000000) {
            /** 售楼员觉得我可能有5百万,打算我推荐这个别墅 */
            House bieShu = salesperson.bieShu();
            myHouse = bieShu;
        }else {
            /** 可实际上我只是个穷鬼,所以售楼员推了这套80万的商品房 */
            House shangPinLou = salesperson.shangPinLou();
            /** 好了,这套在预算内,剁手了 */
            myHouse = shangPinLou;
        }
        System.err.println(myHouse == null?"没房子找不到老婆":"有房子了,虽然小点,但起码老婆不嫌弃,美滋滋结婚了");
        System.err.println(myHouse == null?"":myHouse);
    }
}

/**
 *     房子--最终产品
 * */
class House{
    Building building;    // 建筑主体
    Door door;            // 大门
    List<Room> rooms;    // 房间
    Garden garden;        // 花园
    Basement basement;    // 地下室
    String description;    // 房子简述
    public House(Building building, Door door, List<Room> rooms, Garden garden, Basement basement,String description) {
        this.building = building;
        this.door = door;
        this.rooms = rooms;
        this.garden = garden;
        this.basement = basement;
        this.description = description;
    }
    public House() {}
    @Override
    public String toString() {
        return "House [building=" + building + ", door=" + door + ", rooms=" + rooms + ", garden=" + garden
                + ", basement=" + basement + ", description=" + description + "]";
    }
}
/**
 *     建筑--也就是房子主体--中间产品
 * */
class Building{
    double area;            // 面积
    int floor;                // 楼层
    String description;        // 大门描述
    public Building(double area, int floor, String description) {
        this.area = area;
        this.floor = floor;
        this.description = description;
    }
    public Building() { }
    @Override
    public String toString() {
        return "Building [area=" + area + ", floor=" + floor + ", description=" + description + "]";
    }
}
/**
 *     大门--中间产品
 * */
class Door{
    double width;            //
    double hight;            //
    String description;        // 大门描述
    public Door(double width, double hight, String description) {
        this.width = width;
        this.hight = hight;
        this.description = description;
    }
    public Door() { }
    @Override
    public String toString() {
        return "Door [width=" + width + ", hight=" + hight + ", description=" + description + "]";
    }
}
/**
 *     房间--中间产品
 * */
class Room{
    double area;            // 面积
    String description;        // 房间描述
    int windowNum;            // 窗户个数
    public Room(double area, String description, int windowNum) {
        this.area = area;
        this.description = description;
        this.windowNum = windowNum;
    }
    public Room() { }
    @Override
    public String toString() {
        return "Room [area=" + area + ", description=" + description + ", windowNum=" + windowNum + "]";
    }
}
/**
 *     花园--中间产品
 * */
class Garden{
    double area;            // 面积
    String description;        // 花园样子
    boolean hasSwimmingPool;// 是否要泳池
    public Garden() {}
    public Garden(double area, String description, boolean hasSwimmingPool) {
        this.area = area;
        this.description = description;
        this.hasSwimmingPool = hasSwimmingPool;
    }
    @Override
    public String toString() {
        return "Garden [area=" + area + ", description=" + description + ", hasSwimmingPool=" + hasSwimmingPool + "]";
    }
}
/**
 *     地下室--中间产品
 * */
class Basement{
    double area;            // 面积
    double hight;            // 地下室高
    String description;        // 地下室样子
    public Basement() { }
    public Basement(double area, double hight, String description) {
        this.area = area;
        this.hight = hight;
        this.description = description;
    }
    @Override
    public String toString() {
        return "Basement [area=" + area + ", hight=" + hight + ", description=" + description + "]";
    }
}
/**
 *     建造者,也就是建筑公司
 * */
class HouseBuilder{
    House house;    // 房子
    public HouseBuilder() {
        this.house = new House();
    }
    /**    
     *     建筑主体施工队,构建建筑主体
     * */
    public HouseBuilder buildBuilding(double area,int floor,String description) {
        Building building = new Building();
        building.area = area;
        building.floor = floor;
        building.description = description;
        this.house.building = building;
        return this;
    }
    /**    
     *     大门施工队,构建房子的大门
     * */
    public HouseBuilder buildDoor(double width,double hight,String description) {
        Door door = new Door();
        door.width = width;
        door.hight = hight;
        door.description = description;
        this.house.door = door;
        return this;
    }
    /**    
     *     房间施工队,构建房子的房间
     * */
    public HouseBuilder buildRooms(double area,int windowNum,String description,int roomNum) {
        Room room = null;
        List<Room> rooms = new ArrayList<Room>(roomNum);
        for (int i = 0; i < roomNum; i++) {
            room = new Room();
            room.area = area;
            room.windowNum = windowNum;
            room.description = description;
            rooms.add(room);
        }
        this.house.rooms = rooms;
        return this;
    }
    /**    
     *     花园施工队,构建房子的花园
     * */
    public HouseBuilder buildGarden(double area,boolean hasSwimmingPool,String description) {
        Garden garden = new Garden();
        garden.area = area;
        garden.hasSwimmingPool = hasSwimmingPool;
        garden.description = description;
        this.house.garden = garden;
        return this;
    }
    /**    
     *     花园施工队,构建房子的花园
     * */
    public HouseBuilder buildBasement(double area,double hight,String description) {
        Basement basement = new Basement();
        basement.area = area;
        basement.hight = hight;
        basement.description = description;
        this.house.basement = basement;
        return this;
    }
    /**
     *     验收,也就是生成最终产品
     * */
    public House createHouse() {
        return this.house;
    }
}
/**
 *     销售员,可以可有可无,如果不用的话,那他的工作就是交给业务程序来做
 * */
class Salesperson {
    /**
     *     原谅我的拼音,商品房
     * */
    public House shangPinLou() {
        HouseBuilder houseBuilder = new HouseBuilder();
        houseBuilder.buildBuilding(120, 1, "120平方的一层商品房,毛坯房")
        .buildDoor(1.5, 2, "豪华大铁门一扇")
        .buildRooms(20, 2, "3个20平方两窗户的大房间", 3);
        House house = houseBuilder.createHouse();
        house.description = "120平方的一层商品房,三室两厅,毛坯房";
        return house;
    }
    /**
     *     原谅我的拼音,商品房
     * */
    public House bieShu() {
        HouseBuilder houseBuilder = new HouseBuilder();
        houseBuilder.buildBuilding(400, 4, "400平方的5层大别墅,精装修")
        .buildDoor(5, 2, "别墅专用铁栅栏门")
        .buildRooms(60, 3, "5个60平带阳台豪华大房间", 5)
        .buildBasement(100, 3, "100平3米高地下室")
        .buildGarden(80, true, "80平带泳池大花园");
        House house = houseBuilder.createHouse();
        house.description = "400平方的5层大别墅,5室3厅,100平地下室,80平带泳池大花园,精装修,拎包入住";
        return house;
    }
}

 

以上是关于设计模式--Builder生成器模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 - Builder模式

每天一个设计模式-7 生成器模式(Builder)

设计模式--Builder生成器模式

.Net 设计模式进阶之路——生成器模式[Builder]

.Net 设计模式进阶之路——生成器模式[Builder]

生成器模式 (Builder Pattern)