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()方法,其他的就是和书中的案例的代码基本一致了

posted @ 2021-11-01 15:08  张艳涛&java  阅读(86)  评论(0编辑  收藏  举报