建造者模式或生成器模式(Java)

一:建造者模式诞生的背景

1:背景

需要用程序代码实现房屋建造过程,已知房子House属性有ceiling(天花板)、wall(墙)、floor(地板),客户请你建造平房和公寓房子。

2:平常的思维

/**
 * 房屋的JavaBean类
 * @author Peter
 */
public class House {

	private String wall; //墙
	
	private String floor; //地板
	
	private String ceiling; //天花板

	public String getWall() {
		return wall;
	}

	public void setWall(String wall) {
		this.wall = wall;
	}

	public String getFloor() {
		return floor;
	}

	public void setFloor(String floor) {
		this.floor = floor;
	}

	public String getCeiling() {
		return ceiling;
	}

	public void setCeiling(String ceiling) {
		this.ceiling = ceiling;
	}
	
}
/**
 * 建造平房
 * @author Peter
 */
public class PingFangHouse {

	public void makeHouse(House house){
		System.out.println("巴拉巴拉一大堆平房"+house.getCeiling());
		System.out.println("巴拉巴拉一大堆平房"+house.getWall());
		System.out.println("巴拉巴拉一大堆平房"+house.getFloor());
	}
}
/**
 * 建造公寓
 * @author Peter
 */
public class GongYuHouse {

	public void makeHouse(House house){
		System.out.println("巴拉巴拉一大堆公寓"+house.getCeiling());
		System.out.println("巴拉巴拉一大堆公寓"+house.getWall());
		System.out.println("巴拉巴拉一大堆公寓"+house.getFloor());
	}
}
/**
 * 客户端
 * @author Peter
 */
public class MainClass {

	public static void main(String[] args) {
		House h1 = new House();
		h1.setCeiling("建造天花板");
		h1.setWall("建造墙");
		h1.setFloor("建造地板");
		
		PingFangHouse pingfangHouse = new PingFangHouse();
		pingfangHouse.makeHouse(h1);
		System.out.println("----------------------------");
		GongYuHouse gongyuHouse = new GongYuHouse();
		gongyuHouse.makeHouse(h1);
		
	}
}

但是我们发现平房的建造和公寓的建造基本流程是一样的:(1)先建造天花板;(2)建造墙;(3)建造地板;(4)看房子输出结果;只是中间的一些细节不一样,现实中公寓和平房的建造也是这样的。这样就存在如下问题:(1)建造每种房子的时候都会输出这几步,应该提炼出来,形成公共的处理过程;(2)在今后可能会有很多不同的房子需要建造,这就需要在处理过程不变的情况下,能方便的切换到不同的房子建造(即建造每种房子的时候,应该和具体的实现步骤分开,这样就能够复用处理过程,而且能很容易地切换不同房子的建造)。

二:建造者模式

解决上面的问题,使用建造者模式是一个合理的解决方案。

1:定义

Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种。其定义为:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

2:应用建造者模式解决问题的思路

细细分析上面的实现,构造每种房子的处理过程,就是构建的过程,每种房子建造的具体实现就相当于是不同的表现。因为不同的步骤实现,决定最终的表现也就不同。即上面的问题恰好是建造者模式要解决的问题。

要实现同样的构建过程可以创建不同的表现,那么很直观的就可以相到先把构建过程独立出来,在建造者模式中把它称为指导者,由它来指导装配过程,但是不负责每步的具体实现。当然指导者显然是不能满足所有的要求,还必须要有能具体实现每步的对象,在建造者模式中称这些实现对象为生成器。

这样一来,指导者就是可以重用的构建过程,而生成器是可以被切换的具体实现。前面的实现中,每种具体房子的建造就相当于是生成器。

3:建造者模式的结构和说明


Builder:生成器接口,定义创建一个Product对象所需的各个部件的操作;

ConcreteBuilder:具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让客户获取组装完成后的产品对象的方法。

Director:指导者,也被称为导向者,主要用来使用builder接口,以一个统一的过程来构建所需要的Product对象。

Product:产品,表示被生成器构建的复杂对象,包含多个部件。

4:生成器模式示例代码

/**
 * 生成器接口,定义创建一个Product对象所需的各个部件的操作
 * @author Peter
 */
public interface Builder {
	/**
	 * 示意方法,构建每个部件
	 */
	public void buildPart();
}
/**
 * 具体的生成器实现对象
 * @author Peter
 */
public class ConcreteBuilder implements Builder {
	/**
	 * 生成器最终构建的产品对象
	 */
	private Product resultProduct;
	
	/**
	 * 获取生成器最终构建的产品对象
	 * @return
	 */
	public Product getResultProduct() {
		return resultProduct;
	}

	public void buildPart() {
		//构建某个部件的功能处理
	}
}
/**
 * 指导者,指导使用生成器的接口来构建产品的对象
 * @author Peter
 */
public class Director {

	/**
	 * 持有当前需要使用的生成器对象
	 */
	private Builder builder;

	/**
	 * 构造方法传入生成器对象
	 * @param builder
	 */
	public Director(Builder builder) {
		this.builder = builder;
	}
	
	/**
	 * 示意方法,指导生成器构建最终的产品对象
	 */
	public void construct(){
		//通过使用生成器接口来构建最终的产品对象
		builder.buildPart();
	}
}
/**
 * 被构建的产品对象的接口
 * @author Peter
 */
public interface Product {

	//定义产品的操作
	
}

