前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Java链式对象构造的正确姿势

Java链式对象构造的正确姿势

作者头像
明明如月学长
发布2021-08-31 16:08:43
发布2021-08-31 16:08:43
1.3K00
代码可运行
举报
运行总次数:0
代码可运行

开发业务代码过程中,如果能过类似JQuey那种链式编程或者Java中的Builder模式一样可以一直点下去,是一种非常爽的体验。

如果内部有一些类似Map、JSONObject的属性,怎样更表意呢?怎样隐藏内部数据结构呢?

普通的Builder模式应该外部创建Map或者JSONObject对象并赋值,能否有更好的解决方案呢?

当然也可以通过uilder中写一个put方法可以避免多出现一个对象,但是如何更表意呢?

代码语言:javascript
代码运行次数:0
复制
 public Builder put(String key, String value){
            data.put(key, value);
            return this;
        }

下面介绍一个不错的技巧

一、一个不错的技巧

借助Builder模式和中间类实现链式编程和淡化内部特殊类型(JSONObject)的属性的效果。

代码语言:javascript
代码运行次数:0
复制
import com.alibaba.fastjson.JSONObject;
import lombok.Data;

/**
 * 明明如月
 * liuwangyangedu@163.com
 */
@Data
public class MyConfig {
    private JSONObject data;

    private String appName;

    private Long logTime;

    private MyConfig(Builder builder) {
        this.data = builder.data;
        this.appName = builder.appName;
        this.logTime = builder.logTime;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private JSONObject data = new JSONObject();

        private String appName;

        private Long logTime;

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

        public Builder logTime(Long logTime) {
            this.logTime = logTime;
            return this;
        }

        public SemiData key(String key) {
            return new SemiData(this, key);
        }

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

        public class SemiData {
            private String key;
            private Builder parent;

            private SemiData(Builder myConfig, String key) {
                this.parent = myConfig;
                this.key = key;
            }

            public Builder value(Object value) {
                parent.data.put(key, value);
                return parent;
            }
        }
    }

}

用法

代码语言:javascript
代码运行次数:0
复制
 @Test
    void builder() {

        String appName = "test";
        Long currentTime = System.currentTimeMillis();
        MyConfig myConfig = MyConfig.builder()
                .appName(appName)
                .logTime(currentTime)
                .key("name").value("张三")
                .key("age").value(24)
                .key("sex").value("男")
                .build();

        assertEquals(appName, myConfig.getAppName());
        assertEquals(currentTime, myConfig.getLogTime());

        JSONObject data = myConfig.getData();
        assertEquals(data.get("name"),"张三");
    }

二、另外一种变种

不使用Builder模式,通过中间类实现链式编程和淡化内部特护类型(JSONObject)的属性的效果。

代码语言:javascript
代码运行次数:0
复制
import com.alibaba.fastjson.JSONObject;
import lombok.Data;

/**
 * 明明如月
 * liuwangyangedu@163.com
 */
@Data
public class MyConfig {
    private JSONObject data = new JSONObject();

    private String appName;

    private Long logTime;

    public MyConfig appName(String appName) {
        this.appName = appName;
        return this;
    }

    public MyConfig logTime(Long logTime) {
        this.logTime = logTime;
        return this;
    }

    public SemiData key(String key) {
        return new SemiData(this, key);
    }

    public class SemiData {
        private String key;
        private MyConfig parent;

        private SemiData(MyConfig myConfig, String key) {
            this.parent = myConfig;
            this.key = key;
        }

        public MyConfig value(Object value) {
            parent.data.put(key, value);
            return parent;
        }
    }

}

用法

代码语言:javascript
代码运行次数:0
复制
@Test
    void builder() {

        String appName = "test";
        Long currentTime = System.currentTimeMillis();
        MyConfig myConfig = new MyConfig().appName(appName)
                .logTime(currentTime)
                .key("name").value("张三")
                .key("age").value(24)
                .key("sex").value("男");

        assertEquals(appName, myConfig.getAppName());
        assertEquals(currentTime, myConfig.getLogTime());

        JSONObject data = myConfig.getData();
        assertEquals(data.get("name"),"张三");

    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/04/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、一个不错的技巧
  • 二、另外一种变种
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档