注:示例来自《大话设计模式》
现有如下需求 用程序画一个小人 简单代码实现如下
package Test12;
public class Program {
public static void main(String[] args) {
System.out.println("画小人头部");
System.out.println("画小人身体");
System.out.println("画小人左手");
System.out.println("画小人右手");
System.out.println("画小人左腿");
System.out.println("画小人右腿");
}
}
如果现在要再画一个身体比较胖的小人呢 代码实现如下
package Test12;
public class Program {
public static void main(String[] args) {
System.out.println("画瘦小人头部");
System.out.println("画瘦小人身体");
System.out.println("画瘦小人左手");
System.out.println("画瘦小人右手");
System.out.println("画瘦小人左腿");
System.out.println("画瘦小人右腿");
System.out.println("画胖小人头部");
System.out.println("画胖小人身体");
System.out.println("画胖小人左手");
System.out.println("画胖小人右手");
System.out.println("画胖小人左腿");
System.out.println("画胖小人右腿");
}
}
上面的代码全写在一个类中了 如果需要在别的地方用画小人的程序怎么办
下面进行分离 代码如下
画瘦小人类
package Test12;
public class PersonThinBuilder {
public void Build() {
System.out.println("画瘦小人头部");
System.out.println("画瘦小人身体");
System.out.println("画瘦小人左手");
System.out.println("画瘦小人右手");
System.out.println("画瘦小人左腿");
System.out.println("画瘦小人右腿");
}
}
画胖小人类
package Test12;
public class PersonFatBuilder {
public void Build() {
System.out.println("画胖小人头部");
System.out.println("画胖小人身体");
System.out.println("画胖小人左手");
System.out.println("画胖小人右手");
System.out.println("画胖小人左腿");
System.out.println("画胖小人右腿");
}
}
客户端代码
package Test12;
public class Program {
public static void main(String[] args) {
PersonThinBuilder ptb = new PersonThinBuilder();
ptb.Build();
PersonFatBuilder pfb = new PersonFatBuilder();
pfb.Build();
}
}
上面的代码达到了可以复用这两个画小人程序的目的 但是还有个问题 比如现在需要加一个高个的小人 有可能会因为编程不在意 少写一个方法 造成缺胳膊少腿的情况 最好的办法是规定 凡是建造小人 都必须要有头和身体 以及两手两脚 下面我们使用建造者模式进行实现 代码如下
建造人抽象类
package Test12;
public abstract class PersonBuilder {
public abstract void BuildHead();
public abstract void BuildBody();
public abstract void BuildArmLeft();
public abstract void BuildArmRight();
public abstract void BuildLegLeft();
public abstract void BuildLegRight();
}
瘦人实现类
package Test12;
public class PersonThinBuilder extends PersonBuilder {
@Override
public void BuildHead() {
System.out.println("画瘦小人头部");
}
@Override
public void BuildBody() {
System.out.println("画瘦小人身体");
}
@Override
public void BuildArmLeft() {
System.out.println("画瘦小人左手");
}
@Override
public void BuildArmRight() {
System.out.println("画瘦小人右手");
}
@Override
public void BuildLegLeft() {
System.out.println("画瘦小人左腿");
}
@Override
public void BuildLegRight() {
System.out.println("画瘦小人右腿");
}
}
胖人实现类
package Test12;
public class PersonFatBuilder extends PersonBuilder {
@Override
public void BuildHead() {
System.out.println("画胖小人头部");
}
@Override
public void BuildBody() {
System.out.println("画胖小人身体");
}
@Override
public void BuildArmLeft() {
System.out.println("画胖小人左手");
}
@Override
public void BuildArmRight() {
System.out.println("画胖小人右手");
}
@Override
public void BuildLegLeft() {
System.out.println("画胖小人左腿");
}
@Override
public void BuildLegRight() {
System.out.println("画胖小人右腿");
}
}
指挥者类 用它来控制建造过程 也用它来隔离用户与建造过程的关联
package Test12;
public class PersonDirector {
private PersonBuilder pb;
public PersonDirector(PersonBuilder pb)
{
this.pb = pb;
}
public void CreatePerson()
{
pb.BuildHead();
pb.BuildBody();
pb.BuildArmLeft();
pb.BuildArmRight();
pb.BuildLegLeft();
pb.BuildLegRight();
}
}
客户端代码
package Test12;
public class Program {
public static void main(String[] args) {
PersonThinBuilder ptb = new PersonThinBuilder();
PersonDirector pdThin = new PersonDirector(ptb);
pdThin.CreatePerson();
PersonFatBuilder pfb = new PersonFatBuilder();
PersonDirector pdFat = new PersonDirector(pfb);
pdFat.CreatePerson();
}
}
建造者模式 将一个复杂对象的构建与它的表示分离 使得同样的构建过程可以创建不同的表示
如果我们用了建造者模式 那么用户就只需指定需要建造的类型就可以得到它们 而具体建造的过程和细节就不需知道了
建造者模式主要是用于创建一些复杂的对象 这些对象内部构建间的建造顺序通常是稳定的 但对象内部的构建通常面临着复杂的变化
建造者模式的好处就是使得建造代码与表示代码分离 由于建造者隐藏了该产品是如何组装的 所以若需要改变一个产品的内部表示 只需要再定义一个具体的建造者就可以了
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式