• Effective Java 阅读笔记--之(一) 建造者模式(Builder)


    本文作者是张艳涛

    说起设计模式,都能说出来有叫建造者模式的一种模式,第一次对这个用法是在msb 的ResultWrapper中使用

     return ResultWrapper.getSuccessBuilder().data(payHtml).build();

    ,他是使用Lombok的@builder注解实现的,看了网上的资料想自己写下,还没写出来,

    今天看Effective java 第二章 他就给出了建造者模式的写法,书上给出来的定义

    它不直接生成想要的对象,二十让客户端利用所必要的参数调用构造器(或者静态工厂),特岛一个builder 对象,然后客户端在builder对象上调用类似setter的方法,来设置每个相关的可选参数.

    最后,客户端调用午餐的build方法来生成通常是不可变的对象,同时给出了一个范例

    package com.zyt.cap2.buildpatten;
    
    /**
     * @author 张艳涛 zyt
     * @version 1.0
     * @date 2021/11/1 11:50
     * @description
     */
    public class NutritionFacts {
        private final int servingSize;
        private final int servings;
        private final int calories;
        private final int fat;
        private final int sodium;
        private final int carbohydrate;
    
        public static class Builder{
            //required
            private final int servingSize;
            private final int servings;
            //optianal
            private int calories=0;
            private int fat = 0;
            private int sodium=0;
            private int carbohydrate=0;
    
            public Builder(int servingSize, int serving) {
                this.servingSize = servingSize;
                this.servings = serving;
            }
            public Builder calories(int val){
                calories=val;return this;
            }
            public Builder fat(int val){
                fat=val;
                return this;
            }
            public Builder sodium(int val){
                sodium=val;
                return this;
            }
            public Builder carbohydrate(int val){
                carbohydrate=val;
                return this;
            }
            public NutritionFacts build(){
                return new NutritionFacts(this);
            }
        }
    
        @Override
        public String toString() {
            return "NutritionFacts{" +
                    "servingSize=" + servingSize +
                    ", servings=" + servings +
                    ", calories=" + calories +
                    ", fat=" + fat +
                    ", sodium=" + sodium +
                    ", carbohydrate=" + carbohydrate +
                    '}';
        }
    
        public NutritionFacts(Builder builder) {
            servings=builder.servings;
            servingSize = builder.servingSize;
            calories = builder.calories;
            fat = builder.fat;
            sodium = builder.sodium;
            carbohydrate= builder.carbohydrate;
        }
    
        public static void main(String[] args) {
            NutritionFacts one = new Builder(240, 8).calories(100).sodium(35).calories(27).build();
            System.out.println(one);
            Builder calories = new Builder(33, 44).calories(22);
        }
    }

    这里的核心就是使用静态内部类作为builder,在最后的build()方法里面,新建主类对象,将内部类的值传递给主类;

    上次想看Lombok 生成的代码,没想到怎么看,今天直接想起来到去target中查看呢

    那么看下Lombok生成的代码

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by FernFlower decompiler)
    //
    
    package com.msb.dongbao.common.base.dto;
    
    import com.msb.dongbao.common.base.enums.StateCodeEnum;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import java.io.Serializable;
    
    @ApiModel("基础返回实体")
    public class ResultWrapper<T> implements Serializable {
        @ApiModelProperty(
            name = "msg",
            dataType = "string",
            value = "响应信息"
        )
        private String msg;
        @ApiModelProperty(
            name = "getCode",
            dataType = "int",
            value = "响应码"
        )
        private int code;
        @ApiModelProperty(
            name = "data",
            dataType = "object",
            value = "数据内容"
        )
        private T data;
    
        public static ResultWrapper.ResultWrapperBuilder getSuccessBuilder() {
            return builder().code(StateCodeEnum.SUCCESS.getCode()).msg(StateCodeEnum.SUCCESS.msg());
        }
    
        public static ResultWrapper.ResultWrapperBuilder getErrorBuilder() {
            return builder().code(StateCodeEnum.ERROR.getCode()).msg(StateCodeEnum.SUCCESS.msg());
        }
    
        ResultWrapper(final String msg, final int code, final T data) {
            this.msg = msg;
            this.code = code;
            this.data = data;
        }
    
        public static <T> ResultWrapper.ResultWrapperBuilder<T> builder() {
            return new ResultWrapper.ResultWrapperBuilder();
        }
    
        public String getMsg() {
            return this.msg;
        }
    
        public int getCode() {
            return this.code;
        }
    
        public T getData() {
            return this.data;
        }
    
        public void setMsg(final String msg) {
            this.msg = msg;
        }
    
        public void setCode(final int code) {
            this.code = code;
        }
    
        public void setData(final T data) {
            this.data = data;
        }
    
    
        public static class ResultWrapperBuilder<T> {
            private String msg;
            private int code;
            private T data;
    
            ResultWrapperBuilder() {
            }
    
            public ResultWrapper.ResultWrapperBuilder<T> msg(final String msg) {
                this.msg = msg;
                return this;
            }
    
            public ResultWrapper.ResultWrapperBuilder<T> code(final int code) {
                this.code = code;
                return this;
            }
    
            public ResultWrapper.ResultWrapperBuilder<T> data(final T data) {
                this.data = data;
                return this;
            }
    
            public ResultWrapper<T> build() {
                return new ResultWrapper(this.msg, this.code, this.data);
            }
    
            public String toString() {
                return "ResultWrapper.ResultWrapperBuilder(msg=" + this.msg + ", code=" + this.code + ", data=" + this.data + ")";
            }
        }
    }

    特别说明的是在使用Lombok中他自定了一个builder()方法,其他的就是和书中的案例的代码基本一致了

  • 相关阅读:
    线程池
    非XA式Spring分布式事务
    好的架构不是设计出来的,而是演进出来的
    缓存穿透
    【转】MySQL数据库主从同步管理
    setup 桌面化设置网卡
    gitlab web登入密码忘记以后可以用如下方式修改密码
    kvm与selinux
    linux下跳板机跟客户端之间无密码登陆
    LINUX下安装TeamViewer
  • 原文地址:https://www.cnblogs.com/zytcomeon/p/15493816.html
Copyright © 2020-2023  润新知