建造者模式,有4个角色:
- 导演角色(Director)
- 抽象创建者角色 (Builder)
- 具体创建者角色(ConcreteBuilder)
-
需要创建的产品(Product)
类图如下:
创建者模式类图.png
举例代码如下:
假设客户(Client)现在要造一个房子(House),客户不会做,客户就找到包工头(Director),把需求告诉他,但是做房子很麻烦,包工头也干不完,于是请来了施工队(ConcreteBuilder),在做房子这个行业里,施工队都是按一定的标准做的(Builder).
首先我们要先有一个房子的实体类
package com.byedbl.builder;
/*
* A house as a concrete product we got finally
*/
public class House {
int roomNumber;
int doorNumber;
public House() {
roomNumber = 0;
doorNumber = 0;
}
public int getRoomNumber() {
return roomNumber;
}
public int getDoorNumber() {
return doorNumber;
}
}
接着要有个包工头(Director),包工头知道怎么指挥施工队(Builder)
package com.byedbl.builder;
/*
* This class is a Director
*/
public class HouseDirector {
public void CreateHouse(HouseBuilder concreteBuilder) {
concreteBuilder.BuildRoom(1);
concreteBuilder.BuildRoom(2);
concreteBuilder.BuildDoor(1, 2);
//return builder.getHouse();
}
}
接着要请个有一定标准的施工队.没标准建出来的就比较恐怖了.
先立标准
package com.byedbl.builder;
/*
* An abstract Builder
*/
public abstract class HouseBuilder {
public abstract void BuildRoom(int roomNo);
public abstract void BuildDoor(int room1, int room2);
public abstract House getHouse();
}
在找个会这个标准的施工队
package com.byedbl.builder;
public class ConcreteHouseBuilderA extends HouseBuilder{
private House house;
public ConcreteHouseBuilderA() {
house = new House();
}
public void BuildRoom(int roomNo) {
//you can create a new Room added to a House
house.roomNumber++;
}
public void BuildDoor(int room1, int room2) {
// you can create a new door assotiated with 2 room
// and added this door into a house
house.doorNumber++;
}
public House getHouse() {
return house;
}
}
整个流程下来,客户创建房子是这样子的.
package com.byedbl.builder;
/**
* 建造者角色:
* <ul>
* <li>导演角色(Director)
* <li>创建者角色
* <li>具体创建者角色
* <li>产品,产品可能也有一个抽象类
* </ul>
* <pre>
* 建造者模式适合场景:
* 1. 产品内部有复杂的结构
* 2. 产品对象的属性相互依赖,比如邮件,有前后依赖关系,缺一不可,这种可以在 Director 角色里规定必要的流程
* ConcreteBuilder 负责具体的创建工作
* 3. 换一个 ConcreteBuilder 就换了一种款式的产品.很方便
* </pre>
* <p> 与工厂模式的区别:
* 两者都是创建产品,建造者用意是得到宏观的层面得到一个最终的产品,而工厂模式可能是产品的一个零件
**/
public class TestClient {
public TestClient() {
}
public static void main(String[] args) {
House myHouse ;
ConcreteHouseBuilderA myHouseBuilder = new ConcreteHouseBuilderA();
HouseDirector myHouseDirector = new HouseDirector();
myHouseDirector.CreateHouse(myHouseBuilder);
myHouse = myHouseBuilder.getHouse();
System.out.println("My house has room :" + myHouse.getRoomNumber());
System.out.println("My house has door :" + myHouse.getDoorNumber());
}
}
虽然客户不会创建房子,但是听说包工头(Director)专门干这事,于是我们客户就找个包工头new HouseDirector()
,包工头就向外喊,谁谁谁会造这样子的房子(立了个标准,Builder),这时ConcreteHouseBuilderA
就说我会,然后房子就这样造出来了,其实包工头就是动动嘴而已,真正干活的还是ConcreteHouseBuilderA
构建者有什么用呢?
- 在创建比较复杂对象的时候很有用,
- 换一种
ConcreteHouseBuilder
就是不同的产品,但是因为有Director的标准流程在那,产品也不会走型. - 客户端无需知道具体的创建过程.
- 通过建造者模式构造一个类,达到一个链式创建的效果
public class NutritionFacts {
//定义一堆属性
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
//定义一个静态类Builder
public static class Builder{
// 定义一堆和上面一样的属性,并加上默认值
private final int servingSize;
private final int servings;
private int calories=0;
private int fat=0;
private int carbohydrate=0;
private int sodium=0;
public Builder( int servingSize, int servings){
this.servingSize=servingSize;
this.servings=servings;
}
public Builder calories( int val){
calories=val;
//返回Builder
return this;
}
public Builder fat( int val){
fat=val;
return this;
}
public Builder carbohydrate( int val){
carbohydrate=val;
return this;
}
public Builder sodium( int val){
sodium=val;
return this;
}
//提供build方法,调用外围类的构造器创建最终的类
public NutritionFacts build(){
return new NutritionFacts( this);
}
}
private NutritionFacts(Builder builder){
servingSize=builder.servingSize;
servings=builder.servings;
calories=builder.calories;
fat=builder.fat;
sodium=builder.sodium;
carbohydrate=builder.carbohydrate;
}
public static void main(String[] args) {
NutritionFacts nu= new NutritionFacts.Builder(240, 8).calories(100).sodium(35).build();
System.out.println(nu.calories);
System.out.println(nu.servingSize);
}
}
网友评论