建造者模式
创建一个产品时,有时产品有不同的组成成分,在其组成成分没创建完成之前,改产品是不可使用的。使用建造者模式,通过创建所有产品内部零件,组装完成后返回给用户。
例子:
举例设计LOL角色,角色包含皮肤、技能、属性、性别
Java实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
class Actor{
private String skin;
private String skill;
private String attribute;
private String gender;
public String getSkin() { return skin; }
public void setSkin(String skin) { this.skin = skin; }
public String getSkill() { return skill; }
public void setSkill(String skill) { this.skill = skill; }
public String getAttribute() { return attribute; }
public void setAttribute(String attribute) { this.attribute = attribute; }
public String getGender() { return gender; }
public void setGender(String gender) { this.gender = gender; }
@Override public String toString() { return "Actor{" + "skin='" + skin + '\'' + ", skill='" + skill + '\'' + ", attribute='" + attribute + '\'' + ", gender='" + gender + '\'' + '}'; } } abstract class AbstractActorBuilder{ protected Actor actor = new Actor();
public abstract void buildSkin();
public abstract void buildSkill();
public abstract void buildAttribute();
public abstract void buildGender();
public Actor resultActor(){ return actor; }
}
class GarenActorBuilder extends AbstractActorBuilder{ @Override public void buildSkin() { actor.setSkin("盖伦皮肤"); }
@Override public void buildSkill() { actor.setSkill("盖伦技能"); }
@Override public void buildAttribute() { actor.setAttribute("盖伦属性"); }
@Override public void buildGender() { actor.setGender("男"); } }
class XinZhaoActorBuilder extends AbstractActorBuilder{
@Override public void buildSkin() { actor.setSkin("赵信皮肤"); }
@Override public void buildSkill() { actor.setSkill("赵信技能"); }
@Override public void buildAttribute() { actor.setAttribute("赵信属性"); }
@Override public void buildGender() { actor.setGender("男"); } }
class AsheActorBuilder extends AbstractActorBuilder{ @Override public void buildSkin() { actor.setSkin("艾希皮肤"); }
@Override public void buildSkill() { actor.setSkill("艾希技能"); }
@Override public void buildAttribute() { actor.setAttribute("艾希属性"); }
@Override public void buildGender() { actor.setGender("女"); } }
class BuilderDirector{
public Actor constructActor(AbstractActorBuilder actorBuilder){ actorBuilder.buildSkin(); actorBuilder.buildSkill(); actorBuilder.buildAttribute(); actorBuilder.buildGender(); return actorBuilder.resultActor(); } }
public class Main { public static void main(String[] args) { Actor asheActor = new BuilderDirector().constructActor(new AsheActorBuilder()); System.out.println(asheActor); Actor xinZhaoActor = new BuilderDirector().constructActor(new XinZhaoActorBuilder()); System.out.println(xinZhaoActor); Actor garenActor = new BuilderDirector().constructActor(new GarenActorBuilder()); System.out.println(garenActor);
} }
|
在创建角色的时候,用户直接使用建造组装者创建创建相关角色,传入相关角色的创建者即可。在实际使用中,在创建各个组件的时候,应该是有规则的,通过不同的规则建造不同的角色。在后续如果新增了相关角色,可以新建一个角色建造者即可,无需修改其他相关代码。改处缺点在于,如果角色新增了其他相关组件,则修改较大。
建造者总结
建造者核心在于一步步构建一个包含多个组件的完整对象,与工厂模式不同在于通常建造者创建的对象相对工厂模式比较复杂,通常工厂模式创建的是单一或者相对不是很复杂的对象。如果将工厂模式看出汽车零件生产厂,建造者模式可以看出汽车装配厂。
建造者优点:
- 用户不需要知道建造细节,将产品本身和产品创建进行解耦,使相同的创建过程可以创建不同的产品。
- 扩展方便,符合”开闭原则”
- 细化了产品创建,使创建过程清晰明了
建造者缺点:
- 如果产品过多,会导致建造者过多,系统过于臃肿。
- 如果产品组件过于复杂而且多变,会导致产品创建过程过于复杂。
建造者使用范围:
- 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
- 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
- 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。