设计模式--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; } }