设计模式之建造者模式

178 阅读3分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

建造者模式(Builder Pattern)通过多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

建造者模式通过将一个复杂对象的构建过程与它的表现分离,使得构建的过程可以自由扩展,降低部件与组装过程的耦合。

建造者模式(Builder Pattern)使用的场景

  • 需要初始化生成的对应成员变量过多,初始化特别复杂,需要的构造函数参数过多;
  • 同一个方法,不同的类对应调用,产生不同的结果。(主要是因为初始化的成员变量不同引起的。)
  • 产品类复杂,多个成员变量都可以构建类对应,并且产生的结果不同。

建造者的UML图

BuilderPattern.png

通过UML图,可以看出BuilderPattern中的角色分类。

  • AbstractBuilder(抽象建造者):抽象建造者定义了产品的组建过程,一般是需要子类进行实现的方法。
  • ConcreteBuilder(具体构建者):抽象构建者的实现,根据具体的需求进行实现。
  • Product:产品类
  • Director:统一组装构建过程

实例演示 我们知道手机由屏幕、按键、cpu、电池等组件组成,这里我们以构建一个手机的例子来讲解。

定义产品类

/**
 * 定义手机产品类
 * @author Iflytek_dsw
 *
 */
class PhoneProduct {
	private String screen;
	private String battery;
	private String hardware;
	protected PhoneProduct() {}
	public void setScreen(String screen) {
		this.screen = screen;
	}
	public void setBattery(String battery) {
		this.battery = battery;
	}
	public void setHardware(String hardware) {
		this.hardware = hardware;
	}
}

定义抽象Builder

/**
 * 定义抽象Builder类,定义构造Product的方法
 * @author Iflytek_dsw
 *
 */
public abstract class AbstractPhoneBuilder {
	public abstract void buildScreen(String screen);
	public abstract void buildBattery(String battery);
	public abstract void buildHardware(String hardware);
	public abstract PhoneProduct createPhone();
}

定义具体Builder类

/**
 * 创建一个Android手机产品
 * @author Iflytek_dsw
 *
 */
public class AndroidPhoneBuilder extends AbstractPhoneBuilder{

	private PhoneProduct product = new PhoneProduct();

	@Override
	public void buildScreen(String screen) {
		product.setScreen(screen);
	}

	@Override
	public void buildBattery(String battery) {
		product.setBattery(battery);
	}

	@Override
	public void buildHardware(String hardware) {
		product.setHardware(hardware);
	}

	@Override
	public PhoneProduct createPhone() {
		return product;
	}
}

定义Director类

public class Director {
	private AbstractPhoneBuilder builder;

	public Director(AbstractPhoneBuilder builder) {
		super();
		this.builder = builder;
	}
	
	public void concreatePhone(String screen,String battery,String hardware){
		builder.buildBattery(battery);
		builder.buildHardware(hardware);
		builder.buildScreen(screen);
	}
}

定义客户端

public class Client {
	public static void main(String args[]){
		AndroidPhoneBuilder androidPhoneBuilder = new AndroidPhoneBuilder();
		Director director = new Director(androidPhoneBuilder);
		director.concreatePhone("三星", "南孚", "Imax6");
		PhoneProduct product= androidPhoneBuilder.getPhone();
	}
}

通过上面的例子,Director类封装了构建复杂对象的过程,然后通过指定具体的Builder类生成具体的实例对象。通过Builder和Director类一起讲复杂对象的构建过程与它的表示进行风力,使得同样的过程可以创建不同的实例对象。

通过上面的例子,是不是感觉搞通过建造者模式去生成一个对象也是很复杂的一件事。所以在实际的使用中,一般都是Director类省略,形成一个精简版。针对上面的例子,我们来看看下面的精简版:

/**
 * 定义手机产品类
 * @author Iflytek_dsw
 *
 */
class PhoneProduct {
	private String screen;
	private String battery;
	private String hardware;
	protected PhoneProduct() {}
	public void setScreen(String screen) {
		this.screen = screen;
	}
	public void setBattery(String battery) {
		this.battery = battery;
	}
	public void setHardware(String hardware) {
		this.hardware = hardware;
	}
	
	/**
	 * 封装Builder内部类
	 * @author Iflytek_dsw
	 *
	 */
	public static class Builder{
		private PhoneProduct product = new PhoneProduct();
		
		public Builder setScreen(String screen){
			product.screen = screen;
			return this;
		}
		
		public Builder setBattery(String battery) {
			product.battery = battery;
			return this;
		}
		
		public Builder setHardware(String hardware) {
			product.hardware = hardware;
			return this;
		}
		
		public PhoneProduct buildProduct(){
			return product;
		}
	}
}

//客户端
public class Client {
	public static void main(String[]args){
		PhoneProduct.Builder builder = new PhoneProduct.Builder();
		builder.setBattery("南孚");
		builder.setHardware("Imax6");
		builder.setScreen("镁光");
		PhoneProduct product = builder.buildProduct();
	}
}

通过去除Director类,整个类的构建结构更加简洁了,代码的可读性也提高了很多。所以推荐大家使用这种方式进行。