java设计模式---生成器模式(Builder pattern)

java设计模式—生成器模式(Builder pattern)

  1. 简介
    1.1 定义
    工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。
    与抽象工厂的区别:
    在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的建造过程。
    1.2 主要作用
    在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
    (1)用户只需要给出指定复杂对象的类型和内容;
    (2)建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)
    1.3 解决的问题
    (1)方便用户创建复杂的对象(不需要知道实现过程)
    (2)代码复用性 & 封装性(将对象构建过程和细节进行封装 & 复用)
    2. UML图
    这里写图片描述
    (1)指挥者(Director)直接和客户端(Client)进行需求沟通;
    (2)沟通后指挥者将客户创建产品的需求划分为各个部件的建造请求(Builder);
    (3)将各个部件的建造请求委派到具体的建造者(ConcreteBuilder);
    (4)各个具体建造者负责进行产品部件的构建;
    (5)最终构建成具体产品(Product)。
    3. 简单实现
// 简单的产品
public class Pizza {
    private String dough = "";
    private String sauce = "";
    public void setDough(String dough) {
        this.dough = dough;
    }
    public void setSauce(String sauce) {
        this.sauce = sauce;
    }
    @Override
    public String toString() {
        return "Pizza [dough=" + dough + ", sauce=" + sauce +"]";
    }
}
// 抽象的Builder
public abstract class PizzaBuilder {
    protected Pizza pizza;
    public Pizza getPizza() {
        return pizza;
    }
    public void createNewPizzaProduct() {
        pizza = new Pizza();
    }
    public abstract void buildDough();
    public abstract void buildSauce();
}

//具体的Builder 1
public class Test1PizzaBuilder extends PizzaBuilder {
    @Override
    public void buildDough() {
        pizza.setDough("dough test1");
    }
    @Override
    public void buildSauce() {
        pizza.setSauce("sauce test1");
    }
}

// 具体的Builder 2
public class Test2PizzaBuilder extends PizzaBuilder {
    @Override
    public void buildDough() {
        pizza.setDough("dough test2");
    }
    @Override
    public void buildSauce() {
        pizza.setSauce("souce test2");
    }
}
public class Waiter {
    private PizzaBuilder pizzaBuilder;

    public void setPizzaBuilder(PizzaBuilder pizzaBuilder) {
        this.pizzaBuilder = pizzaBuilder;
    }
    public void constructPizza()
    {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
    }

    public Pizza getPizza() {
         return pizzaBuilder.getPizza();
    }
}
// 测试
public class BuilderTest {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        PizzaBuilder test1pizzabuilder = new Test1PizzaBuilder();
        PizzaBuilder test2pizzabuilder = new Test2PizzaBuilder();

        waiter.setPizzaBuilder(test1pizzabuilder );
        waiter.constructPizza();
        Pizza pizza = waiter.getPizza();

        System.out.println(pizza);
        waiter.setPizzaBuilder(test2pizzabuilder);
        waiter.constructPizza();
        System.out.println(waiter.getPizza());
    }
}

4. 优缺点
4.1 优点
(1)易于解耦
将产品本身与产品创建过程进行解耦,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。
(2)易于精确控制对象的创建
将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
(3)易于拓展
增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则“。
每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。
4.2 缺点
建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeBuilderJava 1.6  自动生成 Builder 模式。当设计类的构造函数或静态工厂具有多个参数时,Builder 模式是一个不错的选择。—— Effective Java,第二版,第39页背景在 Java 中实现 Builder 模式容易出错和重复。即使是一个简单的四字段类,最基本的构建器 API 需要 39 行代码,如果你不使用像 AutoValue 这样的实用程序来生成值样板,则需要 72 行代码。使用import org.inferred.freebuilder.FreeBuilder; @FreeBuilder public interface Person {   /** Returns the person's full (English) name. */   String name();   /** Returns the person's age in years, rounded down. */   int age();   /** Builder of {@link Person} instances. */   class Builder extends Person_Builder { } }JavaBean convention如果值类型遵循 JavaBean 命名约定,只需在访问器方法前面加上'get'(或者,布尔访问器是'is')。 FreeBuilder 会跟随,并在 setter 方法上添加“set”前缀,以及从 toString 输出中删除前缀。@FreeBuilder public interface Person {   /** Returns the person's full (English) name. */   String getName();   /** Returns the person's age in years, rounded down. */   int getAge();   /** Builder of {@link Person} instances. */   class Builder extends Person_Builder { } } Person person = new Person.Builder()     .setName("Phil")     .setAge(31)     .build(); System.out.println(person);  // Person{name=Phil, age=31} 标签:FreeBuilder

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值