动态参数类型处理:使用 Builder 模式构建灵活的函数

本文介绍了如何使用 Builder 模式来解决函数参数类型不确定的问题。Builder 模式允许我们在构建对象时,逐步设置对象的属性,从而避免了创建大量重载方法或使用复杂的条件判断。

Builder 模式详解

Builder 模式是一种创建型设计模式,它将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。Builder 模式通常包含以下几个角色:

  • Builder(抽象建造者): 定义了构建对象的抽象方法,通常包含设置对象各个属性的方法。
  • ConcreteBuilder(具体建造者): 实现了 Builder 接口,负责具体对象的构建过程。
  • Director(指挥者): 负责安排构建过程,调用 Builder 的方法来构建对象。
  • Product(产品): 表示被构建的复杂对象。

示例代码:使用 Builder 模式构建 Range 函数

以下代码示例展示了如何使用 Builder 模式来构建一个 Range 函数,该函数接受 scale、min 和 max 三个参数,每个参数既可以是 double 类型的数值,也可以是接受 PVector 类型参数并返回 Double 类型的函数。

import processing.core.PVector;

import java.io.IOException;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

import static processing.core.PApplet.map;
import static processing.core.PApplet.noise;

public class RangeBuilderExample {

    public static void main(String... args) throws IOException {
        List pvs = List.of(new PVector(0, 0));

        Stream s = pvs.stream().map(new RangeBuilder().scale(.02)
                                                              .min(0)
                                                              .max(255)
                                                              .build());
        Stream s2 = pvs.stream().map(new RangeBuilder().scale(new RangeBuilder().scale(.02)
                                                                                        .min(.1)
                                                                                        .max(.002)
                                                                                        .build())
                                                           .min(0)
                                                           .max(255)
                                                           .build());

    }

    public static final class RangeBuilder {

        private Function scale;
        private Function min;
        private Function max;

        public RangeBuilder scale(Function scale) {
            this.scale = scale;
            return this;
        }

        public RangeBuilder scale(double scale) {
            return scale(in -> scale);
        }

        public RangeBuilder min(Function min) {
            this.min = min;
            return this;
        }

        public RangeBuilder min(double min) {
            return min(in -> min);
        }

        public RangeBuilder max(Function max) {
            this.max = max;
            return this;
        }

        public RangeBuilder max(double scale) {
            return scale(in -> scale);
        }

        public Function build() {
            return pv -> map(noise(pv.x * scale.apply(pv), pv.y * scale.apply(pv)), 0, 1, min.apply(pv), max.apply(pv));
        }

    }
}

代码解释:

  1. RangeBuilder 类: 这是具体的 Builder 类,它包含了 scale、min 和 max 三个 Function 类型的属性,用于存储构建 Range 函数所需的参数。
  2. scale(Function scale)、min(Function min)、max(Function max) 方法: 这些方法用于设置 scale、min 和 max 属性的值,它们接受 Function 类型的参数。
  3. scale(double scale)、min(

    double min)、max(double scale) 方法:
    这些方法是重载方法,用于设置 scale、min 和 max 属性的值,它们接受 double 类型的参数。在这些方法内部,我们将 double 类型的参数转换为 Function 类型,并调用对应的 scale(Function scale)、min(Function min)、max(Function max) 方法。
  4. build() 方法: 该方法负责构建 Range 函数,它将 scale、min 和 max 属性的值传递给 map 函数,并返回一个 Function 类型的函数。

使用示例:

在 main 方法中,我们首先创建了一个 List 类型的列表 pvs,其中包含一个 PVector 对象。然后,我们使用 RangeBuilder 类来构建两个 Range 函数 s 和 s2。

  • s 函数的 scale 参数设置为 0.02,min 参数设置为 0,max 参数设置为 255。
  • s2 函数的 scale 参数设置为另一个 Range 函数,该函数的 scale 参数设置为 0.02,min 参数设置为 0.1,max 参数设置为 0.002,min 参数设置为 0,max 参数设置为 255。

最后,我们使用 pvs.stream().map() 方法将 s 和 s2 函数应用于 pvs 列表中的每个 PVector 对象,并将结果存储在 Stream 类型的流中。

注意事项

  • 在 Builder 模式中,Builder 类通常被定义为静态内部类,以便更好地封装构建过程。
  • Builder 模式可以与其他设计模式结合使用,例如,可以将 Builder 模式与工厂模式结合使用,以创建更复杂的对象。
  • 在示例代码中,我们使用了 double 类型来代替 float 类型,这是因为 double 是浮点数的默认类型。

总结

Builder 模式是一种非常有用的设计模式,它可以帮助我们构建复杂的对象,并提高代码的可读性和可维护性。在函数参数类型不确定的场景中,使用 Builder 模式可以避免创建大量重载方法或使用复杂的条件判断,从而使代码更加简洁易懂。 通过使用 Builder 模式,我们可以更加灵活地处理动态参数类型,并构建出更加强大的函数。