建造者模式

为什么需要建造者模式

当我们要创建多个具体实例时,如果需要为每个场景创建一个具体的类,这样实现起来比较麻烦,所以我们需要一个角色,帮助我们针对不同的场景创建不同的实例,当一个实例的创建可以由不同步骤组成,不同的步骤创建不同的实例,固定的创建单个具体实例虽然可以,但是当实例的种类过多,或者需求变动过大,则会产生大量重复的代码,这个时候,需要一个角色扮演实例的创建指挥者,即明确不同的需求,具体的创建交给具体的创建类,这个模式就是创建者模式。

建造者模式是什么

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

核心思想

特定的接口,提供特定的操作,不同的类实现接口,表示不同类别的对象,指挥类明确了都有哪些相同类别但具体又有差距的对象可以被创建,具体的创建则由创建者完成。

具体案例

客户想要购买一批服装,要求这批服装是冬天和秋天两种类别,同时还要求分为男款和女款。

UML:

 

 

 

 

 

 

 

具体代码:

package com.dong.builder;

public interface ClothersModel {
	void color();
	void Season();
	void setseq(String seq);
}

package com.dong.builder;


public class ManModel implements ClothersModel {
	public String id;
	@Override
	public void color() {
		if(id.equalsIgnoreCase("aa"))
			System.out.println("黑色");
		else {
			System.out.println("黄色");
		}
	}
	@Override
	public void Season() {
		if(id.equalsIgnoreCase("aa"))
			System.out.println("春季");
		else {
			System.out.println("冬季");
		}
	}
	
	@Override
	public void setseq(String seq) {
		// TODO Auto-generated method stub
		this.id = seq;
	}
	public void showClother() {
		color();
		Season();
		System.out.println("----------------------->");
	}
}

package com.dong.builder;

public class WomenModel implements ClothersModel {

	public String id;
	@Override
	public void color() {
		if(id.equalsIgnoreCase("bb"))
			System.out.println("红色");
		else {
			System.out.println("蓝色");
		}
	}
	@Override
	public void Season() {
		if(id.equalsIgnoreCase("bb"))
			System.out.println("春季");
		else {
			System.out.println("冬季");
		}
	}
	@Override
	public void setseq(String seq) {
		// TODO Auto-generated method stub
		this.id = seq;
	}
	public void showClother() {
		color();
		Season();
		System.out.println("----------------------->");
	}
}

package com.dong.builder;

public abstract class ClotherBuilder {
	public abstract ClothersModel getClotherModel();
}

package com.dong.builder;

public class ManBuilder extends ClotherBuilder {
	private ManModel manClother = new ManModel();
	public void setid(String str) {
		this.manClother.id = str;
	}
	@Override
	public ClothersModel getClotherModel() {
		return this.manClother;
	}
}

package com.dong.builder;

public class WomenBuilder extends ClotherBuilder {

	private WomenModel womenClother = new WomenModel();
	public void setid(String str) {
		this.womenClother.id = str;
	}
	@Override
	public ClothersModel getClotherModel() {
		return this.womenClother;
	}
}

package com.dong.builder;

public class Director {
	private ManBuilder manBuilder =new ManBuilder();
	private WomenBuilder womenBuilder = new WomenBuilder();
	
	public ManModel getAManModel() {
		this.manBuilder.setid("aa");
		ManModel manmode = (ManModel) this.manBuilder.getClotherModel();
		manmode.showClother();
		return manmode;
	}
	public ManModel getBManModel() {
		this.manBuilder.setid("ab");
		ManModel manmode = (ManModel) this.manBuilder.getClotherModel();
		manmode.showClother();
		return manmode;
	}
	public WomenModel getAWomenModel() {
		this.womenBuilder.setid("bb");
		WomenModel women = (WomenModel) this.womenBuilder.getClotherModel();
		women.showClother();
		return women;
	}
	public WomenModel getBWomenModel() {
		this.womenBuilder.setid("ba");
		WomenModel women = (WomenModel) this.womenBuilder.getClotherModel();
		women.showClother();
		return women;
	}
}

package com.dong.builder;

public class client {
	public static void main(String[] args) {
		Director dir =new Director();
		for(int i =0 ;i<5;i++) {
			dir.getAManModel();
		}
		for(int i =0 ;i<5;i++) {
			dir.getBManModel();
		}
	}
}

优点:

具体创建由别的类实现,而客户端只需调用方法便可以创建不同的实例,具有良好的封装性。

各个模块之间独立,可以方便的扩展。

缺点

对于复杂的类,如果类的实例过多,则代码会有些冗余,但是相对于普通的创建方法,还是有一些优势的。

我的感悟:

如果需要创建的类是复杂的,具有多个特征,则建造者模式可以将类的构建过程进行拆分,一步一步的构建出我们需要的类,就用我们上面的例子说明,衣服分为男士和女士,冬季和春季两个维度的选择,这里比较简单,只有两个维度的组合,如果有多个维度的组合,则我们需要更复杂的表示和处理。男士和女士衣服的创建者只是实现了创建类过程中的一部分,而Director则进行类的更进一步构建,通过类的属性设置,来获取不同的实例对象。

建议自己想一个需求,然后使用创建者模式实现,这样会加深对创建者模式的理解。