建造者模式
为什么需要建造者模式
当我们要创建多个具体实例时,如果需要为每个场景创建一个具体的类,这样实现起来比较麻烦,所以我们需要一个角色,帮助我们针对不同的场景创建不同的实例,当一个实例的创建可以由不同步骤组成,不同的步骤创建不同的实例,固定的创建单个具体实例虽然可以,但是当实例的种类过多,或者需求变动过大,则会产生大量重复的代码,这个时候,需要一个角色扮演实例的创建指挥者,即明确不同的需求,具体的创建交给具体的创建类,这个模式就是创建者模式。
建造者模式是什么
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
核心思想
特定的接口,提供特定的操作,不同的类实现接口,表示不同类别的对象,指挥类明确了都有哪些相同类别但具体又有差距的对象可以被创建,具体的创建则由创建者完成。
具体案例
客户想要购买一批服装,要求这批服装是冬天和秋天两种类别,同时还要求分为男款和女款。
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则进行类的更进一步构建,通过类的属性设置,来获取不同的实例对象。
建议自己想一个需求,然后使用创建者模式实现,这样会加深对创建者模式的理解。