建造者模式(Builder Pattern)是使用多个简单的对象一步一步(顺序构建)构建成一个复杂的对象, 这种类型的设计模式属于创建型模式,他提供了一种创建对象的最佳方式。
一个Builder类会一步一步构建成为最终的对象,并且Builder是独立于其他对象的。
介绍
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,
这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
应用实例:
1、JAVA 中的 StringBuilder .append()
2、JDk中的 DocumentBuilder(org.w3c.dom)
优点:
1、建造者独立,易扩展。
2、便于控制细节风险。
缺点:
1、产品必须有共同点,范围有限制。
2、如内部变化复杂,会有很多的建造类。
使用场景:
1、需要生成的对象具有复杂的内部结构。
2、需要生成的对象内部属性本身相互依赖。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
其中:
- Builder为创建一个Product对象的各个部件指定抽象接口。
- ConcreteBuilder实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,提供一个检索产品的接口。
- Director构造一个使用Builder接口的对象。
- Product表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成组件的类,包括将这些组件装配成最终产品的接口。
适用性
Builder 模式适用于:
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构造过程必须允许被构造的对象有不同的表示时。
public class Main {
public static void main(String[] args) {
Director director = new Director();
Builder builder1 = new Builder1();
director.Construct(builder1);
Product product1 = builder1.getResult();
product1.show();
Builder builder2 = new Builder2();
director.Construct(builder2);
Product product2 = builder2.getResult();
product2.show();
}
}
abstract class Builder {
public abstract void BuildPart();
public abstract Product getResult();
}
class Builder1 extends Builder {
Product product = new Product();
@Override
public void BuildPart() {
product.Add("A");
product.Add("B");
product.Add("C");
product.Add("D");
product.Add("E");
product.Add("F");
}
@Override
public Product getResult() {
return product;
}
}
class Builder2 extends Builder {
Product product = new Product();
@Override
public void BuildPart() {
product.Add("A");
product.Add("B");
product.Add("C");
}
@Override
public Product getResult() {
return product;
}
}
class Product {
List<String> parts = new ArrayList<String>();
public void Add(String part) {
parts.add(part);
}
public void show() {
System.out.print("产品的组成:");
for (String s : parts)
System.out.print(s + " ");
System.out.print("\n");
}
}
实例二:
public class Actor {
private String type="a"; //角色类型
private String sex="男"; //性别
private String face="方形"; //脸型
private String costume="beauty"; //服装
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getCostume() {
return costume;
}
public void setCostume(String costume) {
this.costume = costume;
}
@Override
public String toString() {
return "Actor{" +
"type='" + type + '\'' +
", sex='" + sex + '\'' +
", face='" + face + '\'' +
", costume='" + costume + '\'' +
'}';
}
}
public abstract class ActorBuilder {
protected Actor actor = new Actor();
public abstract void buildType();
public abstract void buildSex();
public abstract void buildFace();
public abstract void buildCostume();
//工厂方法,返回一个完整的游戏角色对象
public Actor createActor() {
return actor;
}
}
public class ActorController {
//逐步构建复杂产品对象
public Actor construct(ActorBuilder actorBuilder) {
Actor actor;
actorBuilder.buildType();
actorBuilder.buildSex();
actorBuilder.buildFace();
actorBuilder.buildCostume();
actor = actorBuilder.createActor();
return actor;
}
}
public class AngelBuilder extends ActorBuilder {
@Override
public void buildType() {
actor.setType("天使");
}
@Override
public void buildSex() {
actor.setSex("女");
}
@Override
public void buildFace() {
actor.setFace("漂亮");
}
@Override
public void buildCostume() {
actor.setCostume("裙子");
}
}
public class ClientTest {
/**
* 下面是一个使用了建造者设计模式的简单示例程序,其概述为 : 无论是何种游戏角色,都需要逐步创建其组成部分,再将各组成部分配装成一个完整的游戏角色
*/
public static void main(String[] args) {
ActorController actorController = new ActorController();
ActorBuilder zero = new HeroBuilder();
Actor actor_zero = actorController.construct(zero);
System.out.println(actor_zero);
System.out.println("------------------------------");
ActorBuilder angel = new AngelBuilder();
Actor actor_angel = actorController.construct(angel);
System.out.println(actor_angel);
}
}
public class HeroBuilder extends ActorBuilder {
@Override
public void buildType() {
actor.setType("英雄");
}
@Override
public void buildSex() {
actor.setSex("男");
}
@Override
public void buildFace() {
actor.setFace("英俊");
}
@Override
public void buildCostume() {
actor.setCostume("盔甲");
}
}