三:利用建造者模式实现房子建造

/**
 * 描述房屋的对象
 * @author Peter
 */
public class House {

	private String wall; //墙
	
	private String floor; //地板
	
	private String ceiling; //天花板

	public String getWall() {
		return wall;
	}

	public void setWall(String wall) {
		this.wall = wall;
	}

	public String getFloor() {
		return floor;
	}

	public void setFloor(String floor) {
		this.floor = floor;
	}

	public String getCeiling() {
		return ceiling;
	}

	public void setCeiling(String ceiling) {
		this.ceiling = ceiling;
	}
	
}
/**
 * 生成器接口,定义创建一个房子所需要的各个部件的操作
 * @author Peter
 *
 */
public interface HouseBuilder {

	public void makeCeiling(); //修天花板
	 
	public void makeWall(); //修墙
	
	public void makeFloor(); //修地板
	
	public House getHouse(); //得到房子
	
}
public class PingFangBuilder implements HouseBuilder {

	private House house = new House();

	public void makeCeiling() {
		house.setCeiling("平房----->天花板");
	}

	public void makeWall() {
		house.setWall("平房----->墙");
	}

	public void makeFloor() {
		house.setFloor("平房----->地板");
	}

	public House getHouse() {
		return house;
	}

}
public class GongYuBuilder implements HouseBuilder {

	private House house = new House();

	public void makeCeiling() {
		house.setCeiling("公寓----->天花板");
	}

	public void makeWall() {
		house.setWall("公寓----->墙");
	}

	public void makeFloor() {
		house.setFloor("公寓----->地板");
	}

	public House getHouse() {
		return house;
	}

}
/**
 * 房屋设计者
 * 
 * @author Peter
 */
public class HouseDirector {
	private HouseBuilder builder;

	public HouseDirector(HouseBuilder builder) {
		this.builder = builder;
	}

	// 组装房屋
	public void makeHouse() {
		builder.makeCeiling();
		builder.makeWall();
		builder.makeFloor();
	}
}
/**
 * 客户端
 * @author Peter
 *
 */
public class MainClass {

	public static void main(String[] args) {
		//平房
		//HouseBuilder builder = new PingFangBuilder();
		
		//公寓
		HouseBuilder builder = new GongYuBuilder();
		
		HouseDirector director = new HouseDirector(builder);
		director.makeHouse();
		House house = builder.getHouse();
		System.out.println(house.getCeiling());
		System.out.println(house.getWall());
		System.out.println(house.getFloor());
	}
}

四:建造者模式讲解

1:建造者模式功能

建造者模式主要的功能是构建复杂的产品,而且是细化的分步骤的构建产品,即生成器模式重在一步一步解决构造复杂对象的问题。更重要的是,这个构建过程是统一的,固定不变的,变化的部分放到生成器部分了,只要配置不同的生成器,那么同样的构建过程,就能构建出不同的产品。

更直白的说,生成器模式的重心在于分离构建算法和具体的构造实现,从而使得构建算法可以重用。具体的构造实现可以很方便的扩展和切换,从而可以灵活的组合来构造出不同的产品对象。

2:生成器模式的构成

生成器模式有两个很重要的部分:Builder接口和Director。

Builder:定义了如何构建各个部件,即每个部件的功能是如何实现,以及如何装配这些部件到产品中去;

Director:知道如何组合来构建产品,即Director负责整体的构建算法,而且通常是分步骤进行的;

3:生成器模式的使用

应用生成器模式的时候,可以让客户端创建Director,在它里面封装整体构建算法,然后让Director去调用Builder,让Builder去封装具体部件的构建功能,

4:生成器模式的调用顺序示意图


5:生成器模式的优点

(1)松散耦合(生成器模式可以用同一个构建算法构建出表现上完全不同的产品,实现产品构建和产品表现上的分离,生成器模式正是把产品构建的过程独立出来,使它和具体产品的变现松散耦合,从而使得构建算法可以复用,而具体产品变现也可以灵活地、方便地扩展和切换);

(2)可以很容易改变产品内部表示(在生成器模式中,由于Builder对象只是提供接口给Director使用,那么具体的部件创建和装配方式是被Builder接口隐藏了的,Director并不知道这些具体的实现细节。这样一来,要想改变产品的内部表示,只需要切换Builder的具体实现即可,不用管Director,因此变得很容易);

(3)更好地复用(生成器模式很好地实现了构建算法和具体产品实现的分离。这样一来,使得构建产品的算法可以复用。同样的道理,具体产品的实现也可以复用,同一个产品的实现,可以配合不同的构建算法使用)。

五:小思生成器模式

生成器模式的本质是分离整体构建算法和部件构造。

构建一个复杂的对象,本来就有构建的过程,以及构建过程中具体的实现。生成器模式就是用来分离这两个部分,从而使得程序结构更松散、扩展更容易、复用性更好,同时也会使得代码更清晰,意图更明确。

虽然在生成器模式的整体构建算法中,会一步一步引导Builder来构建对象,但这并不是说生成器模式主要就是用来实现分步构建对象的。生成器模式的重心还是在于分离整体构建算法和部件构造,而分步骤构建对象不过是整体构建算法的一个简单表现,或者说是一个附带产物。

如果创建的算法应该独立于该对象的组成部分以及他们的装配方式时推荐使用生成器模式;

如果同一个构建过程有着不同的表示时推荐使用生成器模式。






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值