Java设计模式-建造者模式

Java 的多个设计模式中,最易理解的应该就属 建造者模式 了,虽说看似很简单容易理解,但是却是很好的实践方式。
在平常的开发中,也有很多地方可以用到,让代码也是变得更加具有可读性和可维护性。

建造者模式的定义

什么是建造者模式呢?

网上查一下,如是说:

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

看起来还是有点抽象。其实通俗一点的说,建造者模式就是将一个复杂的对象的一系列属性的设置分为多个步骤来一步一步的来设置它的一系列属性,最终构建出这个复杂的对象。

建造者模式的场景

建造者模式就是将原本冗长的对象属性设置,转为使用清晰的明了的步骤来设置。

在我们平时编码的时候,总会遇到一些属性比较多,而且有嵌套对象的的对象,这个时候,如果使用常规的方式去构建这个对象,我们需要一个一个属性的去 set 它的属性。

如果说是字段不多还好,但是如果是有很多的字段,还有嵌套对象,那是不是感觉要崩溃。

还有一个就是,不知道大家遇到过,一个对象的构造方法参数一大堆,在 new 这个对象的时候,设置参数写着写着都不知道这个参数到底是干嘛的了,这样就很容易出错,毕竟如果是类型但是含义完全不同的字段,你设置错了也不会报错,但最终的结果却会是大相径庭。而且代码的可读性也是大大的降低了。

遇到这种情况的时候,我们就应该要想想,需要怎么做才能够减少出错的概率,并且提升代码的可读性和代码的可维护性。这个时候建造者模式就应该是个不二之选了。

建造者模式的例子

这里我们使用一个下单的场景来举例。

比如一个订单对象,包含了订单数据信息,收货人信息,地址信息,商品信息,促销信息,物流信息,支付信息。

在下单的时候,我们需要将各种信息组装到订单中,其中就包含了很多的字段,还有嵌套的对象,这里我们就可以采用建造者模式来一步一步的构建出一个完整的订单对象。

show code

订单对象对象包含了以下的字段信息:

@Data
public class Order {

    /**
     * 订单id
     */
    private Long id;

    /**
     * 订单创建时间
     */
    private Timestamp createTime;

    /**
     * 订单更新时间
     */
    private Timestamp updateTime;

    /**
     * 订单号
     */
    private String orderCode;

    /**
     * 订单状态
     */
    private OrderStatus orderStatus;

    /**
     * 未支付订单过期时间
     */
    private Timestamp expireAt;

    /**
     * 订单用户信息
     */
    private OrderUser orderUser;

    /**
     * 订单物流信息
     */
    private OrderDelivery orderDelivery;

    /**
     * 订单支付信息
     */
    private OrderPayment orderPayment;

    /**
     * 订单商品信息
     */
    private List<OrderProduct> orderProducts;

    /**
     * 订单促销信息
     */
    private List<OrderPromotion> orderPromotions;

    /**
     * 订单收货地址信息
     */
    private OrderAddress orderAddress;
}

上面只是简单的列了下订单的信息,真实的场景肯定会有更多的字段。下面我们就使用建造者模式来构建这个订单信息。

创建一个名为 OrderBuilder 的订单信息构造器。

public class OrderBuilder {

    /**
     * 将需要构建的 order 对象作为全局变量
     * 在一步一步构建完成之后返回该对象
     */
    private Order order;

    /**
     * 使构造器私有化
     * 不让使用者使用 new 来创建构造器,而是通过 {@link OrderBuilder#newBuilder()} 来创建构造器
     */
    private OrderBuilder() {
    }

    /**
     * 建造者模式的入口
     * 这里会初始化构造器和需要构造的order对象
     * 也可以根据自己的要做一些其他的操作
     *
     * @return 构造器本身,后面可以链式调用
     */
    public static OrderBuilder newBuilder() {
        OrderBuilder orderBuilder = new OrderBuilder();
        orderBuilder.order = new Order();

        return orderBuilder;
    }

    /**
     * 这里设置一些order的简单属性
     *
     * @param orderVo 前端传入的 order value object 对象
     * @return 构造器本身,后面可以链式调用
     */
    public OrderBuilder initOrder(OrderVo orderVo) {
        //这里根据自己的需要做一些简单的设值操作
        //...
        return this;
    }

    /**
     * 设置订单用户信息
     *
     * @param orderUser 前端传入的订单用户 value object 对象
     * @return 构造器本身,后面可以链式调用
     */
    public OrderBuilder setOrderUser(OrderUserVo orderUser) {
        //...
        return this;
    }

    /**
     * 设置订单用户收货地址信息
     *
     * @param orderAddress 前端传入的订单用户收货地址 value object 对象
     * @return 构造器本身,后面可以链式调用
     */
    public OrderBuilder setOrderAddress(OrderAddressVo orderAddress) {
        //...
        return this;
    }

    /**
     * 设置订单物流信息
     *
     * @param orderDelivery 前端传入的订单物流 value object 对象
     * @return 构造器本身,后面可以链式调用
     */
    public OrderBuilder setOrderDelivery(OrderDeliveryVo orderDelivery) {
        //...
        return this;
    }

    /**
     * 设置订单商品信息
     *
     * @param orderProducts 前端传入的订单商品 value object 对象集合
     * @return 构造器本身,后面可以链式调用
     */
    public OrderBuilder setOrderProducts(List<OrderProductVo> orderProducts) {
        //...
        return this;
    }

    /**
     * 设置订单促销信息
     *
     * @param orderPromotions 前端传入的订单促销信息 value object 对象集合
     * @return 构造器本身,后面可以链式调用
     */
    public OrderBuilder setOrderPromotions(List<OrderPromotionVo> orderPromotions) {
        //...
        return this;
    }

    /**
     * 设置订单支付信息
     *
     * @param orderPayment 前端传入的订单支付信息 value object 对象集合
     * @return 构造器本身,后面可以链式调用
     */
    public OrderBuilder setOrderPayment(OrderPaymentVo orderPayment) {
        //...
        return this;
    }

    /**
     * 返回最终构建完成的订单对象
     *
     * @return 返回最终构建完成的订单对象
     */
    public Order build() {
        return this.order;
    }

}

上面的订单信息构造器创建好了,我们在构建订单对象的时候,就显得特别的简洁了,只需要创建构造器和根据需要调用构造器方法设值就行了。

Order order = OrderBuilder.newBuilder()
                .initOrder(orderVo)
                .setOrderUser(orderUserVo)
                .setOrderAddress(orderAddressVo)
                .setOrderProducts(orderProducts)
                .setOrderPromotions(orderPromotions)
                .setOrderPayment(orderPaymentVo)
                .build();

尾巴

建造者模式就说完了,有错误的请留言指出,文笔不是很好,请多包涵。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 定义 建造模式是对象的创建模式。建造模式可以将一个产品的内部表象(internal representation)...
    步积阅读 6,931评论 1 7
  • 前言 建造者模式又被称呼为生成器模式,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。使用多个简...
    斌林诚上阅读 39,141评论 7 65
  • 1.定义 建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。这种类型设计模式属于创建型模式,它提供了一种创...
    132xin阅读 110评论 0 3
  • 建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 实用范围 ...
    怡红快绿阅读 409评论 0 0
  • 我和班长走到了他家... “进来坐吧,我爸出差了,我姐出去了,我妈还在加班,待会就回来了。我拿件外套给你吧!”班长...
    挽留_5ee1阅读 210评论 1 2