El modo constructor salvó mi trastorno obsesivo-compulsivo

Constructor

prefacio

Todo el mundo debería estar familiarizado con el modo Builder . En nuestra carrera de codificación, siempre lo encontraremos. Ya sea AlertDialog en el desarrollo de Android, OkHttp y Retrofit en el marco de la red o JavaPoet, existen tales amigos.

La razón por la que es tan popular, además de su relativamente baja dificultad para ponerse en marcha, es que realmente soluciona un problema en nuestro desarrollo diario, que requiere demasiados parámetros a la hora de crear objetos .

dar un pequeño ejemplo

En los últimos años, todo el mundo se ha vuelto popular para especular con monedas, lo que dificulta encontrar una tarjeta en el mercado. Con la introducción de políticas gubernamentales y el colapso de las monedas virtuales. Las tarjetas gráficas ya no tienen precio. Xiaolong, quien acaba de graduarse de la universidad, abrió una tienda de computadoras, especializándose en distribuir computadoras a las personas. Al principio, los requisitos eran relativamente simples y solo se registraba para las personas la CPU, la GPU, el disco duro y otra información relacionada de la computadora.

La forma tradicional de crear objetos.

// 电脑类
class Computer {
    private String mBroad;
    private String mCPU;
    private String mGPU;

    public Computer(String broad, String CPU, String GPU) {
        mBroad = broad;
        mCPU = CPU;
        mGPU = GPU;
    }

