如何将对象一步一步搭建起来 -- 建造者模式

有一些较为复杂的对象,创建他们可能需要很多步骤,比如在一些RPG游戏中创建一个角色,我们通常需要选取职业,性别,种族,面部特征,体格等元素,如果把一个游戏中的角色设计成一个对象的话,我们要如何创建出这个复杂的对象呢?
比较好的方法是建造者模式。

复杂对象的创建和表示分离:

如何使用建造者模式:
在建造者模式中我们需要这样几个类:

  1. 抽象建造者
  2. 具体建造者
  3. 产品对象
  4. 指挥者
    下面举个例子:
/**
 * 抽象建造者
 */
public abstract class AbstractProductBuilder {
    protected Product product = new Product();

    protected abstract void buildName();
    protected abstract void buildType();
    protected abstract void buildPrice();

    public Product getProduct() {
        return product;
    }
}

/**
 * 具体建造者
 */
public class AppleBuilder extends AbstractProductBuilder {
    @Override
    protected void buildName() {
        product.setName("iphone12");
    }

    @Override
    protected void buildType() {
        product.setType("phone");
    }

    @Override
    protected void buildPrice() {
        product.setPrice("10000");
    }
}

/**
 * 具体建造者
 */
public class HuaweiBuilder extends AbstractProductBuilder{

    @Override
    protected void buildName() {
        product.setName("p40");
    }

    @Override
    protected void buildType() {
        product.setType("phone");
    }

    @Override
    protected void buildPrice() {
        product.setPrice("8000");
    }
}

/**
 * 指挥者
 */
public class Director {
    private Map<String, AbstractProductBuilder> builders;

    private Director() {
        this.builders = new HashMap<>();
        this.builders.put("apple", new AppleBuilder());
        this.builders.put("huawei", new HuaweiBuilder());
    }

    public void setBuider(String key, AbstractProductBuilder builder) {
        builders.put(key, builder);
    }

    public Product build(String key) {
        AbstractProductBuilder builder = builders.get(key);
        builder.buildName();
        builder.buildPrice();
        builder.buildType();
        return builder.getProduct();
    }
}

对于不同产品的创建方式可以实现不同的建造者,然后将该建造者交给指挥者,用来创建复杂产品,当然,产品的每个属性不一定要写死,也可以让客户端来传递,这样不同的建造者有很多种写法和使用方式,建造复杂对象非常灵活。

餐后甜点

在JDK中我们用得最多的用时建造者模式的类库就是StringBuilder和StringBuffer了把。
下面看看JDK中这样的建造者是如何使用的。

/**
* 抽象建造者,定义了append insert delete等一些用于构建字符串的方法
*/
abstract class AbstractStringBuilder implements Appendable, CharSequence 

/**
*具体建造者
*/
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
/**
*具体建造者
*/
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

他们的方法功能类似,但是StringBuffer的方法上都有synchronized关键字,这是为了保证该构建字符串的时候的线程安全。

posted @ 2020-07-17 17:23  BarneyMosby  阅读(148)  评论(0)    收藏  举报