user1692342
user1692342

Reputation: 5237

Create a common builder for an object irrespective of fields being passed in

I'have a class which has multiple fields:

@Builder
public class SampleClass {
    private String a;
    private String b;
    private String c;
    private String d;
}

I've a helper class which does some string modification:

public class StringModifier {
    public static String prefixUnderscore(String text) {
        return "_" + text;
    }

    public static String postfixUnderscore(String text) {
        return text + "_";
    }
}

Now based on some conditions, I may have either field a or field b. To build the object I do:

private static SampleClass getSampleClassWithB(String b, String c, Function<String, String> mapper) {
        String d = mapper.apply(b);
        return SampleClass.builder().b(b).c(c).d(d).build();
    }

    private static SampleClass getSampleClassWithA(String a, String c, Function<String, String> mapper) {
        String d = mapper.apply(a);
        return SampleClass.builder().a(a).c(c).d(d).build();
    }

And to use these functions:

getSampleClassWithA("a", "c", StringModifier::postfixUnderscore);
getSampleClassWithB("b", "c", StringModifier::prefixUnderscore);

Now as you can see both getSampleClassWithA & getSampleClassWithB do pretty similar things. Is there a way to combine this into a method?

Upvotes: 1

Views: 63

Answers (1)

Holger
Holger

Reputation: 298409

As always, if two or more methods are doing mostly the same and you want to avoid the code duplication, you have to find an abstraction for the difference, in this case, the invocation of either, a or b, on the builder:

private static SampleClass getSampleClassWith(
    String value, BiFunction<SampleClassBuilder,String,SampleClassBuilder> property,
    String c, Function<String, String> mapper) {

    return property.apply(SampleClass.builder(),value).c(c).d(mapper.apply(value)).build();
}
getSampleClassWith("a", SampleClassBuilder::a, "c", StringModifier::postfixUnderscore);
getSampleClassWith("b", SampleClassBuilder::b, "c", StringModifier::prefixUnderscore);

Upvotes: 3

Related Questions