    @Override
    public String toString() {
        return "Computer{" +
                ", mBroad='" + mBroad + ''' +
                ", mCPU='" + mCPU + ''' +
                ", mGPU='" + mGPU + ''' +
                '}';
    }
}
复制代码

En este momento, crea un objeto Computer como este:

Computer computer = new Computer("微星 B550M","INTEL I5","NV 3060TI");
复制代码

Con el aumento del volumen de negocios, también aumentan los requisitos de los clientes. También hay requisitos correspondientes para el mouse, el teclado y el sistema. Por lo tanto, la clase de Computación tuvo que cambiarse en consecuencia.

static class Computer {
    private String mOS;
    private String mBroad;
    private String mKeyBoard;
    private String mMouse;
    private String mCPU;
    private String mGPU;

    public Computer(String OS, String broad, String keyBoard, String mouse, String CPU, String GPU) {
        mOS = OS;
        mBroad = broad;
        mKeyBoard = keyBoard;
        mMouse = mouse;
        mCPU = CPU;
        mGPU = GPU;
    }

    // 就写一个set方法否则文章太长,其他就不写了
    public void setmBroad(String mBroad) {
        this.mBroad = mBroad;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "mOS='" + mOS + ''' +
                ", mBroad='" + mBroad + ''' +
                ", mKeyBoard='" + mKeyBoard + ''' +
                ", mMouse='" + mMouse + ''' +
                ", mCPU='" + mCPU + ''' +
                ", mGPU='" + mGPU + ''' +
                '}';
    }
}
复制代码

Y los parámetros para crear el objeto Computer son cada vez más largos:

Computer computer = new Computer("MAC OS","微星 B550M","IQUNIX F97"
,"罗技 MX MASTER3","INTEL I5","NV 3060TI");
复制代码

Si hay nuevos parámetros de demanda, fuente de alimentación, chasis, disipación de calor, módulo de memoria, disco duro... Ni me lo imagino.

Problema de parámetros de inicialización de objetos

En este punto nos enfrentamos a un problema común en programación, se requieren demasiados parámetros en el objeto, y si se pasan todos en el constructor , el constructor será el mismo que en el ejemplo, demasiado largo, si se pasa por el método set, será aún más aterrador.

En este momento, surgió un modo, y él es el modo constructor .

Manejo del modo constructor

/**
 * @author:TianLong
 * @date:2022/10/17 19:58
 * @detail:产品类
 */
class Computer{
    private String mOS;
    private String mBroad;
    private String mKeyBoard;
    private String mMouse;
    private String mCPU;
    private String mGPU;
    private Computer(String OS, String broad, String keyBoard, String mouse, String CPU, String GPU) {
        mOS = OS;
        mBroad = broad;
        mKeyBoard = keyBoard;
        mMouse = mouse;
        mCPU = CPU;
        mGPU = GPU;
    }

    public static ComputerBuilder createBuilder(){
        return new ComputerBuilder();
    }

    @Override
    public String toString() {
        return "Computer{" +
                "mOS='" + mOS + ''' +
                ", mBroad='" + mBroad + ''' +
                ", mKeyBoard='" + mKeyBoard + ''' +
                ", mMouse='" + mMouse + ''' +
                ", mCPU='" + mCPU + ''' +
                ", mGPU='" + mGPU + ''' +
                '}';
    }

    /**
     * @author:TianLong
     * @date:2022/10/17 19:58
     * @detail:产品建造者类
     */
    public static class ComputerBuilder{
        private String mOS = "Windows";
        private String mBroad= "微星 B550M";
        private String mKeyBoard= "无";
        private String mMouse= "无";
        private String mCPU= "Intel I5";
        private String mGPU= "AMD 6600XT";

        public ComputerBuilder setOS(String OS) {
            mOS = OS;
            return this;
        }

        public ComputerBuilder setBroad(String broad) {
            mBroad = broad;
            return this;
        }

        public ComputerBuilder setKeyBoard(String keyBoard) {
            mKeyBoard = keyBoard;
            return this;
        }

        public ComputerBuilder setMouse(String mouse) {
            mMouse = mouse;
            return this;
        }

        public ComputerBuilder setCPU(String CPU) {
            mCPU = CPU;
            return this;
        }

        public ComputerBuilder setGPU(String GPU) {
            mGPU = GPU;
            return this;
        }

        public Computer build(){
            // 可以在build方法中做一些校验等其他工作
            if (mBroad.contains("技嘉")){
                throw new RuntimeException("技嘉辱华,不支持技嘉主板");
            }
 
            Computer computer = new Computer(mOS,mBroad,mKeyBoard,mMouse,mCPU,mGPU);
            return computer;
        }
    }
复制代码

La versión antigua y la versión Builder crean objetos

// 老版本的Computer对象创建
Computer computer = new Computer("MAC OS","微星 B550M","IQUNIX F97"
,"罗技 MX MASTER3","INTEL I5","NV 3060TI");

// Builder版本的Computer对象创建
Computer computer =Computer.createBuilder()
        .setCPU("AMD 5600X")
        .setGPU("NV 3060TI")
        .setMouse("罗技 MX MASTER3")
        .setKeyBoard("IQUNIX F97")
        .build();
复制代码

两个版本一对比就能体现出来优势。老版本构造函数中的参数太多太长,同一个类型的参数很容易传错位,经常传参数的时候,还要看看第几个参数应该传什么。

Builder模式的对象创建,简单明了,更容易理解,而且流式的调用更加美观,不会出错。

从代码中可以看到,Computer类的构造函数是私有的,保证了所有对象的创建都必须从ComputerBuilder这个类来创建。且ComputerBuilder这个类的build方法中,可以进行校验或者其他操作。

同时,Computer这个类中是否存在Set方法,由你的实际应用场景决定,反正我的使用场景里,没有修改需求。

注意事项

  1. 上述代码为常见写法,并非固定模板。只要能通过Builder类创建目标对象,都可以算是建造者模式
  2. 建造者模式中的目标对象的构造函数必须是private修饰。否则可以直接创建对象。Builder类就没有意义了
  3. 建造者模式中的目标对象是否需要Set方法,由具体需求决定。一般情况下没有Set方法,可以避免对该对象中的参数进行修改。
  4. Builder中的build方法,可以处理一些逻辑问题,比如校验信息等
  5. 工厂模式注重的是同一类型的对象中通过参数来控制具体创建哪个对象。Builder模式关注的是单一对象中的参数传递

Supongo que te gusta

Origin juejin.im/post/7197326179934191676
Recomendado
Clasificación