聊聊设计模式之builder 模式

本文探讨了在Java中如何使用Builder模式解决构造复杂对象时的问题,通过实例对比了传统构造方法和set方法的不足,介绍了Builder模式的实现方式,强调了其在确保对象完整性和提高代码优雅性方面的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主题我们编码跟人生一样,需要有仪式感,优雅。哈哈 切入正题
先看一段代码

public ContactBusinessImpl(IContactDao contactDao, IIdMetaBusiness idMetaBusiness,
                               IDepartmentBusiness departmentBusiness,
                               IEuserBusiness euserBusiness,
                               IUserContactBusiness userContactBusiness,
                               IUserEnterpriseBusiness userEnterpriseBusiness,
                               IUserRoleBusiness userRoleBusiness,
                               IUserBusiness userBusiness,
                               ISensitiveWordBusiness sensitiveWordBusiness,
                               IProducerBusiness producerBusiness,
                               IOperationTracesBusiness operationTracesBusiness,
                               IMobileUserMappingDao mobileUserMappingDao,
                               ICommonBusiness commonBusiness) {
        this.contactDao = contactDao;
        this.idMetaBusiness = idMetaBusiness;
        this.departmentBusiness = departmentBusiness;
        this.euserBusiness = euserBusiness;
        this.userContactBusiness = userContactBusiness;
        this.userEnterpriseBusiness = userEnterpriseBusiness;
        this.userRoleBusiness = userRoleBusiness;
        this.userBusiness = userBusiness;
        this.sensitiveWordBusiness = sensitiveWordBusiness;
        this.producerBusiness = producerBusiness;
        this.operationTracesBusiness = operationTracesBusiness;
        this.mobileUserMappingDao = mobileUserMappingDao;
        this.commonBusiness = commonBusiness;
    }

这样的构造是不是让人蛋疼, 然后如果需要传入非必须属性的时候 怎么办? 构造方法参数太多了,很容易传错。
在此我么想到了 set 如下

 public String getShoes() {
        return shoes;
    }

    public void setShoes(String shoes) {
        this.shoes = shoes;
    }

    ......

这种缺点有很多,缺点1 如果我要定义 final 的成员呢?
然后比如这样 缺点2 set 几十个的时候:

 Contact contact = new Contact();

                    contact.setContactId(rs.getString("contactId"));
                    contact.setEnterpriseId(rs.getString("enterpriseId"));
                    contact.setDepartmentId(rs.getString("departmentId"));
                    contact.setUserId(rs.getString("userId"));
                    contact.setEuserId(rs.getString("euserId"));
                    contact.setContactSort(rs.getInt("contactSort"));
                    contact.setContactLevel(rs.getInt("contactLevel"));
                    contact.setDetail(rs.getString("detail"));
                    contact.setCreateUserId(rs.getString("createUserId"));

非常的不优雅。
缺点 3 调用者可能拿到不完整状态的对象,这种方式是 先创建对象、后赋值,用户不知道什么时候拿到的对象是完整的,构建完成的。很有可能你只 set 了一两个属性就返回了,一些必要的属性没有被赋值。

回到主题: 优雅的 变种builder 模式
直接上代码:

public class ContactSingleExportBo{

    private String departmentPath;
    private String contactId;
    private String name;
    private String mobile;
    private final String departmentId;
    private String email;
    private String position;
    private String contactSort;
    private String deptVisib;
    private String euserType;
    private String otherPhone;
    private String userData;
    private String tel;
    private String contactLevel;
    private String departmentSort;
    private String departmentDepth;

    public static ContactSingleExportBo.Builder builder(String departmentId) {
        return new ContactSingleExportBo.Builder(departmentId);
    }
    // 构造 ,参数为它的静态内部类,使用静态内部类的变量一一赋值
    private ContactSingleExportBo(Builder builder) {
        departmentPath = builder.departmentPath;
        contactId = builder.contactId;
        name = builder.name;
        mobile = builder.mobile;
        departmentId = builder.departmentId;
        email = builder.email;
        position = builder.position;
        contactSort = builder.contactSort;
        deptVisib = builder.deptVisib;
        euserType = builder.euserType;
        otherPhone = builder.otherPhone;
        userData = builder.userData;
        tel = builder.tel;
        contactLevel = builder.contactLevel;
        departmentSort = builder.departmentSort;
        departmentDepth = builder.departmentDepth;
    }

    //的静态内部类,成员变量和 本类 的一致
    public static final class Builder {
        private String departmentPath;
        private String contactId;
        private String name;
        private String mobile;
        private final String departmentId; //必选 初始化在构造器中
        private String email;
        private String position;
        private String contactSort;
        private String deptVisib;
        private String euserType;
        private String otherPhone;
        private String userData;
        private String tel;
        private String contactLevel;
        private String departmentSort;
        private String departmentDepth;

        public Builder(String departmentId) {
            this.departmentId = departmentId;
        }

        public Builder departmentPath(String val) {
            departmentPath = val;
            return this;
        }

        public Builder contactId(String val) {
            contactId = val;
            return this;
        }

        public Builder name(String val) {
            name = val;
            return this;
        }

        public Builder mobile(String val) {
            mobile = val;
            return this;
        }


        public Builder email(String val) {
            email = val;
            return this;
        }

        public Builder position(String val) {
            position = val;
            return this;
        }

        public Builder contactSort(String val) {
            contactSort = val;
            return this;
        }

        public Builder deptVisib(String val) {
            deptVisib = val;
            return this;
        }

        public Builder euserType(String val) {
            euserType = val;
            return this;
        }

        public Builder otherPhone(String val) {
            otherPhone = val;
            return this;
        }

        public Builder userData(String val) {
            userData = val;
            return this;
        }

        public Builder tel(String val) {
            tel = val;
            return this;
        }

        public Builder contactLevel(String val) {
            contactLevel = val;
            return this;
        }

        public Builder departmentSort(String val) {
            departmentSort = val;
            return this;
        }

        public Builder departmentDepth(String val) {
            departmentDepth = val;
            return this;
        }

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

看起来代码很多, 其实都可以自动生成,
在这里插入图片描述
还有 IEDA 可以使用插件 直接注解 ,更优雅,

/**
 *  删除文档元数据
 */
@Getter
@Setter
@Builder
public class DocNodeLocationMeta {
    @NotNull(message = "文档类型不能为null")
    private String indexType;                      // 索引类型
    @NotNull(message = "分片信息不能为null")
    private String indexShardingData;              // 分片字段
    @NotNull(message = "文档标识符不能为null")
    private String docIdentifier;                  // 文档标识符
    private String routingData;                    // 路由数据

}

是不是很简单了? 注解自行了解插件lombok
可以看到

然后我们来看看它的链式调用:
在这里插入图片描述

这里灰常优雅 ,先赋值,后创建对象,最终调用 build() 方法才创建了构建类的对象,保证了状态的完整性。

总结:
经典的 Builder 模式定义为:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值