构建器模式和大量强制参数

2024-02-01

迄今为止我使用的是下列的 http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html构建器模式的实现(与描述的实现相反)here http://en.wikipedia.org/wiki/Builder_pattern#Java):

public class Widget {
    public static class Builder {
        public Builder(String name, double price) { ... }
        public Widget build() { ... }
        public Builder manufacturer(String value) { ... }
        public Builder serialNumber(String value) { ... }
        public Builder model(String value) { ... }
    }

    private Widget(Builder builder) { ... }
}

这对于我遇到的大多数情况都很有效,在这些情况下,我需要构建具有各种必需/强制和可选参数的复杂对象。然而,我最近一直在努力理解当所有参数都是强制性的(或者至少绝大多数参数都是强制性的)时,该模式有何好处。

解决这个问题的一种方法是对传递给它们自己的类的参数进行逻辑分组,以减少传递给构建器构造函数的参数数量。

例如,代替:

Widget example = new Widget.Builder(req1, req2, req3,req4,req5,req6,req7,req8)
                           .addOptional(opt9)
                           .build();

分组如下:

Object1 group1 = new Object1(req1, req2, req3, req4);
Object2 group2 = new Object2(req5, req6);

Widget example2 = new Widget.Builder(group1, group2, req7, req8)
                            .addOptional(opt9)
                            .build();

虽然使用单独的对象可以大大简化事情,但如果不熟悉代码,也会使事情变得有点难以理解。我考虑的一件事是将所有参数移动到自己的参数中addParam(param)方法,然后对所需参数进行验证build() method.

什么是最佳实践?是否有我没有考虑过的更好方法?


您可以使用步骤生成器 http://www.javacodegeeks.com/2013/05/building-smart-builders.html如果你有很多强制参数。简而言之:您为每个强制参数定义一个接口,并且构建器方法返回下一个强制构建器接口或可选方法的构建器本身。构建器仍然是实现所有接口的单个​​类。

interface StepB {
    StepBuilder b(String b);
}

interface StepA {
    StepB a(String a);
}

final class StepBuilder implements StepA, StepB {
    private String a;
    private String b;
    private String c = "";

    private StepBuilder() {
    }

    static StepA with() {
      return new StepBuilder();
    }

    // mandatory, from StepA
    @Override
    StepB a(String a) {
        this.a = a;
        return this;
    }

    // mandatory, from StepB
    @Override
    StepBuilder b(String b) {
        this.b = b;
        return this;
    }

    // optional
    StepBuilder c(String c) {
        this.c = c;
        return this;
    }

    Product build() {
        return new Product(a, b, c);
    }
}

Usage:

StepBuilder.with().a("hello").b("world").build();

// or with the optional parameter c
StepBuilder.with().a("hello").b("world").c("!").build();

请记住我为该类命名StepBuilder只是为了在我的解释中说清楚。最好给它一个反映各自域某些方面的名称。例子:

Url.with().host("example.com").port(81).path("some/where").query("status=1").build()

Kotlin 和 Scala 等语言在这里更方便,因为它们提供带有默认值的命名参数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

构建器模式和大量强制参数 的相关文章

随机推荐