资讯专栏INFORMATION COLUMN

一起学设计模式 - 建造者模式

MockingBird / 1613人阅读

摘要:构造函数参数太多错误的对象状态使用模式在我们的示例中,改造下召唤师类齐天大圣孙悟空上单基石天赋战争雷霆瘟疫之源图奇下路基石天赋战阵热诚皎月女神戴安娜中单建造者模式让我们写的代码更具可读性,可理解为建立复杂的物体。

建造者模式(Builder Pattern)属于创建型模式的一种,将多个简单对象构建成一个复杂的对象,构建过程抽象化,不同实现方法可以构造出不同表现(属性)的对象,还提供了一种更加优雅构建对象的方式...

概述

有时候构建一个复杂的对象,需要经过好几步的处理,比如常用的StringBuffer、StringBuilder、以及Swagger(一种接口文档),都是以这种模式构建对象的

优点

建造者模式比较独立,将对象本身与构建过程解耦

精准控制构建出的对象和内容,构造层和显示层是分离的

写法上更加优雅

缺点

范围受限,不适合差异较大的对象

内部复杂多变,构造类相对会多

适用场景

构建具有共同特性的复杂对象

相关模式

抽象工厂模式与建造者模式相似,因为它也可以创建复杂对象。主要的区别是建造者模式着重于一步步得构造出复杂对象。而抽象工厂模式着重于多个系列的产品对象(简单的或是复杂的)。建造者是在最后的一步返回对象,而对于抽象工厂来说,对象是立即返回的。

案例

传统方式

public class Summoner {

    private String name;
    private String type;
    private String innate;

    public Summoner(String name, String type, String innate) {
        this.name = name;
        this.type = type;
        this.innate = innate;
    }
}

简单的对象我们可以使用下面这种方式,因为属性较少这种方式还看的,但不幸的是如果要增加字段或我们还需要去扩展构造方法,且可读性不好,相同类型的情况下在一定程度上混淆视听了

Summoner s1 = new Summoner("德玛","战士","战争雷霆");

为什么不调用无参数的构造函数,通过setter方法来减轻问题。

解答: 如果程序员忘记调用一个特定的setter方法会发生什么?我们可能得到的是一个部分初始化的对象,而且编译器也不会检测出任何问题。

构造函数参数太多

错误的对象状态

使用模式

在我们的示例中,改造下召唤师类

public class Summoner {

    private String name;
    private String type;
    private String innate;

    private Summoner(Builder builder) {
        this.name = builder.name;
        this.type = builder.type;
        this.innate = builder.innate;
    }

    protected static class Builder {
        private String name;
        private String type;
        private String innate;

        protected Builder name(String name) {
            this.name = name;
            return this;
        }

        protected Builder type(String type) {
            this.type = type;
            return this;
        }

        protected Builder innate(String innate) {
            this.innate = innate;
            return this;
        }
        protected Summoner build() {
            return new Summoner(this);
        }
    }
}

public class BuilderDemo {

    public static void main(String[] args) {
        Summoner monkey = new Summoner.Builder().name("齐天大圣 - 孙悟空").type("上单 - AD").innate("基石天赋 - 战争雷霆").build();
        System.out.println(monkey.toString());

        Summoner mouse = new Summoner.Builder().name("瘟疫之源 - 图奇").type("下路 - ADC").innate("基石天赋 - 战阵热诚").build();
        System.out.println(mouse.toString());

        Summoner diann = new Summoner.Builder().name("皎月女神 - 戴安娜").type("中单 - AP").build();
        System.out.println(diann.toString());
    }
}

建造者模式让我们写的代码更具可读性,可理解为建立复杂的物体。它往往是实现一个连贯的操作,从而更加直观,此处由于类型较为单一差距不大,但遇到复杂对象构建差距就立竿见影了

Summoner{name="齐天大圣 - 孙悟空", type="上单 - AD", innate="基石天赋 - 战争雷霆"}
Summoner{name="瘟疫之源 - 图奇", type="下路 - ADC", innate="基石天赋 - 战阵热诚"}
Summoner{name="皎月女神 - 戴安娜", type="中单 - AP", innate="null"}
总结

我们通过一个简单的代码例子开始,慢慢变得复杂。然后使用Builder模式来解决我们发现的问题。

如果你发现自己在一个情况下,你不断添加新参数的构造函数,使得代码变得容易出错,很难读,也许可以考虑使用一个Builder重构你的代码。

推荐

lombok: https://github.com/rzwitserloot/lombok

IntelliJ IDEA : InnerBuilder 插件

- 说点什么

全文代码:https://gitee.com/battcn/design-pattern/tree/master/Chapter4/battcn-builder

个人QQ:1837307557

battcn开源群(适合新手):391619659

微信公众号:battcn(欢迎调戏)

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

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

相关文章

  • 《源码中的设计模式》之建造模式——链式调用

    摘要:上期原型模式发布以后,收到了粉丝的感谢,一条创作的动力更足了。今天我们一块看一下建造者模式,同样是创建型设计模式。为我们提供了建造者模式的快速实现,要应用到实际编码中。 ...

    wind3110991 评论0 收藏0
  • JS 建造模式

    摘要:如何应对这种变化如何提供一种封装机制来隔离出复杂对象的各个部分的变化,从而保持系统中的稳定构建算法不随着需求改变而改变这就是要说的建造者模式。建造者模式,将一个复杂对象的构建层与其表示层相互分离,使得同样的构建过程可以采用不同的表示。 1. 简介 在软件系统中,有时候面临着一个复杂对象的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着...

    channg 评论0 收藏0
  • 设计模式建造设计模式

    摘要:本质建造者设计模式分离了对象子组件的构造过程和组装过程,实现了构建与组装的解耦,不同的构建器相同的组装顺序以及相同的构建器不同的组装顺序都可以创建出不同的对象,使得构建与组装充分解耦,进而实现构建算法与组装算法的解耦,从而实现更好的复用。 这是设计模式系列的第二篇——建造者设计模式,我希望推送的文章是一个系列的,尽量保持一样的写作风格,尽量把我理解的阐述清楚,关于建造者设计模式主要从以...

    wangxinarhat 评论0 收藏0

发表评论

0条评论

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