资讯专栏INFORMATION COLUMN

Java设计模式-建造者模式

txgcwm / 454人阅读

摘要:在建造者模式比较庞大时,导演类可以有多个。该种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反设计的最初目标。源码地址参考文献设计模式之禅

定义
Separate the construction of a complex object from its representation so that the sameconstruction process can create different representations.

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

实现 产品类

由多个部件组成

public class Product {

    private String partA;
    private String partB;

    public String getPartA() {
        return partA;
    }

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public String getPartB() {
        return partB;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    @Override
    public String toString() {
        return "partA:" + partA + ", partB:" + partB;
    }
}
抽象建造者

规范产品的组建,一般是由子类实现。其中,buildPart方法是零件的配置,设置一个不同零件,或者不同的装配顺序就可能产生不同的产品。

public abstract class Builder {

    /**
     * 设置产品的不同组件/零件,以获得不同的产品
     */
    public abstract void buildPartA();

    /**
     * 设置产品的不同组件/零件,以获得不同的产品
     */
    public abstract void buildPartB();

    /**
     * 建造产品
     * @return
     */
    public abstract Product getProduct();

}
具体建造者

实现抽象类定义的所有方法,并且返回一个组建好的对象

public class ConcreteBuilder1 extends Builder {

    private Product product = new Product();

    @Override
    public void buildPartA() {
        System.out.println("ConcreteBuilder1->buildPartA()");
        product.setPartA("组件A1");
    }

    @Override
    public void buildPartB() {
        System.out.println("ConcreteBuilder1->buildPartB()");
        product.setPartB("组件B1");
    }

    @Override
    public Product getProduct() {
        System.out.println("ConcreteBuilder1->getProduct()");
        return product;
    }
}
public class ConcreteBuilder2 extends Builder {

    private Product product = new Product();

    @Override
    public void buildPartA() {
        System.out.println("ConcreteBuilder2->buildPartA()");
        product.setPartA("组件A2");
    }

    @Override
    public void buildPartB() {
        System.out.println("ConcreteBuilder2->buildPartB()");
        product.setPartB("组件B2");
    }

    @Override
    public Product getProduct() {
        System.out.println("ConcreteBuilder2->getProduct()");
        return product;
    }
}
导演类

也叫指挥者类,负责安排已有模块的顺序,然后告诉Builder开始建造。导演类起到封装的作用,避免高层模块深入到建造者内部的实现类。在建造者模式比较庞大时,导演类可以有多个。

public class Director {

    private Builder builder;

    public Director(Builder builder){
        this.builder = builder;
    }

    /**
     * 将部件partA、partB...最后组成复杂对象(使用多个简单的对象一步一步构建成一个复杂的对象)
     */
    public void construct(){
        builder.buildPartA();
        builder.buildPartB();
    }
}
客户端代码
public class Client {

    public static void main(String[] args) {
        Builder builder1 = new ConcreteBuilder1();
        Director director1 = new Director(builder1);
        director1.construct();
        Product product1 = builder1.getProduct();
        System.out.println(product1);

        Builder builder2 = new ConcreteBuilder2();
        Director director2 = new Director(builder2);
        director2.construct();
        Product product2 = builder2.getProduct();
        System.out.println(product2);
    }
}
优点

封装性

客户端不必知道产品内部组成的细节

建造者独立,容易扩展

便于控制细节风险

由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响

使用场景

相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。

多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。

产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。

在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。

该种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反设计的最初目标。

扩展

除上面的通用源码实现外,还有另外一种更为常见的场景,就是当一个类构造器需要传入很多参数时,并且通常有一部分参数是可选的,如果使用构造方法创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用 builder模式:

public class Person {
    private final String cardId;
    private final String name;
    private final Integer age;
    private final String sex;
    private final String address;

    public static class Builder {
        // 必须的参数
        private final String cardId;
        private final String name;
        // 可选的参数
        private Integer age;
        private String sex;
        private String address;

        public Builder(String cardId, String name) {
            this.cardId = cardId;
            this.name = name;
        }

        public Builder age(Integer age) {
            this.age = age;
            return this;
        }

        public Builder sex(String sex) {
            this.sex = sex;
            return this;
        }

        public Builder address(String address) {
            this.address = address;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }

    private Person(Builder builder) {
        this.cardId = builder.cardId;
        this.name = builder.name;
        this.age = builder.age;
        this.sex = builder.sex;
        this.address = builder.address;
    }

    @Override
    public String toString() {
        return "cardId:" + cardId + ",name:" + name + ",age:" + age + ",sex:" + sex + ",address:" + address;
    }
}
public class Client {

    public static void main(String[] args) {
        Person zhangsan = new Person.Builder("100000000000000000", "张三")
                .age(28)
                .sex("MALE")
                .address("BJ")
                .build();
        System.out.println(zhangsan);

        Person lisi = new Person.Builder("100000000000000001", "李四")
                .address("TJ")
                .build();
        System.out.println(lisi);
    }
}

上面的代码通过Person的内部类Builder创建一个Person实例,其中,李四对年龄和性别进行了”保密“(age和sex均为可选参数)。可以看到,代码看起来更为优雅,大大增强了可读性,并且客户端代码也更容易编写。

源码地址:https://gitee.com/tianranll/j...

参考文献:《设计模式之禅》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75162.html

相关文章

  • 设计模式建造模式

    摘要:建造者实现抽象类的所有未实现的方法,具体来说一般是两项任务组建产品返回组建好的产品。 0x01.定义与类型 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 用户只需指定需要建造的类型就可以得到他们,建造过程及细节不需要知道 类型:创建型 实现建造模式的两种方式 1.抽象建造者 UML: showImg(https://segmentfault.co...

    banana_pi 评论0 收藏0
  • 我的Java设计模式-建造模式

    摘要:汽车本身就是复杂产品对象,其制造过程可以形象的表示建造者模式。另一辆法拉利,。法拉利具体建造者代码如下构造法拉利的第一部分。咻咻法拉利已造好三建造者模式的优缺点优点降低代码耦合度。 在未上大学之前,一直有个梦想I have a dream!,就是能成为一位汽车工程师,一直幻想着开着自己设计的汽车飞奔在公路上,迷倒了万千少女。咳咳~~虽然现在没实现我的dream,但梦想还是得有的。 说到...

    elisa.yang 评论0 收藏0
  • Java设计模式之(三)——建造模式

    摘要:建造者模式实现建造者模式实现创建抽象建造者类创建具体建造者类。建造者模式使用场景建造者模式使用场景相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。1、什么是建造者模式 Separate the construction of a complex object from its representation so that the same constructi...

    Forelax 评论0 收藏0
  • #yyds干货盘点#Java设计模式之(三)——建造模式

    1、什么是建造者模式Separate the construction of a complex object from its representation so that the same construction process can create different representations.将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。 说人话:将构...

    番茄西红柿 评论0 收藏2637
  • 深入理解建造模式 ——组装复杂的实例

    摘要:而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品。最后通过一个套餐实例,介绍了建造者模式在实例中的基本使用手段。 历史文章回顾: 设计模式专栏 深入理解单例模式 深入理解工厂模式 历史优质文章推荐: 分布式系统的经典基础理论 可能是最漂亮的Spring事务管理详解 面试中关于Java虚拟机(jvm)的问题看这篇就够了 无论是在现实世界中还是在软件...

    sanyang 评论0 收藏0

发表评论

0条评论

txgcwm

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<